From gitlab at gitlab.haskell.org Sat Apr 1 01:28:26 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 31 Mar 2023 21:28:26 -0400 Subject: [Git][ghc/ghc][master] 15 commits: ci: make lint-ci-config job fast again Message-ID: <642788ba3fd1_3483da47284f148701db@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 15 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - hadrian/src/Settings/Builders/RunTest.hs - testsuite/config/ghc - testsuite/driver/my_typing.py - testsuite/driver/runtests.py - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/driver/testutil.py - − testsuite/driver/typing_stubs.py - testsuite/timeout/Makefile Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: b58ecd021c2533f0f0d0b1c9109200a69506d2b7 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. @@ -264,7 +264,7 @@ lint-author: - *drafts-can-fail-lint lint-ci-config: - image: nixos/nix:2.12.0 + image: nixos/nix:2.14.1 extends: .lint # We don't need history/submodules in this job variables: @@ -979,7 +979,7 @@ project-version: .ghcup-metadata: stage: deploy - image: "nixos/nix:2.12.0" + image: nixos/nix:2.14.1 dependencies: null tags: - x86_64-linux @@ -1084,4 +1084,3 @@ ghcup-metadata-testing-release: rules: - if: '$RELEASE_JOB == "yes"' when: manual - ===================================== .gitlab/ci.sh ===================================== @@ -514,7 +514,7 @@ function build_hadrian() { # hadrian calls tar/xz to produce bindist, there's no other build # work taking place. if [[ "${CI_JOB_NAME:-}" != *"i386"* ]]; then - XZ_OPT="${XZ_OPT:-} -T$cores" + export XZ_OPT="${XZ_OPT:-} -T$cores" fi if [[ -n "${REINSTALL_GHC:-}" ]]; then @@ -606,6 +606,8 @@ function test_hadrian() { return # special case for JS backend elif [ -n "${CROSS_TARGET:-}" ] && [ "${CROSS_EMULATOR:-}" == "js-emulator" ]; then + # The JS backend doesn't support CROSS_EMULATOR logic yet + unset CROSS_EMULATOR # run "hadrian test" directly, not using the bindist, even though it did get installed. # This is a temporary solution, See !9515 for the status of hadrian support. run_hadrian \ ===================================== .gitlab/gen_ci.hs ===================================== @@ -114,6 +114,7 @@ data LinuxDistro | Ubuntu1804 | Centos7 | Alpine + | AlpineWasm | Rocky8 deriving (Eq) @@ -279,6 +280,7 @@ distroName Ubuntu1804 = "ubuntu18_04" distroName Ubuntu2004 = "ubuntu20_04" distroName Centos7 = "centos7" distroName Alpine = "alpine3_12" +distroName AlpineWasm = "alpine3_17-wasm" distroName Rocky8 = "rocky8" opsysName :: Opsys -> String @@ -646,7 +648,6 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} } , "bash .gitlab/ci.sh test_hadrian" ] | otherwise = [ "find libraries -name config.sub -exec cp config.sub {} \\;" | Darwin == opsys ] ++ - [ "sudo apk del --purge glibc*" | opsys == Linux Alpine, isNothing $ crossTarget buildConfig ] ++ [ "sudo chown ghc:ghc -R ." | Linux {} <- [opsys]] ++ [ ".gitlab/ci.sh setup" , ".gitlab/ci.sh configure" @@ -929,7 +930,7 @@ job_groups = . setVariable "HADRIAN_ARGS" "--docs=none" . delVariable "INSTALL_CONFIGURE_ARGS" ) - $ validateBuilds Amd64 (Linux Alpine) cfg + $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = (crossConfig "wasm32-wasi" NoEmulatorNeeded Nothing) @@ -992,4 +993,3 @@ write_result as obj = [] -> B.putStrLn (fp:_) -> B.writeFile fp) (A.encode obj) - ===================================== .gitlab/generate_job_metadata ===================================== @@ -1,5 +1,5 @@ #! /usr/bin/env nix-shell -#!nix-shell -i bash -p cabal-install "haskell.packages.ghc924.ghcWithPackages (pkgs: with pkgs; [aeson])" git jq +#!nix-shell -i bash -p cabal-install "haskell.packages.ghc92.ghcWithPackages (pkgs: with pkgs; [aeson])" git jq cd "$(dirname "${BASH_SOURCE[0]}")" cabal run gen_ci -- metadata jobs-metadata.json ===================================== .gitlab/generate_jobs ===================================== @@ -1,5 +1,5 @@ #!/usr/bin/env nix-shell -#!nix-shell -i bash -p cabal-install "haskell.packages.ghc924.ghcWithPackages (pkgs: with pkgs; [aeson])" git jq +#!nix-shell -i bash -p cabal-install "haskell.packages.ghc92.ghcWithPackages (pkgs: with pkgs; [aeson])" git jq # shellcheck shell=bash ===================================== .gitlab/jobs.yaml ===================================== @@ -544,17 +544,17 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static": { + "nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": false, + "allow_failure": true, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -595,17 +595,18 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static", - "BUILD_FLAVOUR": "release+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi", - "CROSS_TARGET": "wasm32-wasi", - "HADRIAN_ARGS": "--docs=none", - "TEST_ENV": "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static", + "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", + "BUILD_FLAVOUR": "validate+fully_static", + "CONFIGURE_ARGS": "--disable-ld-override ", + "HADRIAN_ARGS": "--docs=no-sphinx", + "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", + "TEST_ENV": "x86_64-linux-alpine3_12-int_native-validate+fully_static", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static": { + "nightly-x86_64-linux-alpine3_12-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", @@ -615,7 +616,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_12-validate+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -656,27 +657,28 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static", - "BUILD_FLAVOUR": "release+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi", - "CROSS_TARGET": "wasm32-wasi", - "HADRIAN_ARGS": "--docs=none", - "TEST_ENV": "x86_64-linux-alpine3_12-int_native-cross_wasm32-wasi-release+fully_static", + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-validate+fully_static", + "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", + "BUILD_FLAVOUR": "validate+fully_static", + "CONFIGURE_ARGS": "--disable-ld-override ", + "HADRIAN_ARGS": "--docs=no-sphinx", + "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", + "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static": { + "nightly-x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", "cat ci_timings" ], - "allow_failure": true, + "allow_failure": false, "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -685,14 +687,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-alpine3_12-$CACHE_REV", + "key": "x86_64-linux-alpine3_17-wasm-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_17-wasm:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -706,7 +708,6 @@ } ], "script": [ - "sudo apk del --purge glibc*", "sudo chown ghc:ghc -R .", ".gitlab/ci.sh setup", ".gitlab/ci.sh configure", @@ -718,18 +719,17 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "native", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-int_native-validate+fully_static", - "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", - "BUILD_FLAVOUR": "validate+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", - "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", - "TEST_ENV": "x86_64-linux-alpine3_12-int_native-validate+fully_static", + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static", + "BUILD_FLAVOUR": "release+fully_static", + "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi", + "CROSS_TARGET": "wasm32-wasi", + "HADRIAN_ARGS": "--docs=none", + "TEST_ENV": "x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static": { + "nightly-x86_64-linux-alpine3_17-wasm-int_native-cross_wasm32-wasi-release+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", @@ -739,7 +739,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_17-wasm-int_native-cross_wasm32-wasi-release+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -748,14 +748,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-alpine3_12-$CACHE_REV", + "key": "x86_64-linux-alpine3_17-wasm-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_17-wasm:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -780,17 +780,17 @@ "x86_64-linux" ], "variables": { - "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static", + "BIGNUM_BACKEND": "native", + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_17-wasm-int_native-cross_wasm32-wasi-release+fully_static", "BUILD_FLAVOUR": "release+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override --enable-unregisterised --with-intree-gmp --with-system-libffi", + "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi", "CROSS_TARGET": "wasm32-wasi", "HADRIAN_ARGS": "--docs=none", - "TEST_ENV": "x86_64-linux-alpine3_12-unreg-cross_wasm32-wasi-release+fully_static", + "TEST_ENV": "x86_64-linux-alpine3_17-wasm-int_native-cross_wasm32-wasi-release+fully_static", "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-alpine3_12-validate+fully_static": { + "nightly-x86_64-linux-alpine3_17-wasm-unreg-cross_wasm32-wasi-release+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", @@ -800,7 +800,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-validate+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_17-wasm-unreg-cross_wasm32-wasi-release+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -809,14 +809,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-alpine3_12-$CACHE_REV", + "key": "x86_64-linux-alpine3_17-wasm-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_17-wasm:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -830,7 +830,6 @@ } ], "script": [ - "sudo apk del --purge glibc*", "sudo chown ghc:ghc -R .", ".gitlab/ci.sh setup", ".gitlab/ci.sh configure", @@ -843,13 +842,12 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-validate+fully_static", - "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", - "BUILD_FLAVOUR": "validate+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", - "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", - "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static", + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_17-wasm-unreg-cross_wasm32-wasi-release+fully_static", + "BUILD_FLAVOUR": "release+fully_static", + "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi", + "CROSS_TARGET": "wasm32-wasi", + "HADRIAN_ARGS": "--docs=none", + "TEST_ENV": "x86_64-linux-alpine3_17-wasm-unreg-cross_wasm32-wasi-release+fully_static", "XZ_OPT": "-9" } }, @@ -2459,7 +2457,6 @@ } ], "script": [ - "sudo apk del --purge glibc*", "sudo chown ghc:ghc -R .", ".gitlab/ci.sh setup", ".gitlab/ci.sh configure", @@ -2523,7 +2520,6 @@ } ], "script": [ - "sudo apk del --purge glibc*", "sudo chown ghc:ghc -R .", ".gitlab/ci.sh setup", ".gitlab/ci.sh configure", @@ -3521,7 +3517,7 @@ "TEST_ENV": "x86_64-freebsd13-validate" } }, - "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static": { + "x86_64-linux-alpine3_12-validate+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", @@ -3531,7 +3527,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_12-validate+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -3573,15 +3569,16 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static", - "BUILD_FLAVOUR": "release+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi", - "CROSS_TARGET": "wasm32-wasi", - "HADRIAN_ARGS": "--docs=none", - "TEST_ENV": "x86_64-linux-alpine3_12-cross_wasm32-wasi-release+fully_static" + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-validate+fully_static", + "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", + "BUILD_FLAVOUR": "validate+fully_static", + "CONFIGURE_ARGS": "--disable-ld-override ", + "HADRIAN_ARGS": "--docs=no-sphinx", + "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", + "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static" } }, - "x86_64-linux-alpine3_12-validate+fully_static": { + "x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh clean", @@ -3591,7 +3588,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-alpine3_12-validate+fully_static.tar.xz", + "ghc-x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static.tar.xz", "junit.xml" ], "reports": { @@ -3600,14 +3597,14 @@ "when": "always" }, "cache": { - "key": "x86_64-linux-alpine3_12-$CACHE_REV", + "key": "x86_64-linux-alpine3_17-wasm-$CACHE_REV", "paths": [ "cabal-cache", "toolchain" ] }, "dependencies": [], - "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV", + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_17-wasm:$DOCKER_REV", "needs": [ { "artifacts": false, @@ -3621,7 +3618,6 @@ } ], "script": [ - "sudo apk del --purge glibc*", "sudo chown ghc:ghc -R .", ".gitlab/ci.sh setup", ".gitlab/ci.sh configure", @@ -3634,13 +3630,12 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_12-validate+fully_static", - "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", - "BUILD_FLAVOUR": "validate+fully_static", - "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", - "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", - "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static" + "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static", + "BUILD_FLAVOUR": "release+fully_static", + "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi", + "CROSS_TARGET": "wasm32-wasi", + "HADRIAN_ARGS": "--docs=none", + "TEST_ENV": "x86_64-linux-alpine3_17-wasm-cross_wasm32-wasi-release+fully_static" } }, "x86_64-linux-deb10-int_native-validate": { ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -213,6 +213,7 @@ runTestBuilderArgs = builder Testsuite ? do (testEnv, testMetricsFile) <- expr . liftIO $ (,) <$> lookupEnv "TEST_ENV" <*> lookupEnv "METRICS_FILE" perfBaseline <- expr . liftIO $ lookupEnv "PERF_BASELINE_COMMIT" + targetWrapper <- expr . liftIO $ lookupEnv "CROSS_EMULATOR" threads <- shakeThreads <$> expr getShakeOptions top <- expr $ topDirectory @@ -282,6 +283,7 @@ runTestBuilderArgs = builder Testsuite ? do , case perfBaseline of Just commit | not (null commit) -> arg ("--perf-baseline=" ++ commit) _ -> mempty + , emitWhenSet targetWrapper $ \cmd -> arg ("--target-wrapper=" ++ cmd) , emitWhenSet testEnv $ \env -> arg ("--test-env=" ++ env) , emitWhenSet testMetricsFile $ \file -> arg ("--metrics-file=" ++ file) , getTestArgs -- User-provided arguments from command line. ===================================== testsuite/config/ghc ===================================== @@ -70,7 +70,7 @@ if windows: config.other_ways += winio_ways # LLVM -if not config.unregisterised and not config.arch == "javascript" and config.have_llvm: +if not config.unregisterised and not config.arch in {"wasm32", "javascript"} and config.have_llvm: config.compile_ways.append('optllvm') config.run_ways.append('optllvm') ===================================== testsuite/driver/my_typing.py ===================================== @@ -8,13 +8,8 @@ The testsuite driver can be typechecked using mypy [1]. [1] http://mypy-lang.org/ """ -try: - from typing import * - import typing -except: - # The backwards compatibility stubs must live in another module lest - # mypy complains. - from typing_stubs import * # type: ignore +from typing import * +import typing #################################################### @@ -23,14 +18,7 @@ except: # N.B. mypy appears to typecheck as though the "then" clause of if structures # is taken. We exploit this below. -# TextIO is missing on some older Pythons. -if 'TextIO' not in globals(): - try: - from typing import TextIO - except ImportError: - TextIO = None # type: ignore -else: - TextIO = None # type: ignore +from typing import TextIO #################################################### ===================================== testsuite/driver/runtests.py ===================================== @@ -26,10 +26,10 @@ from pathlib import Path # So we import it here first, so that the testsuite doesn't appear to fail. import subprocess -from concurrent.futures import ThreadPoolExecutor +import asyncio from testutil import getStdout, str_warn, str_info, print_table, shorten_metric_name -from testglobals import getConfig, ghc_env, getTestRun, TestConfig, \ +from testglobals import getConfig, ghc_env, TestConfig, t, \ TestOptions, brokens, PerfMetric from my_typing import TestName from perf_notes import MetricChange, GitRef, inside_git_repo, is_worktree_dirty, format_perf_stat, get_abbrev_hash_length, is_commit_hash @@ -71,6 +71,7 @@ parser.add_argument("--config", action='append', help="config field") parser.add_argument("--rootdir", action='append', help="root of tree containing tests (default: .)") parser.add_argument("--metrics-file", help="file in which to save (append) the performance test metrics. If omitted, git notes will be used.") parser.add_argument("--summary-file", help="file in which to save the (human-readable) summary") +parser.add_argument("--target-wrapper", help="wrapper executable to use when executing binaries compiled for the target") parser.add_argument("--no-print-summary", action="store_true", help="should we print the summary?") parser.add_argument("--only", action="append", help="just this test (can be give multiple --only= flags)") parser.add_argument("--way", action="append", help="just this way") @@ -119,6 +120,7 @@ hasMetricsFile = config.metrics_file is not None config.summary_file = args.summary_file config.no_print_summary = args.no_print_summary config.baseline_commit = args.perf_baseline +config.target_wrapper = args.target_wrapper if args.top: config.top = args.top @@ -307,7 +309,7 @@ if windows: path = format_path(path) ghc_env['PATH'] = os.pathsep.join([path, ghc_env.get("PATH", "")]) -testopts_local.x = TestOptions() +testopts_ctx_var.set(TestOptions()) # if timeout == -1 then we try to calculate a sensible value if config.timeout == -1: @@ -337,8 +339,6 @@ t_files = list(findTFiles(config.rootdirs)) print('Found', len(t_files), '.T files...') -t = getTestRun() # type: TestRun - # Avoid cmd.exe built-in 'date' command on Windows t.start_time = datetime.datetime.now() @@ -484,25 +484,28 @@ if config.list_broken: else: # Now run all the tests try: - with ThreadPoolExecutor(max_workers=config.threads) as executor: + async def run_parallelTests(): + sem = asyncio.Semaphore(config.threads) + ts = [] + for oneTest in parallelTests: if stopping(): break - oneTest(executor) + ts.append(oneTest(sem)) + + return await asyncio.gather(*ts) - # wait for parallel tests to finish - if not stopping(): - executor.shutdown(wait=True) + # wait for parallel tests to finish + asyncio.run(run_parallelTests()) # Run the following tests purely sequential - with ThreadPoolExecutor(max_workers=1) as executor: + async def run_aloneTests(): for oneTest in aloneTests: if stopping(): break - oneTest(executor) + await oneTest(None) - if not stopping(): - executor.shutdown(wait=True) + asyncio.run(run_aloneTests()) except KeyboardInterrupt: pass @@ -523,13 +526,13 @@ else: groups[m.stat.metric].append(m) - for metric_name, stats in groups.items(): + for metric_name, stats in groups.items(): # type: ignore heading = 'Metrics: %s' % metric_name print() print(heading) print('-' * len(heading)) print() - tabulate_metrics(stats) + tabulate_metrics(stats) # type: ignore else: print("\nNone collected.") print("") ===================================== testsuite/driver/testglobals.py ===================================== @@ -178,6 +178,11 @@ class TestConfig: # threads self.threads = 1 + # An optional executable used to wrap target code execution + # When set tests which aren't marked with TestConfig.cross_okay + # are skipped. + self.target_wrapper = None + # tests which should be considered to be broken during this testsuite # run. self.broken_tests = set() # type: Set[TestName] @@ -304,9 +309,6 @@ class TestRun: global t t = TestRun() -def getTestRun() -> TestRun: - return t - # ----------------------------------------------------------------------------- # Information about the current test @@ -448,6 +450,12 @@ class TestOptions: # Should we copy the files of symlink the files for the test? self.copy_files = False + # Should the test be run in a cross-compiled tree? + # None: infer from test function + # True: run when --target-wrapper is set + # False: do not run in cross-compiled trees + self.cross_okay = None # type: Optional[bool] + # The extra hadrian dependencies we need for this particular test self.hadrian_deps = set(["test:ghc"]) # type: Set[str] ===================================== testsuite/driver/testlib.py ===================================== @@ -36,7 +36,8 @@ from my_typing import * from threading import Timer from collections import OrderedDict -import threading +import asyncio +import contextvars global wantToStop wantToStop = False @@ -80,15 +81,19 @@ def get_all_ways() -> Set[WayName]: # Options valid for the current test only (these get reset to # testdir_testopts after each test). -global testopts_local -testopts_local = threading.local() +global testopts_ctx_var +testopts_ctx_var = contextvars.ContextVar('testopts_ctx_var') # type: ignore def getTestOpts() -> TestOptions: - return testopts_local.x + return testopts_ctx_var.get() def setLocalTestOpts(opts: TestOptions) -> None: - global testopts_local - testopts_local.x = opts + global testopts_ctx_var + testopts_ctx_var.set(opts) + +def isCross() -> bool: + """ Are we testing a cross-compiler? """ + return config.target_wrapper is not None def isCompilerStatsTest() -> bool: opts = getTestOpts() @@ -205,14 +210,8 @@ def have_library(lib: str) -> bool: print(cmd_line) - p = subprocess.Popen(cmd_line, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=ghc_env) - # read from stdout and stderr to avoid blocking due to - # buffers filling - p.communicate() - r = p.wait() + cp = subprocess.run(cmd_line, capture_output=True, env=ghc_env) + r = cp.returncode got_it = r == 0 have_lib_cache[lib] = got_it @@ -255,7 +254,7 @@ def req_dynamic_hs( name, opts ): opts.expect = 'fail' def req_interp( name, opts ): - if not config.have_interp: + if not config.have_interp or isCross(): opts.expect = 'fail' # JS backend doesn't provide an interpreter yet js_skip(name, opts) @@ -633,6 +632,11 @@ KNOWN_OPERATING_SYSTEMS = set([ 'solaris2', ]) +def exe_extension() -> str: + if config.arch == 'wasm32': + return '.wasm' + return '' + def opsys( os: str ) -> bool: assert os in KNOWN_OPERATING_SYSTEMS return config.os == os @@ -1021,8 +1025,11 @@ parallelTests = [] aloneTests = [] allTestNames = set([]) # type: Set[TestName] -def runTest(executor, opts, name: TestName, func, args): - return executor.submit(test_common_work, name, opts, func, args) +async def runTest(sem, opts, name: TestName, func, args): + if sem is None: + return await test_common_work(name, opts, func, args) + async with sem: + return await test_common_work(name, opts, func, args) # name :: String # setup :: [TestOpt] -> IO () @@ -1060,7 +1067,7 @@ def test(name: TestName, if name in config.broken_tests: myTestOpts.expect = 'fail' - thisTest = lambda executor: runTest(executor, myTestOpts, name, func, args) + thisTest = lambda sem: runTest(sem, myTestOpts, name, func, args) if myTestOpts.alone: aloneTests.append(thisTest) else: @@ -1080,7 +1087,7 @@ do_not_copy = ('.hi', '.o', '.dyn_hi' , '.dyn_o', '.out' ,'.hi-boot', '.o-boot') # 12112 -def test_common_work(name: TestName, opts, +async def test_common_work(name: TestName, opts, func, args) -> None: try: t.total_tests += 1 @@ -1098,14 +1105,21 @@ def test_common_work(name: TestName, opts, all_ways = [WayName('ghci')] else: all_ways = [] + if isCross(): + opts.cross_okay = False elif func in [makefile_test, run_command]: # makefile tests aren't necessarily runtime or compile-time # specific. Assume we can run them in all ways. See #16042 for what # happened previously. all_ways = config.compile_ways + config.run_ways + if isCross(): + opts.cross_okay = False else: all_ways = [WayName('normal')] + if isCross() and opts.cross_okay is False: + opts.skip = True + # A test itself can request extra ways by setting opts.extra_ways all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways])) @@ -1176,7 +1190,7 @@ def test_common_work(name: TestName, opts, if stopping(): break try: - do_test(name, way, func, args, files) + await do_test(name, way, func, args, files) except KeyboardInterrupt: stopNow() except Exception as e: @@ -1200,9 +1214,9 @@ def test_common_work(name: TestName, opts, except Exception as e: framework_fail(name, None, 'Unhandled exception: ' + str(e)) -def do_test(name: TestName, +async def do_test(name: TestName, way: WayName, - func: Callable[..., PassFail], + func: Callable[..., Awaitable[PassFail]], args, files: Set[str] ) -> None: @@ -1271,7 +1285,7 @@ def do_test(name: TestName, if opts.pre_cmd: stdout_path = in_testdir(name, 'pre_cmd_stdout') stderr_path = in_testdir(name, 'pre_cmd_stderr') - exit_code = runCmd('cd "{0}" && {1}'.format(opts.testdir, override_options(opts.pre_cmd)), + exit_code = await runCmd('cd "{0}" && {1}'.format(opts.testdir, override_options(opts.pre_cmd)), stdout = stdout_path, stderr = stderr_path, print_output = config.verbose >= 3) @@ -1287,7 +1301,7 @@ def do_test(name: TestName, # Don't continue and try to run the test if the pre_cmd fails. return - result = func(*[name,way] + args) + result = await func(*[name,way] + args) if opts.expect not in ['pass', 'fail', 'missing-lib']: framework_fail(name, way, 'bad expected ' + opts.expect) @@ -1366,20 +1380,20 @@ def framework_warn(name: TestName, way: WayName, reason: str) -> None: # altogether by using the setup function ignore_stdout instead of # run_command. -def run_command( name, way, cmd ): - return simple_run( name, '', override_options(cmd), '' ) +async def run_command( name, way, cmd ): + return await simple_run( name, '', override_options(cmd), '' ) -def makefile_test( name, way, target=None ): +async def makefile_test( name, way, target=None ): if target is None: target = name cmd = '$MAKE -s --no-print-directory {target}'.format(target=target) - return run_command(name, way, cmd) + return await run_command(name, way, cmd) # ----------------------------------------------------------------------------- # GHCi tests -def ghci_script( name, way, script): +async def ghci_script( name, way, script): flags = ' '.join(get_compiler_flags()) way_flags = ' '.join(config.way_flags[way]) @@ -1390,54 +1404,54 @@ def ghci_script( name, way, script): # NB: put way_flags before flags so that flags in all.T can override others getTestOpts().stdin = script - return simple_run( name, way, cmd, getTestOpts().extra_run_opts ) + return await simple_run( name, way, cmd, getTestOpts().extra_run_opts ) # ----------------------------------------------------------------------------- # Compile-only tests -def compile( name, way, extra_hc_opts ): - return do_compile( name, way, False, None, [], [], extra_hc_opts ) +async def compile( name, way, extra_hc_opts ): + return await do_compile( name, way, False, None, [], [], extra_hc_opts ) -def compile_fail( name, way, extra_hc_opts ): - return do_compile( name, way, True, None, [], [], extra_hc_opts ) +async def compile_fail( name, way, extra_hc_opts ): + return await do_compile( name, way, True, None, [], [], extra_hc_opts ) -def backpack_typecheck( name, way, extra_hc_opts ): - return do_compile( name, way, False, None, [], [], "-fno-code -fwrite-interface " + extra_hc_opts, backpack=True ) +async def backpack_typecheck( name, way, extra_hc_opts ): + return await do_compile( name, way, False, None, [], [], "-fno-code -fwrite-interface " + extra_hc_opts, backpack=True ) -def backpack_typecheck_fail( name, way, extra_hc_opts ): - return do_compile( name, way, True, None, [], [], "-fno-code -fwrite-interface " + extra_hc_opts, backpack=True ) +async def backpack_typecheck_fail( name, way, extra_hc_opts ): + return await do_compile( name, way, True, None, [], [], "-fno-code -fwrite-interface " + extra_hc_opts, backpack=True ) -def backpack_compile( name, way, extra_hc_opts ): - return do_compile( name, way, False, None, [], [], extra_hc_opts, backpack=True ) +async def backpack_compile( name, way, extra_hc_opts ): + return await do_compile( name, way, False, None, [], [], extra_hc_opts, backpack=True ) -def backpack_compile_fail( name, way, extra_hc_opts ): - return do_compile( name, way, True, None, [], [], extra_hc_opts, backpack=True ) +async def backpack_compile_fail( name, way, extra_hc_opts ): + return await do_compile( name, way, True, None, [], [], extra_hc_opts, backpack=True ) -def backpack_run( name, way, extra_hc_opts ): - return compile_and_run__( name, way, None, [], extra_hc_opts, backpack=True ) +async def backpack_run( name, way, extra_hc_opts ): + return await compile_and_run__( name, way, None, [], extra_hc_opts, backpack=True ) -def multimod_compile( name, way, top_mod, extra_hc_opts ): - return do_compile( name, way, False, top_mod, [], [], extra_hc_opts ) +async def multimod_compile( name, way, top_mod, extra_hc_opts ): + return await do_compile( name, way, False, top_mod, [], [], extra_hc_opts ) -def multimod_compile_fail( name, way, top_mod, extra_hc_opts ): - return do_compile( name, way, True, top_mod, [], [], extra_hc_opts ) +async def multimod_compile_fail( name, way, top_mod, extra_hc_opts ): + return await do_compile( name, way, True, top_mod, [], [], extra_hc_opts ) -def multimod_compile_filter( name, way, top_mod, extra_hc_opts, filter_with, suppress_stdout=True ): - return do_compile( name, way, False, top_mod, [], [], extra_hc_opts, filter_with=filter_with, suppress_stdout=suppress_stdout ) +async def multimod_compile_filter( name, way, top_mod, extra_hc_opts, filter_with, suppress_stdout=True ): + return await do_compile( name, way, False, top_mod, [], [], extra_hc_opts, filter_with=filter_with, suppress_stdout=suppress_stdout ) -def multiunit_compile( name, way, units, extra_hc_opts ): - return do_compile( name, way, False, None, [], units, extra_hc_opts ) +async def multiunit_compile( name, way, units, extra_hc_opts ): + return await do_compile( name, way, False, None, [], units, extra_hc_opts ) -def multiunit_compile_fail( name, way, units, extra_hc_opts ): - return do_compile( name, way, True, None, [], units, extra_hc_opts ) +async def multiunit_compile_fail( name, way, units, extra_hc_opts ): + return await do_compile( name, way, True, None, [], units, extra_hc_opts ) -def multi_compile( name, way, top_mod, extra_mods, extra_hc_opts ): - return do_compile( name, way, False, top_mod, extra_mods, [], extra_hc_opts) +async def multi_compile( name, way, top_mod, extra_mods, extra_hc_opts ): + return await do_compile( name, way, False, top_mod, extra_mods, [], extra_hc_opts) -def multi_compile_fail( name, way, top_mod, extra_mods, extra_hc_opts ): - return do_compile( name, way, True, top_mod, extra_mods, [], extra_hc_opts) +async def multi_compile_fail( name, way, top_mod, extra_mods, extra_hc_opts ): + return await do_compile( name, way, True, top_mod, extra_mods, [], extra_hc_opts) -def do_compile(name: TestName, +async def do_compile(name: TestName, way: WayName, should_fail: bool, top_mod: Optional[Path], @@ -1448,12 +1462,12 @@ def do_compile(name: TestName, ) -> PassFail: # print 'Compile only, extra args = ', extra_hc_opts - result = extras_build( way, extra_mods, extra_hc_opts ) + result = await extras_build( way, extra_mods, extra_hc_opts ) if badResult(result): return result extra_hc_opts = result.hc_opts - result = simple_build(name, way, extra_hc_opts, should_fail, top_mod, units, False, True, **kwargs) + result = await simple_build(name, way, extra_hc_opts, should_fail, top_mod, units, False, True, **kwargs) if badResult(result): return result @@ -1466,7 +1480,7 @@ def do_compile(name: TestName, actual_stderr_file = add_suffix(name, 'comp.stderr') diff_file_name = in_testdir(add_suffix(name, 'comp.diff')) - if not compare_outputs(way, 'stderr', + if not await compare_outputs(way, 'stderr', join_normalisers(getTestOpts().extra_errmsg_normaliser, normalise_errmsg), expected_stderr_file, actual_stderr_file, @@ -1482,14 +1496,14 @@ def do_compile(name: TestName, # no problems found, this test passed return passed() -def compile_cmp_asm(name: TestName, +async def compile_cmp_asm(name: TestName, way: WayName, ext: str, extra_hc_opts: str ) -> PassFail: if extra_hc_opts: print('Compile only, extra args = ', extra_hc_opts) - result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) + result = await simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): return result @@ -1501,7 +1515,7 @@ def compile_cmp_asm(name: TestName, expected_asm_file = find_expected_file(name, 'asm') actual_asm_file = add_suffix(name, 's') - if not compare_outputs(way, 'asm', + if not await compare_outputs(way, 'asm', join_normalisers(normalise_errmsg, normalise_asm), expected_asm_file, actual_asm_file): return failBecause('asm mismatch') @@ -1509,7 +1523,7 @@ def compile_cmp_asm(name: TestName, # no problems found, this test passed return passed() -def compile_grep_asm(name: TestName, +async def compile_grep_asm(name: TestName, way: WayName, ext: str, is_substring: bool, @@ -1517,7 +1531,7 @@ def compile_grep_asm(name: TestName, ) -> PassFail: if extra_hc_opts: print('Compile and grep asm, extra args = ', extra_hc_opts) - result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) + result = await simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): return result @@ -1533,13 +1547,13 @@ def compile_grep_asm(name: TestName, # no problems found, this test passed return passed() -def compile_grep_core(name: TestName, +async def compile_grep_core(name: TestName, way: WayName, extra_hc_opts: str ) -> PassFail: if extra_hc_opts: print('Compile only, extra args = ', extra_hc_opts) - result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, [], False, False) + result = await simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, [], False, False) if badResult(result): return result @@ -1557,7 +1571,7 @@ def compile_grep_core(name: TestName, # ----------------------------------------------------------------------------- # Compile-and-run tests -def compile_and_run__(name: TestName, +async def compile_and_run__(name: TestName, way: WayName, top_mod: Path, extra_mods: List[str], @@ -1566,38 +1580,38 @@ def compile_and_run__(name: TestName, ) -> PassFail: # print 'Compile and run, extra args = ', extra_hc_opts - result = extras_build( way, extra_mods, extra_hc_opts ) + result = await extras_build( way, extra_mods, extra_hc_opts ) if badResult(result): return result extra_hc_opts = result.hc_opts assert extra_hc_opts is not None if way.startswith('ghci'): # interpreted... - return interpreter_run(name, way, extra_hc_opts, top_mod) + return await interpreter_run(name, way, extra_hc_opts, top_mod) else: # compiled... - result = simple_build(name, way, extra_hc_opts, False, top_mod, [], True, True, backpack = backpack) + result = await simple_build(name, way, extra_hc_opts, False, top_mod, [], True, True, backpack = backpack) if badResult(result): return result - cmd = './' + name; + cmd = './' + name + exe_extension() # we don't check the compiler's stderr for a compile-and-run test - return simple_run( name, way, cmd, getTestOpts().extra_run_opts ) + return await simple_run( name, way, cmd, getTestOpts().extra_run_opts ) -def compile_and_run( name, way, extra_hc_opts ): - return compile_and_run__( name, way, None, [], extra_hc_opts) +async def compile_and_run( name, way, extra_hc_opts ): + return await compile_and_run__( name, way, None, [], extra_hc_opts) -def multimod_compile_and_run( name, way, top_mod, extra_hc_opts ): - return compile_and_run__( name, way, top_mod, [], extra_hc_opts) +async def multimod_compile_and_run( name, way, top_mod, extra_hc_opts ): + return await compile_and_run__( name, way, top_mod, [], extra_hc_opts) -def multi_compile_and_run( name, way, top_mod, extra_mods, extra_hc_opts ): - return compile_and_run__( name, way, top_mod, extra_mods, extra_hc_opts) +async def multi_compile_and_run( name, way, top_mod, extra_mods, extra_hc_opts ): + return await compile_and_run__( name, way, top_mod, extra_mods, extra_hc_opts) def stats( name, way, stats_file ): opts = getTestOpts() return check_stats(name, way, in_testdir(stats_file), opts.stats_range_fields) -def static_stats( name, way, stats_file ): +async def static_stats( name, way, stats_file ): opts = getTestOpts() return check_stats(name, way, in_statsdir(stats_file), opts.stats_range_fields) @@ -1683,9 +1697,9 @@ def check_stats(name: TestName, # ----------------------------------------------------------------------------- # Build a single-module program -def extras_build( way, extra_mods, extra_hc_opts ): +async def extras_build( way, extra_mods, extra_hc_opts ): for mod, opts in extra_mods: - result = simple_build(mod, way, opts + ' ' + extra_hc_opts, False, None, [], False, False) + result = await simple_build(mod, way, opts + ' ' + extra_hc_opts, False, None, [], False, False) if not (mod.endswith('.hs') or mod.endswith('.lhs')): extra_hc_opts += ' %s' % Path(mod).with_suffix('.o') if badResult(result): @@ -1693,7 +1707,7 @@ def extras_build( way, extra_mods, extra_hc_opts ): return passed(hc_opts=extra_hc_opts) -def simple_build(name: Union[TestName, str], +async def simple_build(name: Union[TestName, str], way: WayName, extra_hc_opts: str, should_fail: bool, @@ -1765,7 +1779,7 @@ def simple_build(name: Union[TestName, str], if filter_with != '': cmd = cmd + ' | ' + filter_with - exit_code = runCmd(cmd, None, stdout, stderr, opts.compile_timeout_multiplier) + exit_code = await runCmd(cmd, None, stdout, stderr, opts.compile_timeout_multiplier) actual_stderr_path = in_testdir(name, 'comp.stderr') @@ -1799,7 +1813,7 @@ def simple_build(name: Union[TestName, str], # from /dev/null. Route output to testname.run.stdout and # testname.run.stderr. Returns the exit code of the run. -def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> Any: +async def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> Any: opts = getTestOpts() # figure out what to use for stdin @@ -1831,7 +1845,10 @@ def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> stats_args = '' # Put extra_run_opts last: extra_run_opts('+RTS foo') should work. - cmd = ' '.join([prog, stats_args, my_rts_flags, extra_run_opts]) + args = [prog, stats_args, my_rts_flags, extra_run_opts] + if config.target_wrapper is not None: + args = [config.target_wrapper] + args + cmd = ' '.join(args) if opts.cmd_wrapper is not None: cmd = opts.cmd_wrapper(cmd) @@ -1839,7 +1856,7 @@ def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> cmd = 'cd "{opts.testdir}" && {cmd}'.format(**locals()) # run the command - exit_code = runCmd(cmd, stdin_arg, stdout_arg, stderr_arg, opts.run_timeout_multiplier) + exit_code = await runCmd(cmd, stdin_arg, stdout_arg, stderr_arg, opts.run_timeout_multiplier) # check the exit code if exit_code != opts.exit_code: @@ -1850,11 +1867,11 @@ def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> message = format_bad_exit_code_message(exit_code) return failBecause(message) - if not (opts.ignore_stderr or stderr_ok(name, way) or opts.combined_output): + if not (opts.ignore_stderr or await stderr_ok(name, way) or opts.combined_output): return failBecause('bad stderr', stderr=read_stderr(name), stdout=read_stdout(name)) - if not (opts.ignore_stdout or stdout_ok(name, way)): + if not (opts.ignore_stdout or await stdout_ok(name, way)): return failBecause('bad stdout', stderr=read_stderr(name), stdout=read_stdout(name)) @@ -1863,9 +1880,9 @@ def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> check_prof = '-p' in my_rts_flags # exit_code > 127 probably indicates a crash, so don't try to run hp2ps. - if check_hp and (exit_code <= 127 or exit_code == 251) and not check_hp_ok(name): + if check_hp and (exit_code <= 127 or exit_code == 251) and not await check_hp_ok(name): return failBecause('bad heap profile') - if check_prof and not check_prof_ok(name, way): + if check_prof and not await check_prof_ok(name, way): return failBecause('bad profile') # Check runtime stats if desired. @@ -1881,7 +1898,7 @@ def rts_flags(way: WayName) -> str: # ----------------------------------------------------------------------------- # Run a program in the interpreter and check its output -def interpreter_run(name: TestName, +async def interpreter_run(name: TestName, way: WayName, extra_hc_opts: str, top_mod: Path @@ -1932,7 +1949,7 @@ def interpreter_run(name: TestName, cmd = 'cd "{opts.testdir}" && {cmd}'.format(**locals()) - exit_code = runCmd(cmd, script, stdout, stderr, opts.run_timeout_multiplier) + exit_code = await runCmd(cmd, script, stdout, stderr, opts.run_timeout_multiplier) # split the stdout into compilation/program output split_file(stdout, delimiter, @@ -1955,11 +1972,11 @@ def interpreter_run(name: TestName, # ToDo: if the sub-shell was killed by ^C, then exit - if not (opts.ignore_stderr or stderr_ok(name, way)): + if not (opts.ignore_stderr or await stderr_ok(name, way)): return failBecause('bad stderr', stderr=read_stderr(name), stdout=read_stdout(name)) - elif not (opts.ignore_stdout or stdout_ok(name, way)): + elif not (opts.ignore_stdout or await stdout_ok(name, way)): return failBecause('bad stdout', stderr=read_stderr(name), stdout=read_stdout(name)) @@ -1995,7 +2012,7 @@ def get_compiler_flags() -> List[str]: return flags -def stdout_ok(name: TestName, way: WayName) -> bool: +async def stdout_ok(name: TestName, way: WayName) -> bool: actual_stdout_file = add_suffix(name, 'run.stdout') expected_stdout_file = find_expected_file(name, 'stdout') @@ -2006,7 +2023,7 @@ def stdout_ok(name: TestName, way: WayName) -> bool: actual_stdout_path = in_testdir(actual_stdout_file) return check_stdout(actual_stdout_path, extra_norm) - return compare_outputs(way, 'stdout', extra_norm, + return await compare_outputs(way, 'stdout', extra_norm, expected_stdout_file, actual_stdout_file) def read_stdout( name: TestName ) -> str: @@ -2022,11 +2039,11 @@ def dump_stdout( name: TestName ) -> None: print("Stdout (", name, "):") safe_print(s) -def stderr_ok(name: TestName, way: WayName) -> bool: +async def stderr_ok(name: TestName, way: WayName) -> bool: actual_stderr_file = add_suffix(name, 'run.stderr') expected_stderr_file = find_expected_file(name, 'stderr') - return compare_outputs(way, 'stderr', + return await compare_outputs(way, 'stderr', join_normalisers(normalise_errmsg, getTestOpts().extra_errmsg_normaliser), \ expected_stderr_file, actual_stderr_file, whitespace_normaliser=normalise_whitespace) @@ -2086,20 +2103,20 @@ def write_file(f: Path, s: str) -> None: # Another solution would be to open files in binary mode always, and # operate on bytes. -def check_hp_ok(name: TestName) -> bool: +async def check_hp_ok(name: TestName) -> bool: opts = getTestOpts() # do not qualify for hp2ps because we should be in the right directory hp2psCmd = 'cd "{opts.testdir}" && {{hp2ps}} {name}'.format(**locals()) - hp2psResult = runCmd(hp2psCmd, print_output=True) + hp2psResult = await runCmd(hp2psCmd, print_output=True) actual_ps_path = in_testdir(name, 'ps') if hp2psResult == 0: if actual_ps_path.exists(): - if does_ghostscript_work(): - gsResult = runCmd(genGSCmd(actual_ps_path)) + if await does_ghostscript_work(): + gsResult = await runCmd(genGSCmd(actual_ps_path)) if (gsResult == 0): return True else: @@ -2114,7 +2131,7 @@ def check_hp_ok(name: TestName) -> bool: print("hp2ps error when processing heap profile for " + name) return False -def check_prof_ok(name: TestName, way: WayName) -> bool: +async def check_prof_ok(name: TestName, way: WayName) -> bool: expected_prof_file = find_expected_file(name, 'prof.sample') expected_prof_path = in_testdir(expected_prof_file) @@ -2123,7 +2140,7 @@ def check_prof_ok(name: TestName, way: WayName) -> bool: if not expected_prof_path.exists(): return True - actual_prof_file = add_suffix(name, 'prof') + actual_prof_file = add_suffix(name + exe_extension(), 'prof') actual_prof_path = in_testdir(actual_prof_file) if not actual_prof_path.exists(): @@ -2134,7 +2151,7 @@ def check_prof_ok(name: TestName, way: WayName) -> bool: print("%s is empty" % actual_prof_path) return(False) - return compare_outputs(way, 'prof', normalise_prof, + return await compare_outputs(way, 'prof', normalise_prof, expected_prof_file, actual_prof_file, whitespace_normaliser=normalise_whitespace) @@ -2142,7 +2159,7 @@ def check_prof_ok(name: TestName, way: WayName) -> bool: # new output. Returns true if output matched or was accepted, false # otherwise. See Note [Output comparison] for the meaning of the # normaliser and whitespace_normaliser parameters. -def compare_outputs(way: WayName, +async def compare_outputs(way: WayName, kind: str, normaliser: OutputNormalizer, expected_file, actual_file, diff_file=None, @@ -2180,7 +2197,7 @@ def compare_outputs(way: WayName, if config.verbose >= 1 and _expect_pass(way): # See Note [Output comparison]. - r = runCmd('diff -uw "{0}" "{1}"'.format(null2unix_null(expected_normalised_path), + r = await runCmd('diff -uw "{0}" "{1}"'.format(null2unix_null(expected_normalised_path), actual_normalised_path), stdout=diff_file, print_output=True) @@ -2188,7 +2205,7 @@ def compare_outputs(way: WayName, # If for some reason there were no non-whitespace differences, # then do a full diff if r == 0: - r = runCmd('diff -u "{0}" "{1}"'.format(null2unix_null(expected_normalised_path), + r = await runCmd('diff -u "{0}" "{1}"'.format(null2unix_null(expected_normalised_path), actual_normalised_path), stdout=diff_file, print_output=True) @@ -2333,11 +2350,25 @@ def normalise_errmsg(s: str) -> str: s = normalise_callstacks(s) s = normalise_type_reps(s) + # normalise slashes, minimise Windows/Unix filename differences + s = re.sub('\\\\', '/', s) + + # Normalize the name of the GHC executable. Specifically, + # this catches the cases that: + # + # * In cross-compilers ghc's executable name may include + # a target prefix (e.g. `aarch64-linux-gnu-ghc`) + # * On Windows the executable name may mention the + # versioned name (e.g. `ghc-9.2.1`) + s = re.sub(Path(config.compiler).name + ':', 'ghc:', s) + # If somefile ends in ".exe" or ".exe:", zap ".exe" (for Windows) # the colon is there because it appears in error messages; this # hacky solution is used in place of more sophisticated filename # mangling s = re.sub('([^\\s])\\.exe', '\\1', s) + # Same thing for .wasm modules generated by the Wasm backend + s = re.sub('([^\\s])\\.wasm', '\\1', s) # Same thing for .jsexe directories generated by the JS backend s = re.sub('([^\\s])\\.jsexe', '\\1', s) @@ -2401,6 +2432,9 @@ def normalise_errmsg(s: str) -> str: # clang may warn about unused argument when used as assembler s = re.sub('.*warning: argument unused during compilation:.*\n', '', s) + # strip the cross prefix if any + s = re.sub('^([^:]+-)?ghc:', 'ghc:', s) + return s # normalise a .prof file, so that we can reasonably compare it against @@ -2459,6 +2493,7 @@ def normalise_slashes_( s: str ) -> str: def normalise_exe_( s: str ) -> str: s = re.sub(r'\.exe', '', s) + s = re.sub(r'\.wasm', '', s) s = re.sub(r'\.jsexe', '', s) return s @@ -2468,9 +2503,11 @@ def normalise_output( s: str ) -> str: s = modify_lines(s, lambda l: re.sub(' error:', '', l)) s = modify_lines(s, lambda l: re.sub(' Warning:', ' warning:', l)) # Remove a .exe extension (for Windows) + # and .wasm extension (for the Wasm backend) # and .jsexe extension (for the JS backend) # This can occur in error messages generated by the program. s = re.sub('([^\\s])\\.exe', '\\1', s) + s = re.sub('([^\\s])\\.wasm', '\\1', s) s = re.sub('([^\\s])\\.jsexe', '\\1', s) s = normalise_callstacks(s) s = normalise_type_reps(s) @@ -2490,6 +2527,9 @@ def normalise_output( s: str ) -> str: # clang may warn about unused argument when used as assembler s = re.sub('.*warning: argument unused during compilation:.*\n', '', s) + # strip the cross prefix if any + s = re.sub('^([^:]+-)?ghc:', 'ghc:', s) + return s def normalise_asm( s: str ) -> str: @@ -2527,7 +2567,7 @@ def dump_file(f: Path): except Exception: print('') -def runCmd(cmd: str, +async def runCmd(cmd: str, stdin: Union[None, Path]=None, stdout: Union[None, Path]=None, stderr: Union[None, int, Path]=None, @@ -2544,9 +2584,9 @@ def runCmd(cmd: str, stdout_buffer = b'' stderr_buffer = b'' - hStdErr = subprocess.PIPE - if stderr is subprocess.STDOUT: - hStdErr = subprocess.STDOUT + hStdErr = asyncio.subprocess.PIPE + if stderr is asyncio.subprocess.STDOUT: + hStdErr = asyncio.subprocess.STDOUT try: # cmd is a complex command in Bourne-shell syntax @@ -2554,13 +2594,9 @@ def runCmd(cmd: str, # Hence it must ultimately be run by a Bourne shell. It's timeout's job # to invoke the Bourne shell - r = subprocess.Popen([timeout_prog, timeout, cmd], - stdin=stdin_file, - stdout=subprocess.PIPE, - stderr=hStdErr, - env=ghc_env) + proc = await asyncio.create_subprocess_exec(timeout_prog, timeout, cmd, stdin=stdin_file, stdout=asyncio.subprocess.PIPE, stderr=hStdErr, env=ghc_env) - stdout_buffer, stderr_buffer = r.communicate() + stdout_buffer, stderr_buffer = await proc.communicate() finally: if stdin_file: stdin_file.close() @@ -2580,13 +2616,13 @@ def runCmd(cmd: str, if isinstance(stderr, Path): stderr.write_bytes(stderr_buffer) - if r.returncode == 98: + if proc.returncode == 98: # The python timeout program uses 98 to signal that ^C was pressed stopNow() - if r.returncode == 99 and getTestOpts().exit_code != 99: + if proc.returncode == 99 and getTestOpts().exit_code != 99: # Only print a message when timeout killed the process unexpectedly. if_verbose(1, 'Timeout happened...killed process "{0}"...\n'.format(cmd)) - return r.returncode + return proc.returncode # type: ignore # Each message should be kept lowercase def exit_code_specific_message(exit_code: int) -> str: @@ -2605,34 +2641,45 @@ def format_bad_exit_code_message(exit_code: int) -> str: def genGSCmd(psfile: Path) -> str: return '{{gs}} -dNODISPLAY -dBATCH -dQUIET -dNOPAUSE "{0}"'.format(psfile) - at memoize -def does_ghostscript_work() -> bool: +does_ghostscript_work_cache = None + +async def does_ghostscript_work() -> bool: """ Detect whether Ghostscript is functional. """ + global does_ghostscript_work_cache + if does_ghostscript_work_cache is not None: + return does_ghostscript_work_cache + def gsNotWorking(reason: str) -> None: print("GhostScript not available for hp2ps tests:", reason) if config.gs is None: + does_ghostscript_work_cache = False return False try: - if runCmd(genGSCmd(config.top / 'config' / 'good.ps')) != 0: + if await runCmd(genGSCmd(config.top / 'config' / 'good.ps')) != 0: gsNotWorking("gs can't process good input") + does_ghostscript_work_cache = False return False except Exception as e: gsNotWorking('error invoking gs on bad input: %s' % e) + does_ghostscript_work_cache = False return False try: cmd = genGSCmd(config.top / 'config' / 'bad.ps') + ' >/dev/null 2>&1' - if runCmd(cmd) == 0: + if await runCmd(cmd) == 0: gsNotWorking('gs accepts bad input') + does_ghostscript_work_cache = False return False except Exception as e: gsNotWorking('error invoking gs on bad input: %s' % e) + does_ghostscript_work_cache = False return False + does_ghostscript_work_cache = True return True def add_suffix( name: Union[str, Path], suffix: str ) -> Path: ===================================== testsuite/driver/testutil.py ===================================== @@ -29,9 +29,9 @@ def passed(hc_opts=None) -> PassFail: hc_opts=hc_opts) def failBecause(reason: str, - tag: str=None, - stderr: str=None, - stdout: str=None + tag: Optional[str]=None, + stderr: Optional[str]=None, + stdout: Optional[str]=None ) -> PassFail: return PassFail(passed=False, reason=reason, tag=tag, stderr=stderr, stdout=stdout, hc_opts=None) @@ -49,15 +49,14 @@ def str_info(s: str) -> str: def getStdout(cmd_and_args: List[str]): # Can't use subprocess.check_output, since we also verify that # no stderr was produced - p = subprocess.Popen([strip_quotes(cmd_and_args[0])] + cmd_and_args[1:], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (stdout, stderr) = p.communicate() - r = p.wait() + cp = subprocess.run([strip_quotes(cmd_and_args[0])] + cmd_and_args[1:], capture_output=True) + r = cp.returncode + stdout = cp.stdout + stderr = cp.stderr if r != 0: raise Exception("Command failed: " + str(cmd_and_args)) if stderr: - raise Exception("stderr from command: %s\nStdOut(%s):\n%s\n%s\nOutput(%s):\n%s\n%s\n" % (cmd_and_args,str(len(stdout)), stdout, stdout.decode('utf-8'), str(len(stderr)), stderr, stderr.decode('utf-8'))) + raise Exception("stderr from command: %s\nStdOut(%s):\n%r\n%s\nOutput(%s):\n%r\n%s\n" % (cmd_and_args,str(len(stdout)), stdout, stdout.decode('utf-8'), str(len(stderr)), stderr, stderr.decode('utf-8'))) return stdout.decode('utf-8') def lndir(srcdir: Path, dstdir: Path, force_copy=False): ===================================== testsuite/driver/typing_stubs.py deleted ===================================== @@ -1,23 +0,0 @@ -# Stub definitions for things provided by the `typing` package for use by older -# Python versions which don't ship with `typing`. - -import collections - -class Dummy: - def __getitem__(self, *args): - return None - -List = Dummy() -Tuple = Dummy() -Set = Dummy() -TextIO = Dummy() -Iterator = Dummy() -Callable = Dummy() -Optional = Dummy() -Dict = Dummy() -Union = Dummy() -Any = Dummy() - -NewType = lambda name, ty: ty -def NamedTuple(name, fields): - return collections.namedtuple(name, [field[0] for field in fields]) ===================================== testsuite/timeout/Makefile ===================================== @@ -51,11 +51,7 @@ boot all :: calibrate.out $(TIMEOUT_PROGRAM) calibrate.out: $(RM) -f TimeMe.o TimeMe.hi TimeMe TimeMe.exe - $(PYTHON) calibrate '$(STAGE1_GHC)' > $@ -# We use stage 1 to do the calibration, as stage 2 may not exist. -# This isn't necessarily the compiler we'll be running the testsuite -# with, but it's really the performance of the machine that we're -# interested in + $(PYTHON) calibrate '$(TEST_HC)' > $@ endif endif @@ -66,4 +62,3 @@ clean distclean maintainer-clean: $(RM) -rf install-inplace $(RM) -f calibrate.out $(RM) -f Setup Setup.exe Setup.hi Setup.o - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f885e6575eb741556d6e198d1a9dbdadf10307b...ea853ff066afb4d4f2271b24be898693e2a3e18d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f885e6575eb741556d6e198d1a9dbdadf10307b...ea853ff066afb4d4f2271b24be898693e2a3e18d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 01:28:49 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 31 Mar 2023 21:28:49 -0400 Subject: [Git][ghc/ghc][master] Add test for T23184 Message-ID: <642788d18ac69_3483da4727f6048733a2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 3 changed files: - + testsuite/tests/simplCore/should_run/T23184.hs - + testsuite/tests/simplCore/should_run/T23184.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== testsuite/tests/simplCore/should_run/T23184.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Magic + +main :: IO () +main = print $ noinline (\x -> sum $ tardisManual [0..x]) 0 + +tardisManual :: [Int] -> [Int] +tardisManual xs = + let + go [] !acc _ = ([], 0) + go (_:xs) !acc l = + let (xs', _) = go xs acc l + in (l:xs', 0) + (r, l) = go xs True l + in r +{-# INLINE tardisManual #-} ===================================== testsuite/tests/simplCore/should_run/T23184.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -109,4 +109,5 @@ test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) +test('T23184', normal, compile_and_run, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0077cb225bde18ee6c7ff49d6486eb20fc6c011a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0077cb225bde18ee6c7ff49d6486eb20fc6c011a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 01:59:56 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 31 Mar 2023 21:59:56 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add test for T23184 Message-ID: <6427901c1eaac_3483da4806099488306e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 709214a9 by mangoiv at 2023-03-31T21:59:42-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - d8955491 by Artem Pelenitsyn at 2023-03-31T21:59:48-04:00 User Guide: update copyright year: 2020->2023 - - - - - 19 changed files: - docs/users_guide/conf.py - libraries/base/GHC/Base.hs - libraries/base/changelog.md - testsuite/tests/dependent/ghci/T11549.stdout - testsuite/tests/dependent/ghci/T11786.stdout - testsuite/tests/ghci/scripts/T18755.stdout - + testsuite/tests/simplCore/should_run/T23184.hs - + testsuite/tests/simplCore/should_run/T23184.stdout - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/typecheck/should_compile/abstract_refinement_hole_fits.stderr - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr - testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr - testsuite/tests/typecheck/should_fail/T14884.stderr - − testsuite/tests/typecheck/should_fail/T5570.stderr - testsuite/tests/typecheck/should_fail/all.T - testsuite/tests/typecheck/should_fail/T5570.hs → testsuite/tests/typecheck/should_run/T5570.hs - + testsuite/tests/typecheck/should_run/T5570.stdout - testsuite/tests/typecheck/should_run/all.T Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -47,7 +47,7 @@ rst_prolog = """ # General information about the project. project = u'Glasgow Haskell Compiler' -copyright = u'2020, GHC Team' +copyright = u'2023, GHC Team' # N.B. version comes from ghc_config release = version # The full version, including alpha/beta/rc tags. ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1598,6 +1598,14 @@ const x _ = x flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x +-- Note: Before base-4.19, ($) was not representation polymorphic +-- in both type parameters but only in the return type. +-- The generalization forced a change to the implementation, +-- changing its laziness, affecting expressions like (($) undefined): before +-- base-4.19 the expression (($) undefined) `seq` () was equivalent to +-- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now +-- it is equivalent to undefined `seq` () which diverges. + -- | Application operator. This operator is redundant, since ordinary -- application @(f x)@ means the same as @(f '$' x)@. However, '$' has -- low, right-associative binding precedence, so it sometimes allows @@ -1608,11 +1616,11 @@ flip f x y = f y x -- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, -- or @'Data.List.zipWith' ('$') fs xs at . -- --- Note that @('$')@ is representation-polymorphic in its result type, so that --- @foo '$' True@ where @foo :: Bool -> Int#@ is well-typed. +-- Note that @('$')@ is representation-polymorphic, so that +-- @foo '$' 4#@ where @foo :: Int# -> Int#@ is well-typed. {-# INLINE ($) #-} -($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b -f $ x = f x +($) :: forall repa repb (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b +($) f = f -- | Strict (call-by-value) application operator. It takes a function and an -- argument, evaluates the argument to weak head normal form (WHNF), then calls ===================================== libraries/base/changelog.md ===================================== @@ -21,6 +21,7 @@ ([CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148)) * Add `COMPLETE` pragmas to the `TypeRep`, `SSymbol`, `SChar`, and `SNat` pattern synonyms. ([CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149)) + * Make `($)` representation polymorphic ([CLC proposal #132](https://github.com/haskell/core-libraries-committee/issues/132)) ## 4.18.0.0 *TBA* * Shipped with GHC 9.6.1 ===================================== testsuite/tests/dependent/ghci/T11549.stdout ===================================== @@ -8,8 +8,14 @@ error :: GHC.Stack.Types.HasCallStack => [Char] -> a -- Defined in ‘GHC.Err’ -fprint-explicit-runtime-reps -($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b -($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b +($) + :: forall (repa :: RuntimeRep) (repb :: RuntimeRep) + (a :: TYPE repa) (b :: TYPE repb). + (a -> b) -> a -> b +($) :: + forall (repa :: RuntimeRep) (repb :: RuntimeRep) (a :: TYPE repa) + (b :: TYPE repb). + (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ TYPE :: RuntimeRep -> * ===================================== testsuite/tests/dependent/ghci/T11786.stdout ===================================== @@ -3,13 +3,16 @@ ($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ ($) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b (($)) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ($) :: - forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ ===================================== testsuite/tests/ghci/scripts/T18755.stdout ===================================== @@ -1,3 +1,4 @@ ($) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ===================================== testsuite/tests/simplCore/should_run/T23184.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Magic + +main :: IO () +main = print $ noinline (\x -> sum $ tardisManual [0..x]) 0 + +tardisManual :: [Int] -> [Int] +tardisManual xs = + let + go [] !acc _ = ([], 0) + go (_:xs) !acc l = + let (xs', _) = go xs acc l + in (l:xs', 0) + (r, l) = go xs True l + in r +{-# INLINE tardisManual #-} ===================================== testsuite/tests/simplCore/should_run/T23184.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -109,4 +109,5 @@ test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) +test('T23184', normal, compile_and_run, ['-O']) ===================================== testsuite/tests/typecheck/should_compile/abstract_refinement_hole_fits.stderr ===================================== @@ -115,10 +115,10 @@ abstract_refinement_hole_fits.hs:4:5: warning: [GHC-88464] [-Wtyped-holes (in -W where uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c seq (_ :: t2) (_ :: [Integer] -> Integer) where seq :: forall a b. a -> b -> b - ($) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) - where ($) :: forall a b. (a -> b) -> a -> b ($!) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) where ($!) :: forall a b. (a -> b) -> a -> b + ($) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) + where ($) :: forall a b. (a -> b) -> a -> b return (_ :: [Integer] -> Integer) (_ :: t0) where return :: forall (m :: * -> *) a. Monad m => a -> m a pure (_ :: [Integer] -> Integer) (_ :: t0) @@ -237,10 +237,10 @@ abstract_refinement_hole_fits.hs:7:5: warning: [GHC-88464] [-Wtyped-holes (in -W where uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c seq (_ :: t2) (_ :: Integer -> [Integer] -> Integer) where seq :: forall a b. a -> b -> b - ($) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) - where ($) :: forall a b. (a -> b) -> a -> b ($!) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) where ($!) :: forall a b. (a -> b) -> a -> b + ($) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) + where ($) :: forall a b. (a -> b) -> a -> b return (_ :: Integer -> [Integer] -> Integer) (_ :: t0) where return :: forall (m :: * -> *) a. Monad m => a -> m a pure (_ :: Integer -> [Integer] -> Integer) (_ :: t0) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -184,7 +184,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] round :: forall a b. (RealFrac a, Integral b) => a -> b truncate :: forall a b. (RealFrac a, Integral b) => a -> b seq :: forall a b. a -> b -> b - ($) :: forall a b. (a -> b) -> a -> b either :: forall a c b. (a -> c) -> (b -> c) -> Either a b -> c curry :: forall a b c. ((a, b) -> c) -> a -> b -> c uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c @@ -194,5 +193,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] unzip3 :: forall a b c. [(a, b, c)] -> ([a], [b], [c]) zip3 :: forall a b c. [a] -> [b] -> [c] -> [(a, b, c)] zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] + ($) :: forall a b. (a -> b) -> a -> b zipWith3 :: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -187,7 +187,6 @@ holes3.hs:11:15: error: [GHC-88464] round :: forall a b. (RealFrac a, Integral b) => a -> b truncate :: forall a b. (RealFrac a, Integral b) => a -> b seq :: forall a b. a -> b -> b - ($) :: forall a b. (a -> b) -> a -> b either :: forall a c b. (a -> c) -> (b -> c) -> Either a b -> c curry :: forall a b c. ((a, b) -> c) -> a -> b -> c uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c @@ -197,5 +196,6 @@ holes3.hs:11:15: error: [GHC-88464] unzip3 :: forall a b c. [(a, b, c)] -> ([a], [b], [c]) zip3 :: forall a b c. [a] -> [b] -> [c] -> [(a, b, c)] zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] + ($) :: forall a b. (a -> b) -> a -> b zipWith3 :: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] ===================================== testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr ===================================== @@ -67,7 +67,10 @@ refinement_hole_fits.hs:4:5: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] (and originally defined in ‘GHC.Base’)) ($) (_ :: [Integer] -> Integer) where ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @[Integer] @Integer + with ($) @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @[Integer] + @Integer (imported from ‘Prelude’ at refinement_hole_fits.hs:1:8-30 (and originally defined in ‘GHC.Base’)) ($!) (_ :: [Integer] -> Integer) @@ -168,7 +171,10 @@ refinement_hole_fits.hs:7:5: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] (and originally defined in ‘GHC.Base’)) ($) (_ :: Integer -> [Integer] -> Integer) where ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @Integer @([Integer] -> Integer) + with ($) @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @Integer + @([Integer] -> Integer) (imported from ‘Prelude’ at refinement_hole_fits.hs:1:8-30 (and originally defined in ‘GHC.Base’)) ($!) (_ :: Integer -> [Integer] -> Integer) ===================================== testsuite/tests/typecheck/should_fail/T14884.stderr ===================================== @@ -23,7 +23,7 @@ T14884.hs:4:5: error: [GHC-88464] (imported from ‘Prelude’ at T14884.hs:1:8-13 (and originally defined in ‘GHC.Base’)) ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @String @(IO ()) + with ($) @GHC.Types.LiftedRep @GHC.Types.LiftedRep @String @(IO ()) (imported from ‘Prelude’ at T14884.hs:1:8-13 (and originally defined in ‘GHC.Base’)) ($!) :: forall a b. (a -> b) -> a -> b ===================================== testsuite/tests/typecheck/should_fail/T5570.stderr deleted ===================================== @@ -1,6 +0,0 @@ - -T5570.hs:7:16: error: [GHC-83865] - • Expected a lifted type, but ‘Double#’ is a DoubleRep type - • In the first argument of ‘($)’, namely ‘D#’ - In the second argument of ‘($)’, namely ‘D# $ 3.0##’ - In the expression: print $ D# $ 3.0## ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -265,7 +265,6 @@ test('AssocTyDef07', normal, compile_fail, ['']) test('AssocTyDef08', normal, compile_fail, ['']) test('AssocTyDef09', normal, compile_fail, ['']) test('T3592', normal, compile_fail, ['']) -test('T5570', normal, compile_fail, ['']) test('T5691', normal, compile_fail, ['']) test('T5689', normal, compile_fail, ['']) test('T5684', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/T5570.hs → testsuite/tests/typecheck/should_run/T5570.hs ===================================== @@ -1,5 +1,5 @@ {-# LANGUAGE MagicHash #-} -module T5570 where +module Main where import GHC.Exts ===================================== testsuite/tests/typecheck/should_run/T5570.stdout ===================================== @@ -0,0 +1 @@ +3.0 ===================================== testsuite/tests/typecheck/should_run/all.T ===================================== @@ -94,6 +94,7 @@ test('T4809', normal, compile_and_run, ['']) test('T2722', normal, compile_and_run, ['']) test('mc17', normal, compile_and_run, ['']) test('T5759', normal, compile_and_run, ['']) +test('T5570', normal, compile_and_run, ['']) test('T5573a', omit_ways(['ghci']), compile_and_run, ['']) test('T5573b', omit_ways(['ghci']), compile_and_run, ['']) test('T7023', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f361393418831461e4b8949e4b7dd0bf4ae6909d...d895549185f5cef314ca679b4b1e112c07d42ad2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f361393418831461e4b8949e4b7dd0bf4ae6909d...d895549185f5cef314ca679b4b1e112c07d42ad2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 08:20:27 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 04:20:27 -0400 Subject: [Git][ghc/ghc][master] [feat] make ($) representation polymorphic Message-ID: <6427e94b6eeaf_3483da4e14175491874b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 15 changed files: - libraries/base/GHC/Base.hs - libraries/base/changelog.md - testsuite/tests/dependent/ghci/T11549.stdout - testsuite/tests/dependent/ghci/T11786.stdout - testsuite/tests/ghci/scripts/T18755.stdout - testsuite/tests/typecheck/should_compile/abstract_refinement_hole_fits.stderr - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr - testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr - testsuite/tests/typecheck/should_fail/T14884.stderr - − testsuite/tests/typecheck/should_fail/T5570.stderr - testsuite/tests/typecheck/should_fail/all.T - testsuite/tests/typecheck/should_fail/T5570.hs → testsuite/tests/typecheck/should_run/T5570.hs - + testsuite/tests/typecheck/should_run/T5570.stdout - testsuite/tests/typecheck/should_run/all.T Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1598,6 +1598,14 @@ const x _ = x flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x +-- Note: Before base-4.19, ($) was not representation polymorphic +-- in both type parameters but only in the return type. +-- The generalization forced a change to the implementation, +-- changing its laziness, affecting expressions like (($) undefined): before +-- base-4.19 the expression (($) undefined) `seq` () was equivalent to +-- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now +-- it is equivalent to undefined `seq` () which diverges. + -- | Application operator. This operator is redundant, since ordinary -- application @(f x)@ means the same as @(f '$' x)@. However, '$' has -- low, right-associative binding precedence, so it sometimes allows @@ -1608,11 +1616,11 @@ flip f x y = f y x -- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, -- or @'Data.List.zipWith' ('$') fs xs at . -- --- Note that @('$')@ is representation-polymorphic in its result type, so that --- @foo '$' True@ where @foo :: Bool -> Int#@ is well-typed. +-- Note that @('$')@ is representation-polymorphic, so that +-- @foo '$' 4#@ where @foo :: Int# -> Int#@ is well-typed. {-# INLINE ($) #-} -($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b -f $ x = f x +($) :: forall repa repb (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b +($) f = f -- | Strict (call-by-value) application operator. It takes a function and an -- argument, evaluates the argument to weak head normal form (WHNF), then calls ===================================== libraries/base/changelog.md ===================================== @@ -21,6 +21,7 @@ ([CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148)) * Add `COMPLETE` pragmas to the `TypeRep`, `SSymbol`, `SChar`, and `SNat` pattern synonyms. ([CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149)) + * Make `($)` representation polymorphic ([CLC proposal #132](https://github.com/haskell/core-libraries-committee/issues/132)) ## 4.18.0.0 *TBA* * Shipped with GHC 9.6.1 ===================================== testsuite/tests/dependent/ghci/T11549.stdout ===================================== @@ -8,8 +8,14 @@ error :: GHC.Stack.Types.HasCallStack => [Char] -> a -- Defined in ‘GHC.Err’ -fprint-explicit-runtime-reps -($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b -($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b +($) + :: forall (repa :: RuntimeRep) (repb :: RuntimeRep) + (a :: TYPE repa) (b :: TYPE repb). + (a -> b) -> a -> b +($) :: + forall (repa :: RuntimeRep) (repb :: RuntimeRep) (a :: TYPE repa) + (b :: TYPE repb). + (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ TYPE :: RuntimeRep -> * ===================================== testsuite/tests/dependent/ghci/T11786.stdout ===================================== @@ -3,13 +3,16 @@ ($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ ($) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b (($)) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ($) :: - forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b -- Defined in ‘GHC.Base’ infixr 0 $ ===================================== testsuite/tests/ghci/scripts/T18755.stdout ===================================== @@ -1,3 +1,4 @@ ($) - :: forall (r :: GHC.Types.RuntimeRep) a (b :: TYPE r). + :: forall (repa :: GHC.Types.RuntimeRep) + (repb :: GHC.Types.RuntimeRep) (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ===================================== testsuite/tests/typecheck/should_compile/abstract_refinement_hole_fits.stderr ===================================== @@ -115,10 +115,10 @@ abstract_refinement_hole_fits.hs:4:5: warning: [GHC-88464] [-Wtyped-holes (in -W where uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c seq (_ :: t2) (_ :: [Integer] -> Integer) where seq :: forall a b. a -> b -> b - ($) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) - where ($) :: forall a b. (a -> b) -> a -> b ($!) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) where ($!) :: forall a b. (a -> b) -> a -> b + ($) (_ :: t0 -> [Integer] -> Integer) (_ :: t0) + where ($) :: forall a b. (a -> b) -> a -> b return (_ :: [Integer] -> Integer) (_ :: t0) where return :: forall (m :: * -> *) a. Monad m => a -> m a pure (_ :: [Integer] -> Integer) (_ :: t0) @@ -237,10 +237,10 @@ abstract_refinement_hole_fits.hs:7:5: warning: [GHC-88464] [-Wtyped-holes (in -W where uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c seq (_ :: t2) (_ :: Integer -> [Integer] -> Integer) where seq :: forall a b. a -> b -> b - ($) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) - where ($) :: forall a b. (a -> b) -> a -> b ($!) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) where ($!) :: forall a b. (a -> b) -> a -> b + ($) (_ :: t0 -> Integer -> [Integer] -> Integer) (_ :: t0) + where ($) :: forall a b. (a -> b) -> a -> b return (_ :: Integer -> [Integer] -> Integer) (_ :: t0) where return :: forall (m :: * -> *) a. Monad m => a -> m a pure (_ :: Integer -> [Integer] -> Integer) (_ :: t0) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -184,7 +184,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] round :: forall a b. (RealFrac a, Integral b) => a -> b truncate :: forall a b. (RealFrac a, Integral b) => a -> b seq :: forall a b. a -> b -> b - ($) :: forall a b. (a -> b) -> a -> b either :: forall a c b. (a -> c) -> (b -> c) -> Either a b -> c curry :: forall a b c. ((a, b) -> c) -> a -> b -> c uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c @@ -194,5 +193,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] unzip3 :: forall a b c. [(a, b, c)] -> ([a], [b], [c]) zip3 :: forall a b c. [a] -> [b] -> [c] -> [(a, b, c)] zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] + ($) :: forall a b. (a -> b) -> a -> b zipWith3 :: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -187,7 +187,6 @@ holes3.hs:11:15: error: [GHC-88464] round :: forall a b. (RealFrac a, Integral b) => a -> b truncate :: forall a b. (RealFrac a, Integral b) => a -> b seq :: forall a b. a -> b -> b - ($) :: forall a b. (a -> b) -> a -> b either :: forall a c b. (a -> c) -> (b -> c) -> Either a b -> c curry :: forall a b c. ((a, b) -> c) -> a -> b -> c uncurry :: forall a b c. (a -> b -> c) -> (a, b) -> c @@ -197,5 +196,6 @@ holes3.hs:11:15: error: [GHC-88464] unzip3 :: forall a b c. [(a, b, c)] -> ([a], [b], [c]) zip3 :: forall a b c. [a] -> [b] -> [c] -> [(a, b, c)] zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] + ($) :: forall a b. (a -> b) -> a -> b zipWith3 :: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d] ===================================== testsuite/tests/typecheck/should_compile/refinement_hole_fits.stderr ===================================== @@ -67,7 +67,10 @@ refinement_hole_fits.hs:4:5: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] (and originally defined in ‘GHC.Base’)) ($) (_ :: [Integer] -> Integer) where ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @[Integer] @Integer + with ($) @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @[Integer] + @Integer (imported from ‘Prelude’ at refinement_hole_fits.hs:1:8-30 (and originally defined in ‘GHC.Base’)) ($!) (_ :: [Integer] -> Integer) @@ -168,7 +171,10 @@ refinement_hole_fits.hs:7:5: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] (and originally defined in ‘GHC.Base’)) ($) (_ :: Integer -> [Integer] -> Integer) where ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @Integer @([Integer] -> Integer) + with ($) @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @Integer + @([Integer] -> Integer) (imported from ‘Prelude’ at refinement_hole_fits.hs:1:8-30 (and originally defined in ‘GHC.Base’)) ($!) (_ :: Integer -> [Integer] -> Integer) ===================================== testsuite/tests/typecheck/should_fail/T14884.stderr ===================================== @@ -23,7 +23,7 @@ T14884.hs:4:5: error: [GHC-88464] (imported from ‘Prelude’ at T14884.hs:1:8-13 (and originally defined in ‘GHC.Base’)) ($) :: forall a b. (a -> b) -> a -> b - with ($) @GHC.Types.LiftedRep @String @(IO ()) + with ($) @GHC.Types.LiftedRep @GHC.Types.LiftedRep @String @(IO ()) (imported from ‘Prelude’ at T14884.hs:1:8-13 (and originally defined in ‘GHC.Base’)) ($!) :: forall a b. (a -> b) -> a -> b ===================================== testsuite/tests/typecheck/should_fail/T5570.stderr deleted ===================================== @@ -1,6 +0,0 @@ - -T5570.hs:7:16: error: [GHC-83865] - • Expected a lifted type, but ‘Double#’ is a DoubleRep type - • In the first argument of ‘($)’, namely ‘D#’ - In the second argument of ‘($)’, namely ‘D# $ 3.0##’ - In the expression: print $ D# $ 3.0## ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -265,7 +265,6 @@ test('AssocTyDef07', normal, compile_fail, ['']) test('AssocTyDef08', normal, compile_fail, ['']) test('AssocTyDef09', normal, compile_fail, ['']) test('T3592', normal, compile_fail, ['']) -test('T5570', normal, compile_fail, ['']) test('T5691', normal, compile_fail, ['']) test('T5689', normal, compile_fail, ['']) test('T5684', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/T5570.hs → testsuite/tests/typecheck/should_run/T5570.hs ===================================== @@ -1,5 +1,5 @@ {-# LANGUAGE MagicHash #-} -module T5570 where +module Main where import GHC.Exts ===================================== testsuite/tests/typecheck/should_run/T5570.stdout ===================================== @@ -0,0 +1 @@ +3.0 ===================================== testsuite/tests/typecheck/should_run/all.T ===================================== @@ -94,6 +94,7 @@ test('T4809', normal, compile_and_run, ['']) test('T2722', normal, compile_and_run, ['']) test('mc17', normal, compile_and_run, ['']) test('T5759', normal, compile_and_run, ['']) +test('T5570', normal, compile_and_run, ['']) test('T5573a', omit_ways(['ghci']), compile_and_run, ['']) test('T5573b', omit_ways(['ghci']), compile_and_run, ['']) test('T7023', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62d25071791b68fa63a2bb007fd1ac565795a9c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62d25071791b68fa63a2bb007fd1ac565795a9c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 08:20:57 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 04:20:57 -0400 Subject: [Git][ghc/ghc][master] User Guide: update copyright year: 2020->2023 Message-ID: <6427e9695e717_3483da4e7aa85c922275@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 1 changed file: - docs/users_guide/conf.py Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -47,7 +47,7 @@ rst_prolog = """ # General information about the project. project = u'Glasgow Haskell Compiler' -copyright = u'2020, GHC Team' +copyright = u'2023, GHC Team' # N.B. version comes from ghc_config release = version # The full version, including alpha/beta/rc tags. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77c33fb924d75f502e275c7afbf157e6d963abf4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77c33fb924d75f502e275c7afbf157e6d963abf4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 08:23:24 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 01 Apr 2023 04:23:24 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 3 commits: Smaller diff Message-ID: <6427e9fccae0e_3483da4e7aa3989225ba@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 976a17b4 by Sven Tennie at 2023-03-31T13:42:06+00:00 Smaller diff - - - - - 2ebcbc40 by Sven Tennie at 2023-03-31T13:48:04+00:00 Add comment - - - - - dee3ad94 by Sven Tennie at 2023-04-01T08:23:02+00:00 Add comment - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -77,13 +77,6 @@ instance Show Box where addr = ptr - tag pad_out ls = '0':'x':ls --- | Boxes can be compared, but this is not pure, as different heap objects can, --- after garbage collection, become the same object. -areBoxesEqual :: Box -> Box -> IO Bool -areBoxesEqual (Box a) (Box b) = case reallyUnsafePtrEqualityUpToTag# a b of - 0# -> pure False - _ -> pure True - -- |This takes an arbitrary value and puts it into a box. -- Note that calls like -- @@ -96,6 +89,14 @@ areBoxesEqual (Box a) (Box b) = case reallyUnsafePtrEqualityUpToTag# a b of asBox :: a -> Box asBox x = Box (unsafeCoerce# x) +-- | Boxes can be compared, but this is not pure, as different heap objects can, +-- after garbage collection, become the same object. +areBoxesEqual :: Box -> Box -> IO Bool +areBoxesEqual (Box a) (Box b) = case reallyUnsafePtrEqualityUpToTag# a b of + 0# -> pure False + _ -> pure True + + ------------------------------------------------------------------------ -- Closures type Closure = GenClosure Box @@ -357,6 +358,10 @@ data GenClosure b { info :: !StgInfoTable } + -- | A primitive word from a bitmap encoded stack frame payload + -- + -- The type itself cannot be restored (i.e. it might also represent a byte + -- or an int). | UnknownTypeWordSizedPrimitive { wordVal :: !Word } deriving (Show, Generic, Functor, Foldable, Traversable) @@ -446,6 +451,8 @@ data StackFrame = } deriving (Show, Generic) +-- | Fun types according to @FunTypes.h@ +-- This `Enum` must be aligned with the values in @FunTypes.h at . data RetFunType = ARG_GEN | ARG_GEN_BIG | @@ -545,5 +552,4 @@ allClosures (FunClosure {..}) = ptrArgs allClosures (BlockingQueueClosure {..}) = [link, blackHole, owner, queue] allClosures (WeakClosure {..}) = [cfinalizers, key, value, finalizer] ++ Data.Foldable.toList weakLink allClosures (OtherClosure {..}) = hvalues -allClosures (StackClosure {}) = [] allClosures _ = [] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f07b2836603e11324171cc0b37b9b52423aca4f...dee3ad94ebb5572a5a110d804afbcfcb453cfb12 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f07b2836603e11324171cc0b37b9b52423aca4f...dee3ad94ebb5572a5a110d804afbcfcb453cfb12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 08:47:53 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 01 Apr 2023 04:47:53 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Add C function signatures to Cmm for readability Message-ID: <6427efb9ab6aa_3483da4ef0e88c9266ee@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 6c86f493 by Sven Tennie at 2023-04-01T08:47:26+00:00 Add C function signatures to Cmm for readability - - - - - 1 changed file: - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -8,6 +8,7 @@ // developed. #if defined(StgStack_marking) +// advanceStackFrameIterzh(StgStack* stack, StgWord offsetWords) advanceStackFrameIterzh (P_ stack, W_ offsetWords) { W_ frameSize; (frameSize) = ccall stackFrameSize(stack, offsetWords); @@ -47,6 +48,7 @@ advanceStackFrameIterzh (P_ stack, W_ offsetWords) { return (newStack, newOffsetWords, hasNext); } +// getSmallBitmapzh(StgStack* stack, StgWord offsetWords) getSmallBitmapzh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); @@ -59,6 +61,8 @@ getSmallBitmapzh(P_ stack, W_ offsetWords) { return (bitmap, size); } + +// getRetFunSmallBitmapzh(StgStack* stack, StgWord offsetWords) getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); @@ -71,7 +75,8 @@ getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) { return (bitmap, size); } -getLargeBitmapzh(P_ stack, W_ offsetWords){ +// getLargeBitmapzh(StgStack* stack, StgWord offsetWords) +getLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, stgArrBytes; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); @@ -83,7 +88,8 @@ getLargeBitmapzh(P_ stack, W_ offsetWords){ return (stgArrBytes, size); } -getBCOLargeBitmapzh(P_ stack, W_ offsetWords){ +// getBCOLargeBitmapzh(StgStack* stack, StgWord offsetWords) +getBCOLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, stgArrBytes; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); @@ -95,7 +101,8 @@ getBCOLargeBitmapzh(P_ stack, W_ offsetWords){ return (stgArrBytes, size); } -getRetFunLargeBitmapzh(P_ stack, W_ offsetWords){ +// getRetFunLargeBitmapzh(StgStack* stack, StgWord offsetWords) +getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, stgArrBytes; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); @@ -107,7 +114,8 @@ getRetFunLargeBitmapzh(P_ stack, W_ offsetWords){ return (stgArrBytes, size); } -getWordzh(P_ stack, W_ offsetWords, W_ offsetBytes){ +// getWordzh(StgStack* stack, StgWord offsetWords, StgWord offsetBytes) +getWordzh(P_ stack, W_ offsetWords, W_ offsetBytes) { P_ wordAddr; wordAddr = (StgStack_sp(stack) + WDS(offsetWords) + WDS(offsetBytes)); return (W_[wordAddr]); @@ -121,7 +129,8 @@ getAddrzh(P_ stack, W_ offsetWords){ return (ptr); } -getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords){ +// getUnderflowFrameNextChunkzh(StgStack* stack, StgWord offsetWords) +getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords) { P_ closurePtr; closurePtr = (StgStack_sp(stack) + WDS(offsetWords)); ASSERT(LOOKS_LIKE_CLOURE_PTR(closurePtr)); @@ -132,7 +141,8 @@ getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords){ return (next_chunk); } -getRetFunTypezh(P_ stack, W_ offsetWords){ +// getRetFunTypezh(StgStack* stack, StgWord offsetWords) +getRetFunTypezh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); @@ -142,7 +152,8 @@ getRetFunTypezh(P_ stack, W_ offsetWords){ return (type); } -getInfoTableAddrzh(P_ stack, W_ offsetWords){ +// getInfoTableAddrzh(StgStack* stack, StgWord offsetWords) +getInfoTableAddrzh(P_ stack, W_ offsetWords) { P_ p, info; p = StgStack_sp(stack) + WDS(offsetWords); ASSERT(LOOKS_LIKE_CLOSURE_PTR(p)); @@ -151,13 +162,15 @@ getInfoTableAddrzh(P_ stack, W_ offsetWords){ return (info); } -getStackInfoTableAddrzh(P_ stack){ +// getStackInfoTableAddrzh(StgStack* stack) +getStackInfoTableAddrzh(P_ stack) { P_ info; info = %GET_STD_INFO(UNTAG(stack)); return (info); } -getBoxedClosurezh(P_ stack, W_ offsetWords){ +// getBoxedClosurezh(StgStack* stack, StgWord offsetWords) +getBoxedClosurezh(P_ stack, W_ offsetWords) { P_ ptr; ptr = StgStack_sp(stack) + WDS(offsetWords); @@ -166,6 +179,7 @@ getBoxedClosurezh(P_ stack, W_ offsetWords){ return (box); } +// getStackFieldszh(StgStack* stack) getStackFieldszh(P_ stack){ bits32 size; bits8 dirty, marking; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c86f4938396ce99f66556626a2e28d9abb33502 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c86f4938396ce99f66556626a2e28d9abb33502 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 08:52:24 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 04:52:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: [feat] make ($) representation polymorphic Message-ID: <6427f0c87ed20_3483da4f479a9c92852b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - b0c9c7db by doyougnu at 2023-04-01T04:52:07-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - 8d98ba7d by Torsten Schmits at 2023-04-01T04:52:20-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/JS/Ppr.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Printer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Map.hs - compiler/GHC/Unit/State.hs - docs/users_guide/conf.py - libraries/base/GHC/Base.hs - libraries/base/changelog.md - testsuite/tests/dependent/ghci/T11549.stdout - testsuite/tests/dependent/ghci/T11786.stdout - testsuite/tests/driver/T11381.hs - testsuite/tests/driver/T11381.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d895549185f5cef314ca679b4b1e112c07d42ad2...8d98ba7d11078368d1d37f505bca67fff2a7832f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d895549185f5cef314ca679b4b1e112c07d42ad2...8d98ba7d11078368d1d37f505bca67fff2a7832f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 11:59:05 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Sat, 01 Apr 2023 07:59:05 -0400 Subject: [Git][ghc/ghc][wip/bootstrap-9_6] 20 commits: ci: make lint-ci-config job fast again Message-ID: <64281c89e27f8_3483da526b9b38968560@gitlab.mail> Matthew Pickering pushed to branch wip/bootstrap-9_6 at Glasgow Haskell Compiler / GHC Commits: 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 7628ad37 by Matthew Pickering at 2023-04-01T12:57:53+01:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - 125773b6 by Matthew Pickering at 2023-04-01T12:58:57+01:00 ci: Add job to test 9.6 bootstrapping - - - - - 11 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - docs/users_guide/conf.py - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cce1ac568a4235cc174ba7bc6e79a14ebad22e8d...125773b613b3333d3c3229067cb3515c8f7c7c4f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cce1ac568a4235cc174ba7bc6e79a14ebad22e8d...125773b613b3333d3c3229067cb3515c8f7c7c4f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 13:42:56 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 09:42:56 -0400 Subject: [Git][ghc/ghc][master] driver: Unit State Data.Map -> GHC.Unique.UniqMap Message-ID: <642834e04dcc7_3483da543411489956b8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - 13 changed files: - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/JS/Ppr.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Printer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Map.hs - compiler/GHC/Unit/State.hs - utils/haddock Changes: ===================================== compiler/GHC/CmmToAsm/Wasm/Utils.hs ===================================== @@ -23,7 +23,7 @@ detEltsUFM :: Ord k => UniqFM k0 (k, a) -> [(k, a)] detEltsUFM = sortOn fst . nonDetEltsUFM detEltsUniqMap :: Ord k => UniqMap k a -> [(k, a)] -detEltsUniqMap = sortOn fst . nonDetEltsUniqMap +detEltsUniqMap = sortOn fst . nonDetUniqMapToList builderCommas :: (a -> Builder) -> [a] -> Builder builderCommas f xs = mconcat (intersperse ", " (map f xs)) ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -105,6 +105,7 @@ import GHC.Types.Target import GHC.Types.SourceFile import GHC.Types.SourceError import GHC.Types.SrcLoc +import GHC.Types.Unique.Map import GHC.Types.PkgQual import GHC.Unit @@ -129,6 +130,7 @@ import qualified Control.Monad.Catch as MC import Data.IORef import Data.Maybe import Data.Time +import Data.List (sortOn) import Data.Bifunctor (first) import System.Directory import System.FilePath @@ -529,7 +531,7 @@ warnUnusedPackages us dflags mod_graph = guard (Set.notMember (unitId ui) used_args) return (unitId ui, unitPackageName ui, unitPackageVersion ui, flag) - unusedArgs = mapMaybe resolve (explicitUnits us) + unusedArgs = sortOn (\(u,_,_,_) -> u) $ mapMaybe resolve (explicitUnits us) warn = singleMessage $ mkPlainMsgEnvelope diag_opts noSrcSpan (DriverUnusedPackages unusedArgs) @@ -1733,7 +1735,7 @@ checkHomeUnitsClosed ue home_id_set home_imp_ids loop (from_uid, uid) = let us = ue_findHomeUnitEnv from_uid ue in let um = unitInfoMap (homeUnitEnv_units us) in - case Map.lookup uid um of + case lookupUniqMap um uid of Nothing -> pprPanic "uid not found" (ppr uid) Just ui -> let depends = unitDepends ui ===================================== compiler/GHC/Hs/Doc.hs ===================================== @@ -224,8 +224,8 @@ instance NFData Docs where instance Binary Docs where put_ bh docs = do put_ bh (docs_mod_hdr docs) - put_ bh (sortBy (\a b -> (fst a) `stableNameCmp` fst b) $ nonDetEltsUniqMap $ docs_decls docs) - put_ bh (sortBy (\a b -> (fst a) `stableNameCmp` fst b) $ nonDetEltsUniqMap $ docs_args docs) + put_ bh (sortBy (\a b -> (fst a) `stableNameCmp` fst b) $ nonDetUniqMapToList $ docs_decls docs) + put_ bh (sortBy (\a b -> (fst a) `stableNameCmp` fst b) $ nonDetUniqMapToList $ docs_args docs) put_ bh (docs_structure docs) put_ bh (Map.toList $ docs_named_chunks docs) put_ bh (docs_haddock_opts docs) ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Types.Name.Set import GHC.Types.SrcLoc import GHC.Types.Unique.Set import GHC.Types.Fixity.Env +import GHC.Types.Unique.Map import GHC.Unit.External import GHC.Unit.Finder import GHC.Unit.State @@ -558,8 +559,8 @@ checkMergedSignatures hsc_env mod_summary iface = do let logger = hsc_logger hsc_env let unit_state = hsc_units hsc_env let old_merged = sort [ mod | UsageMergedRequirement{ usg_mod = mod } <- mi_usages iface ] - new_merged = case Map.lookup (ms_mod_name mod_summary) - (requirementContext unit_state) of + new_merged = case lookupUniqMap (requirementContext unit_state) + (ms_mod_name mod_summary) of Nothing -> [] Just r -> sort $ map (instModuleToModule unit_state) r if old_merged == new_merged ===================================== compiler/GHC/JS/Ppr.hs ===================================== @@ -196,9 +196,9 @@ defRenderJsV r = \case | isNullUniqMap m -> text "{}" | otherwise -> braceNest . hsep . punctuate comma . map (\(x,y) -> squotes (ftext x) <> colon <+> jsToDocR r y) - -- nonDetEltsUniqMap doesn't introduce non-determinism here + -- nonDetKeysUniqMap doesn't introduce non-determinism here -- because we sort the elements lexically - $ sortOn (LexicalFastString . fst) (nonDetEltsUniqMap m) + $ sortOn (LexicalFastString . fst) (nonDetUniqMapToList m) JFunc is b -> parens $ hangBrace (text "function" <> parens (hsep . punctuate comma . map (jsToDocR r) $ is)) (jsToDocR r b) defRenderJsI :: RenderJs -> Ident -> Doc ===================================== compiler/GHC/JS/Transform.hs ===================================== @@ -82,7 +82,7 @@ identsV = \case JInt{} -> [] JStr{} -> [] JRegEx{} -> [] - JHash m -> concatMap (identsE . snd) (nonDetEltsUniqMap m) + JHash m -> concatMap identsE (nonDetEltsUniqMap m) JFunc args s -> args ++ identsS s UnsatVal{} -> error "identsV: UnsatVal" @@ -183,7 +183,7 @@ jmcompos ret app f' v = JHash m -> ret JHash `app` m' -- nonDetEltsUniqMap doesn't introduce nondeterminism here because the -- elements are treated independently before being re-added to a UniqMap - where (ls, vs) = unzip (nonDetEltsUniqMap m) + where (ls, vs) = unzip (nonDetUniqMapToList m) m' = ret (listToUniqMap . zip ls) `app` mapM' f vs JFunc xs s -> ret JFunc `app` mapM' f xs `app` f s UnsatVal _ -> ret v' ===================================== compiler/GHC/StgToJS/Object.hs ===================================== @@ -436,7 +436,6 @@ instance Binary Sat.JStat where n -> error ("Binary get bh JStat: invalid tag: " ++ show n) - instance Binary Sat.JExpr where put_ bh (Sat.ValExpr v) = putByte bh 1 >> put_ bh v put_ bh (Sat.SelExpr e i) = putByte bh 2 >> put_ bh e >> put_ bh i @@ -463,7 +462,7 @@ instance Binary Sat.JVal where put_ bh (Sat.JInt i) = putByte bh 4 >> put_ bh i put_ bh (Sat.JStr xs) = putByte bh 5 >> put_ bh xs put_ bh (Sat.JRegEx xs) = putByte bh 6 >> put_ bh xs - put_ bh (Sat.JHash m) = putByte bh 7 >> put_ bh (sortOn (LexicalFastString . fst) $ nonDetEltsUniqMap m) + put_ bh (Sat.JHash m) = putByte bh 7 >> put_ bh (sortOn (LexicalFastString . fst) $ nonDetUniqMapToList m) put_ bh (Sat.JFunc is s) = putByte bh 8 >> put_ bh is >> put_ bh s get bh = getByte bh >>= \case 1 -> Sat.JVar <$> get bh ===================================== compiler/GHC/StgToJS/Printer.hs ===================================== @@ -104,7 +104,7 @@ ghcjsRenderJsV r (JHash m) map (\(x,y) -> quoteIfRequired x <> PP.colon <+> jsToDocR r y) -- nonDetEltsUniqMap doesn't introduce non-determinism here because -- we sort the elements lexically - . sortOn (LexicalFastString . fst) $ nonDetEltsUniqMap m + . sortOn (LexicalFastString . fst) $ nonDetUniqMapToList m where quoteIfRequired :: FastString -> Doc quoteIfRequired x ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1366,7 +1366,7 @@ zonkAndGroupSkolTvs hole_ty = do group_skolems :: UM.UniqMap SkolemInfo ([(TcTyVar, Int)]) group_skolems = bagToList <$> UM.listToUniqMap_C unionBags [(skolemSkolInfo tv, unitBag (tv, n)) | tv <- skol_tvs | n <- [0..]] - skolem_list = sortBy (comparing (sort . map snd . snd)) (UM.nonDetEltsUniqMap group_skolems) + skolem_list = sortBy (comparing (sort . map snd . snd)) (UM.nonDetUniqMapToList group_skolems) {- Note [Adding deferred bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -57,6 +57,7 @@ module GHC.Types.Unique.FM ( mergeUFM, plusMaybeUFM_C, plusUFMList, + plusUFMListWith, sequenceUFMList, minusUFM, minusUFM_C, @@ -331,6 +332,9 @@ plusMaybeUFM_C f (UFM xm) (UFM ym) plusUFMList :: [UniqFM key elt] -> UniqFM key elt plusUFMList = foldl' plusUFM emptyUFM +plusUFMListWith :: (elt -> elt -> elt) -> [UniqFM key elt] -> UniqFM key elt +plusUFMListWith f xs = unsafeIntMapToUFM $ M.unionsWith f (map ufmToIntMap xs) + sequenceUFMList :: forall key elt. [UniqFM key elt] -> UniqFM key [elt] sequenceUFMList = foldr (plusUFM_CD2 cons) emptyUFM where ===================================== compiler/GHC/Types/Unique/Map.hs ===================================== @@ -30,20 +30,25 @@ module GHC.Types.Unique.Map ( plusUniqMap_C, plusMaybeUniqMap_C, plusUniqMapList, + plusUniqMapListWith, minusUniqMap, intersectUniqMap, intersectUniqMap_C, disjointUniqMap, mapUniqMap, filterUniqMap, + filterWithKeyUniqMap, partitionUniqMap, sizeUniqMap, elemUniqMap, + nonDetKeysUniqMap, + nonDetEltsUniqMap, lookupUniqMap, lookupWithDefaultUniqMap, anyUniqMap, allUniqMap, - nonDetEltsUniqMap, + nonDetUniqMapToList, + nonDetUniqMapToKeySet, nonDetFoldUniqMap -- Non-deterministic functions omitted ) where @@ -61,6 +66,8 @@ import Data.Maybe import Data.Data import Control.DeepSeq +import Data.Set (Set, fromList) + -- | Maps indexed by 'Uniquable' keys newtype UniqMap k a = UniqMap { getUniqMap :: UniqFM k (k, a) } deriving (Data, Eq, Functor) @@ -192,6 +199,13 @@ plusMaybeUniqMap_C f (UniqMap m1) (UniqMap m2) = UniqMap $ plusUniqMapList :: [UniqMap k a] -> UniqMap k a plusUniqMapList xs = UniqMap $ plusUFMList (coerce xs) +plusUniqMapListWith :: (a -> a -> a) -> [UniqMap k a] -> UniqMap k a +plusUniqMapListWith f xs = UniqMap $ plusUFMListWith go (coerce xs) + where + -- l and r keys will be identical so we choose the former + go (l_key, l) (_r, r) = (l_key, f l r) +{-# INLINE plusUniqMapListWith #-} + minusUniqMap :: UniqMap k a -> UniqMap k b -> UniqMap k a minusUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ minusUFM m1 m2 @@ -201,6 +215,7 @@ intersectUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ intersectUFM m1 m2 -- | Intersection with a combining function. intersectUniqMap_C :: (a -> b -> c) -> UniqMap k a -> UniqMap k b -> UniqMap k c intersectUniqMap_C f (UniqMap m1) (UniqMap m2) = UniqMap $ intersectUFM_C (\(k, a) (_, b) -> (k, f a b)) m1 m2 +{-# INLINE intersectUniqMap #-} disjointUniqMap :: UniqMap k a -> UniqMap k b -> Bool disjointUniqMap (UniqMap m1) (UniqMap m2) = disjointUFM m1 m2 @@ -211,6 +226,9 @@ mapUniqMap f (UniqMap m) = UniqMap $ mapUFM (fmap f) m -- (,) k instance filterUniqMap :: (a -> Bool) -> UniqMap k a -> UniqMap k a filterUniqMap f (UniqMap m) = UniqMap $ filterUFM (f . snd) m +filterWithKeyUniqMap :: (k -> a -> Bool) -> UniqMap k a -> UniqMap k a +filterWithKeyUniqMap f (UniqMap m) = UniqMap $ filterUFM (uncurry f) m + partitionUniqMap :: (a -> Bool) -> UniqMap k a -> (UniqMap k a, UniqMap k a) partitionUniqMap f (UniqMap m) = coerce $ partitionUFM (f . snd) m @@ -233,8 +251,21 @@ anyUniqMap f (UniqMap m) = anyUFM (f . snd) m allUniqMap :: (a -> Bool) -> UniqMap k a -> Bool allUniqMap f (UniqMap m) = allUFM (f . snd) m -nonDetEltsUniqMap :: UniqMap k a -> [(k, a)] -nonDetEltsUniqMap (UniqMap m) = nonDetEltsUFM m +nonDetUniqMapToList :: UniqMap k a -> [(k, a)] +nonDetUniqMapToList (UniqMap m) = nonDetEltsUFM m +{-# INLINE nonDetUniqMapToList #-} + +nonDetUniqMapToKeySet :: Ord k => UniqMap k a -> Set k +nonDetUniqMapToKeySet m = fromList (nonDetKeysUniqMap m) + +nonDetKeysUniqMap :: UniqMap k a -> [k] +nonDetKeysUniqMap m = map fst (nonDetUniqMapToList m) +{-# INLINE nonDetKeysUniqMap #-} + +nonDetEltsUniqMap :: UniqMap k a -> [a] +nonDetEltsUniqMap m = map snd (nonDetUniqMapToList m) +{-# INLINE nonDetEltsUniqMap #-} nonDetFoldUniqMap :: ((k, a) -> b -> b) -> b -> UniqMap k a -> b nonDetFoldUniqMap go z (UniqMap m) = nonDetFoldUFM go z m +{-# INLINE nonDetFoldUniqMap #-} ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -91,6 +91,8 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.DFM import GHC.Types.Unique.Set import GHC.Types.Unique.DSet +import GHC.Types.Unique.Map +import GHC.Types.Unique import GHC.Types.PkgQual import GHC.Utils.Misc @@ -110,13 +112,10 @@ import System.FilePath as FilePath import Control.Monad import Data.Graph (stronglyConnComp, SCC(..)) import Data.Char ( toUpper ) -import Data.List ( intersperse, partition, sortBy, isSuffixOf ) -import Data.Map (Map) +import Data.List ( intersperse, partition, sortBy, isSuffixOf, sortOn ) import Data.Set (Set) import Data.Monoid (First(..)) import qualified Data.Semigroup as Semigroup -import qualified Data.Map as Map -import qualified Data.Map.Strict as MapStrict import qualified Data.Set as Set import GHC.LanguageExtensions import Control.Applicative @@ -260,7 +259,7 @@ originEmpty _ = False type PreloadUnitClosure = UniqSet UnitId -- | 'UniqFM' map from 'Unit' to a 'UnitVisibility'. -type VisibilityMap = Map Unit UnitVisibility +type VisibilityMap = UniqMap Unit UnitVisibility -- | 'UnitVisibility' records the various aspects of visibility of a particular -- 'Unit'. @@ -274,7 +273,7 @@ data UnitVisibility = UnitVisibility -- ^ The package name associated with the 'Unit'. This is used -- to implement legacy behavior where @-package foo-0.1@ implicitly -- hides any packages named @foo@ - , uv_requirements :: Map ModuleName (Set InstantiatedModule) + , uv_requirements :: UniqMap ModuleName (Set InstantiatedModule) -- ^ The signatures which are contributed to the requirements context -- from this unit ID. , uv_explicit :: Maybe PackageArg @@ -298,7 +297,7 @@ instance Semigroup UnitVisibility where { uv_expose_all = uv_expose_all uv1 || uv_expose_all uv2 , uv_renamings = uv_renamings uv1 ++ uv_renamings uv2 , uv_package_name = mappend (uv_package_name uv1) (uv_package_name uv2) - , uv_requirements = Map.unionWith Set.union (uv_requirements uv1) (uv_requirements uv2) + , uv_requirements = plusUniqMap_C Set.union (uv_requirements uv2) (uv_requirements uv1) , uv_explicit = uv_explicit uv1 <|> uv_explicit uv2 } @@ -307,7 +306,7 @@ instance Monoid UnitVisibility where { uv_expose_all = False , uv_renamings = [] , uv_package_name = First Nothing - , uv_requirements = Map.empty + , uv_requirements = emptyUniqMap , uv_explicit = Nothing } mappend = (Semigroup.<>) @@ -407,7 +406,7 @@ initUnitConfig dflags cached_dbs home_units = -- origin for a given 'Module' type ModuleNameProvidersMap = - Map ModuleName (Map Module ModuleOrigin) + UniqMap ModuleName (UniqMap Module ModuleOrigin) data UnitState = UnitState { -- | A mapping of 'Unit' to 'UnitInfo'. This list is adjusted @@ -431,10 +430,10 @@ data UnitState = UnitState { packageNameMap :: UniqFM PackageName UnitId, -- | A mapping from database unit keys to wired in unit ids. - wireMap :: Map UnitId UnitId, + wireMap :: UniqMap UnitId UnitId, -- | A mapping from wired in unit ids to unit keys from the database. - unwireMap :: Map UnitId UnitId, + unwireMap :: UniqMap UnitId UnitId, -- | The units we're going to link in eagerly. This list -- should be in reverse dependency order; that is, a unit @@ -464,7 +463,7 @@ data UnitState = UnitState { -- and @r[C=\]:C at . -- -- There's an entry in this map for each hole in our home library. - requirementContext :: Map ModuleName [InstantiatedModule], + requirementContext :: UniqMap ModuleName [InstantiatedModule], -- | Indicate if we can instantiate units on-the-fly. -- @@ -475,17 +474,17 @@ data UnitState = UnitState { emptyUnitState :: UnitState emptyUnitState = UnitState { - unitInfoMap = Map.empty, + unitInfoMap = emptyUniqMap, preloadClosure = emptyUniqSet, packageNameMap = emptyUFM, - wireMap = Map.empty, - unwireMap = Map.empty, - preloadUnits = [], - explicitUnits = [], + wireMap = emptyUniqMap, + unwireMap = emptyUniqMap, + preloadUnits = [], + explicitUnits = [], homeUnitDepends = [], - moduleNameProvidersMap = Map.empty, - pluginModuleNameProvidersMap = Map.empty, - requirementContext = Map.empty, + moduleNameProvidersMap = emptyUniqMap, + pluginModuleNameProvidersMap = emptyUniqMap, + requirementContext = emptyUniqMap, allowVirtualUnits = False } @@ -498,7 +497,7 @@ data UnitDatabase unit = UnitDatabase instance Outputable u => Outputable (UnitDatabase u) where ppr (UnitDatabase fp _u) = text "DB:" <+> text fp -type UnitInfoMap = Map UnitId UnitInfo +type UnitInfoMap = UniqMap UnitId UnitInfo -- | Find the unit we know about with the given unit, if any lookupUnit :: UnitState -> Unit -> Maybe UnitInfo @@ -514,20 +513,20 @@ lookupUnit pkgs = lookupUnit' (allowVirtualUnits pkgs) (unitInfoMap pkgs) (prelo lookupUnit' :: Bool -> UnitInfoMap -> PreloadUnitClosure -> Unit -> Maybe UnitInfo lookupUnit' allowOnTheFlyInst pkg_map closure u = case u of HoleUnit -> error "Hole unit" - RealUnit i -> Map.lookup (unDefinite i) pkg_map + RealUnit i -> lookupUniqMap pkg_map (unDefinite i) VirtUnit i | allowOnTheFlyInst -> -- lookup UnitInfo of the indefinite unit to be instantiated and -- instantiate it on-the-fly fmap (renameUnitInfo pkg_map closure (instUnitInsts i)) - (Map.lookup (instUnitInstanceOf i) pkg_map) + (lookupUniqMap pkg_map (instUnitInstanceOf i)) | otherwise -> -- lookup UnitInfo by virtual UnitId. This is used to find indefinite -- units. Even if they are real, installed units, they can't use the -- `RealUnit` constructor (it is reserved for definite units) so we use -- the `VirtUnit` constructor. - Map.lookup (virtualUnitId i) pkg_map + lookupUniqMap pkg_map (virtualUnitId i) -- | Find the unit we know about with the given unit id, if any lookupUnitId :: UnitState -> UnitId -> Maybe UnitInfo @@ -535,7 +534,7 @@ lookupUnitId state uid = lookupUnitId' (unitInfoMap state) uid -- | Find the unit we know about with the given unit id, if any lookupUnitId' :: UnitInfoMap -> UnitId -> Maybe UnitInfo -lookupUnitId' db uid = Map.lookup uid db +lookupUnitId' db uid = lookupUniqMap db uid -- | Looks up the given unit in the unit state, panicking if it is not found @@ -569,12 +568,12 @@ searchPackageId pkgstate pid = filter ((pid ==) . unitPackageId) resolvePackageImport :: UnitState -> ModuleName -> PackageName -> Maybe UnitId resolvePackageImport unit_st mn pn = do -- 1. Find all modules providing the ModuleName (this accounts for visibility/thinning etc) - providers <- Map.filter originVisible <$> Map.lookup mn (moduleNameProvidersMap unit_st) + providers <- filterUniqMap originVisible <$> lookupUniqMap (moduleNameProvidersMap unit_st) mn -- 2. Get the UnitIds of the candidates - let candidates_uid = concatMap to_uid $ Map.assocs providers + let candidates_uid = concatMap to_uid $ sortOn fst $ nonDetUniqMapToList providers -- 3. Get the package names of the candidates let candidates_units = map (\ui -> ((unitPackageName ui), unitId ui)) - $ mapMaybe (\uid -> Map.lookup uid (unitInfoMap unit_st)) candidates_uid + $ mapMaybe (\uid -> lookupUniqMap (unitInfoMap unit_st) uid) candidates_uid -- 4. Check to see if the PackageName helps us disambiguate any candidates. lookup pn candidates_units @@ -600,23 +599,22 @@ resolvePackageImport unit_st mn pn = do -- with module holes). -- mkUnitInfoMap :: [UnitInfo] -> UnitInfoMap -mkUnitInfoMap infos = foldl' add Map.empty infos +mkUnitInfoMap infos = foldl' add emptyUniqMap infos where mkVirt p = virtualUnitId (mkInstantiatedUnit (unitInstanceOf p) (unitInstantiations p)) add pkg_map p | not (null (unitInstantiations p)) - = Map.insert (mkVirt p) p - $ Map.insert (unitId p) p - $ pkg_map + = addToUniqMap (addToUniqMap pkg_map (mkVirt p) p) + (unitId p) p | otherwise - = Map.insert (unitId p) p pkg_map + = addToUniqMap pkg_map (unitId p) p -- | Get a list of entries from the unit database. NB: be careful with -- this function, although all units in this map are "visible", this -- does not imply that the exposed-modules of the unit are available -- (they may have been thinned or renamed). listUnitInfo :: UnitState -> [UnitInfo] -listUnitInfo state = Map.elems (unitInfoMap state) +listUnitInfo state = nonDetEltsUniqMap (unitInfoMap state) -- ---------------------------------------------------------------------------- -- Loading the unit db files and building up the unit state @@ -904,20 +902,20 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag = -- This method is responsible for computing what our -- inherited requirements are. reqs | UnitIdArg orig_uid <- arg = collectHoles orig_uid - | otherwise = Map.empty + | otherwise = emptyUniqMap collectHoles uid = case uid of - HoleUnit -> Map.empty - RealUnit {} -> Map.empty -- definite units don't have holes + HoleUnit -> emptyUniqMap + RealUnit {} -> emptyUniqMap -- definite units don't have holes VirtUnit indef -> - let local = [ Map.singleton + let local = [ unitUniqMap (moduleName mod) (Set.singleton $ Module indef mod_name) | (mod_name, mod) <- instUnitInsts indef , isHoleModule mod ] recurse = [ collectHoles (moduleUnit mod) | (_, mod) <- instUnitInsts indef ] - in Map.unionsWith Set.union $ local ++ recurse + in plusUniqMapListWith Set.union $ local ++ recurse uv = UnitVisibility { uv_expose_all = b @@ -926,7 +924,7 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag = , uv_requirements = reqs , uv_explicit = Just arg } - vm' = Map.insertWith mappend (mkUnit p) uv vm_cleared + vm' = addToUniqMap_C mappend vm_cleared (mkUnit p) uv -- In the old days, if you said `ghc -package p-0.1 -package p-0.2` -- (or if p-0.1 was registered in the pkgdb as exposed: True), -- the second package flag would override the first one and you @@ -950,7 +948,7 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag = vm_cleared | no_hide_others = vm -- NB: renamings never clear | (_:_) <- rns = vm - | otherwise = Map.filterWithKey + | otherwise = filterWithKeyUniqMap (\k uv -> k == mkUnit p || First (Just n) /= uv_package_name uv) vm _ -> panic "applyPackageFlag" @@ -958,7 +956,7 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag = HidePackage str -> case findPackages prec_map pkg_map closure (PackageArg str) pkgs unusable of Left ps -> Failed (PackageFlagErr flag ps) - Right ps -> Succeeded $ foldl' (flip Map.delete) vm (map mkUnit ps) + Right ps -> Succeeded $ foldl' delFromUniqMap vm (map mkUnit ps) -- | Like 'selectPackages', but doesn't return a list of unmatched -- packages. Furthermore, any packages it returns are *renamed* @@ -974,7 +972,7 @@ findPackages prec_map pkg_map closure arg pkgs unusable = let ps = mapMaybe (finder arg) pkgs in if null ps then Left (mapMaybe (\(x,y) -> finder arg x >>= \x' -> return (x',y)) - (Map.elems unusable)) + (nonDetEltsUniqMap unusable)) else Right (sortByPreference prec_map ps) where finder (PackageArg str) p @@ -999,7 +997,7 @@ selectPackages prec_map arg pkgs unusable = let matches = matching arg (ps,rest) = partition matches pkgs in if null ps - then Left (filter (matches.fst) (Map.elems unusable)) + then Left (filter (matches.fst) (nonDetEltsUniqMap unusable)) else Right (sortByPreference prec_map ps, rest) -- | Rename a 'UnitInfo' according to some module instantiation. @@ -1053,8 +1051,8 @@ compareByPreference compareByPreference prec_map pkg pkg' = case comparing unitPackageVersion pkg pkg' of GT -> GT - EQ | Just prec <- Map.lookup (unitId pkg) prec_map - , Just prec' <- Map.lookup (unitId pkg') prec_map + EQ | Just prec <- lookupUniqMap prec_map (unitId pkg) + , Just prec' <- lookupUniqMap prec_map (unitId pkg') -- Prefer the unit from the later DB flag (i.e., higher -- precedence) -> compare prec prec' @@ -1080,7 +1078,7 @@ pprTrustFlag flag = case flag of -- -- See Note [Wired-in units] in GHC.Unit.Types -type WiringMap = Map UnitId UnitId +type WiringMap = UniqMap UnitId UnitId findWiredInUnits :: Logger @@ -1120,7 +1118,7 @@ findWiredInUnits logger prec_map pkgs vis_map = do findWiredInUnit pkgs wired_pkg = firstJustsM [try all_exposed_ps, try all_ps, notfound] where all_ps = [ p | p <- pkgs, p `matches` wired_pkg ] - all_exposed_ps = [ p | p <- all_ps, Map.member (mkUnit p) vis_map ] + all_exposed_ps = [ p | p <- all_ps, (mkUnit p) `elemUniqMap` vis_map ] try ps = case sortByPreference prec_map ps of p:_ -> Just <$> pick p @@ -1146,8 +1144,8 @@ findWiredInUnits logger prec_map pkgs vis_map = do let wired_in_pkgs = catMaybes mb_wired_in_pkgs - wiredInMap :: Map UnitId UnitId - wiredInMap = Map.fromList + wiredInMap :: UniqMap UnitId UnitId + wiredInMap = listToUniqMap [ (unitId realUnitInfo, wiredInUnitId) | (wiredInUnitId, realUnitInfo) <- wired_in_pkgs , not (unitIsIndefinite realUnitInfo) @@ -1155,7 +1153,7 @@ findWiredInUnits logger prec_map pkgs vis_map = do updateWiredInDependencies pkgs = map (upd_deps . upd_pkg) pkgs where upd_pkg pkg - | Just wiredInUnitId <- Map.lookup (unitId pkg) wiredInMap + | Just wiredInUnitId <- lookupUniqMap wiredInMap (unitId pkg) = pkg { unitId = wiredInUnitId , unitInstanceOf = wiredInUnitId -- every non instantiated unit is an instance of @@ -1196,18 +1194,17 @@ upd_wired_in_uid wiredInMap u = case u of upd_wired_in :: WiringMap -> UnitId -> UnitId upd_wired_in wiredInMap key - | Just key' <- Map.lookup key wiredInMap = key' + | Just key' <- lookupUniqMap wiredInMap key = key' | otherwise = key updateVisibilityMap :: WiringMap -> VisibilityMap -> VisibilityMap -updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (Map.toList wiredInMap) - where f vm (from, to) = case Map.lookup (RealUnit (Definite from)) vis_map of +updateVisibilityMap wiredInMap vis_map = foldl' f vis_map (nonDetUniqMapToList wiredInMap) + where f vm (from, to) = case lookupUniqMap vis_map (RealUnit (Definite from)) of Nothing -> vm - Just r -> Map.insert (RealUnit (Definite to)) r - (Map.delete (RealUnit (Definite from)) vm) + Just r -> addToUniqMap (delFromUniqMap vm (RealUnit (Definite from))) + (RealUnit (Definite to)) r - --- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- -- | The reason why a unit is unusable. data UnusableUnitReason @@ -1234,7 +1231,7 @@ instance Outputable UnusableUnitReason where ppr (IgnoredDependencies uids) = brackets (text "ignored" <+> ppr uids) ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids) -type UnusableUnits = Map UnitId (UnitInfo, UnusableUnitReason) +type UnusableUnits = UniqMap UnitId (UnitInfo, UnusableUnitReason) pprReason :: SDoc -> UnusableUnitReason -> SDoc pprReason pref reason = case reason of @@ -1264,7 +1261,7 @@ reportCycles logger sccs = mapM_ report sccs nest 2 (hsep (map (ppr . unitId) vs)) reportUnusable :: Logger -> UnusableUnits -> IO () -reportUnusable logger pkgs = mapM_ report (Map.toList pkgs) +reportUnusable logger pkgs = mapM_ report (nonDetUniqMapToList pkgs) where report (ipid, (_, reason)) = debugTraceMsg logger 2 $ @@ -1278,14 +1275,15 @@ reportUnusable logger pkgs = mapM_ report (Map.toList pkgs) -- | A reverse dependency index, mapping an 'UnitId' to -- the 'UnitId's which have a dependency on it. -type RevIndex = Map UnitId [UnitId] +type RevIndex = UniqMap UnitId [UnitId] -- | Compute the reverse dependency index of a unit database. reverseDeps :: UnitInfoMap -> RevIndex -reverseDeps db = Map.foldl' go Map.empty db +reverseDeps db = nonDetFoldUniqMap go emptyUniqMap db where - go r pkg = foldl' (go' (unitId pkg)) r (unitDepends pkg) - go' from r to = Map.insertWith (++) to [from] r + go :: (UnitId, UnitInfo) -> RevIndex -> RevIndex + go (_uid, pkg) r = foldl' (go' (unitId pkg)) r (unitDepends pkg) + go' from r to = addToUniqMap_C (++) r to [from] -- | Given a list of 'UnitId's to remove, a database, -- and a reverse dependency index (as computed by 'reverseDeps'), @@ -1299,10 +1297,10 @@ removeUnits uids index m = go uids (m,[]) where go [] (m,pkgs) = (m,pkgs) go (uid:uids) (m,pkgs) - | Just pkg <- Map.lookup uid m - = case Map.lookup uid index of - Nothing -> go uids (Map.delete uid m, pkg:pkgs) - Just rdeps -> go (rdeps ++ uids) (Map.delete uid m, pkg:pkgs) + | Just pkg <- lookupUniqMap m uid + = case lookupUniqMap index uid of + Nothing -> go uids (delFromUniqMap m uid, pkg:pkgs) + Just rdeps -> go (rdeps ++ uids) (delFromUniqMap m uid, pkg:pkgs) | otherwise = go uids (m,pkgs) @@ -1311,7 +1309,7 @@ removeUnits uids index m = go uids (m,[]) depsNotAvailable :: UnitInfoMap -> UnitInfo -> [UnitId] -depsNotAvailable pkg_map pkg = filter (not . (`Map.member` pkg_map)) (unitDepends pkg) +depsNotAvailable pkg_map pkg = filter (not . (`elemUniqMap` pkg_map)) (unitDepends pkg) -- | Given a 'UnitInfo' from some 'UnitInfoMap' return all entries in -- 'unitAbiDepends' which correspond to units that do not exist, OR have @@ -1322,7 +1320,7 @@ depsAbiMismatch :: UnitInfoMap depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ unitAbiDepends pkg where abiMatch (dep_uid, abi) - | Just dep_pkg <- Map.lookup dep_uid pkg_map + | Just dep_pkg <- lookupUniqMap pkg_map dep_uid = unitAbiHash dep_pkg == abi | otherwise = False @@ -1331,7 +1329,7 @@ depsAbiMismatch pkg_map pkg = map fst . filter (not . abiMatch) $ unitAbiDepends -- Ignore units ignoreUnits :: [IgnorePackageFlag] -> [UnitInfo] -> UnusableUnits -ignoreUnits flags pkgs = Map.fromList (concatMap doit flags) +ignoreUnits flags pkgs = listToUniqMap (concatMap doit flags) where doit (IgnorePackage str) = case partition (matchingStr str) pkgs of @@ -1351,7 +1349,7 @@ ignoreUnits flags pkgs = Map.fromList (concatMap doit flags) -- the command line. We use this mapping to make sure we prefer -- units that were defined later on the command line, if there -- is an ambiguity. -type UnitPrecedenceMap = Map UnitId Int +type UnitPrecedenceMap = UniqMap UnitId Int -- | Given a list of databases, merge them together, where -- units with the same unit id in later databases override @@ -1359,7 +1357,7 @@ type UnitPrecedenceMap = Map UnitId Int -- makes sense (that's done by 'validateDatabase'). mergeDatabases :: Logger -> [UnitDatabase UnitId] -> IO (UnitInfoMap, UnitPrecedenceMap) -mergeDatabases logger = foldM merge (Map.empty, Map.empty) . zip [1..] +mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..] where merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do debugTraceMsg logger 2 $ @@ -1371,22 +1369,22 @@ mergeDatabases logger = foldM merge (Map.empty, Map.empty) . zip [1..] return (pkg_map', prec_map') where db_map = mk_pkg_map db - mk_pkg_map = Map.fromList . map (\p -> (unitId p, p)) + mk_pkg_map = listToUniqMap . map (\p -> (unitId p, p)) -- The set of UnitIds which appear in both db and pkgs. These are the -- ones that get overridden. Compute this just to give some -- helpful debug messages at -v2 override_set :: Set UnitId - override_set = Set.intersection (Map.keysSet db_map) - (Map.keysSet pkg_map) + override_set = Set.intersection (nonDetUniqMapToKeySet db_map) + (nonDetUniqMapToKeySet pkg_map) -- Now merge the sets together (NB: in case of duplicate, -- first argument preferred) pkg_map' :: UnitInfoMap - pkg_map' = Map.union db_map pkg_map + pkg_map' = pkg_map `plusUniqMap` db_map prec_map' :: UnitPrecedenceMap - prec_map' = Map.union (Map.map (const i) db_map) prec_map + prec_map' = prec_map `plusUniqMap` (mapUniqMap (const i) db_map) -- | Validates a database, removing unusable units from it -- (this includes removing units that the user has explicitly @@ -1409,39 +1407,45 @@ validateDatabase cfg pkg_map1 = -- Helper function mk_unusable mk_err dep_matcher m uids = - Map.fromList [ (unitId pkg, (pkg, mk_err (dep_matcher m pkg))) - | pkg <- uids ] + listToUniqMap [ (unitId pkg, (pkg, mk_err (dep_matcher m pkg))) + | pkg <- uids + ] -- Find broken units directly_broken = filter (not . null . depsNotAvailable pkg_map1) - (Map.elems pkg_map1) + (nonDetEltsUniqMap pkg_map1) (pkg_map2, broken) = removeUnits (map unitId directly_broken) index pkg_map1 unusable_broken = mk_unusable BrokenDependencies depsNotAvailable pkg_map2 broken -- Find recursive units sccs = stronglyConnComp [ (pkg, unitId pkg, unitDepends pkg) - | pkg <- Map.elems pkg_map2 ] + | pkg <- nonDetEltsUniqMap pkg_map2 ] getCyclicSCC (CyclicSCC vs) = map unitId vs getCyclicSCC (AcyclicSCC _) = [] (pkg_map3, cyclic) = removeUnits (concatMap getCyclicSCC sccs) index pkg_map2 unusable_cyclic = mk_unusable CyclicDependencies depsNotAvailable pkg_map3 cyclic -- Apply ignore flags - directly_ignored = ignoreUnits ignore_flags (Map.elems pkg_map3) - (pkg_map4, ignored) = removeUnits (Map.keys directly_ignored) index pkg_map3 + directly_ignored = ignoreUnits ignore_flags (nonDetEltsUniqMap pkg_map3) + (pkg_map4, ignored) = removeUnits (nonDetKeysUniqMap directly_ignored) index pkg_map3 unusable_ignored = mk_unusable IgnoredDependencies depsNotAvailable pkg_map4 ignored -- Knock out units whose dependencies don't agree with ABI -- (i.e., got invalidated due to shadowing) directly_shadowed = filter (not . null . depsAbiMismatch pkg_map4) - (Map.elems pkg_map4) + (nonDetEltsUniqMap pkg_map4) (pkg_map5, shadowed) = removeUnits (map unitId directly_shadowed) index pkg_map4 unusable_shadowed = mk_unusable ShadowedDependencies depsAbiMismatch pkg_map5 shadowed - unusable = directly_ignored `Map.union` unusable_ignored - `Map.union` unusable_broken - `Map.union` unusable_cyclic - `Map.union` unusable_shadowed + -- combine all unusables. The order is important for shadowing. + -- plusUniqMapList folds using plusUFM which is right biased (opposite of + -- Data.Map.union) so the head of the list should be the least preferred + unusable = plusUniqMapList [ unusable_shadowed + , unusable_cyclic + , unusable_broken + , unusable_ignored + , directly_ignored + ] -- ----------------------------------------------------------------------------- -- When all the command-line options are in, we can process our unit @@ -1540,7 +1544,7 @@ mkUnitState logger cfg = do -- or not packages are visible or not) pkgs1 <- mayThrowUnitErr $ foldM (applyTrustFlag prec_map unusable) - (Map.elems pkg_map2) (reverse (unitConfigFlagsTrusted cfg)) + (nonDetEltsUniqMap pkg_map2) (reverse (unitConfigFlagsTrusted cfg)) let prelim_pkg_db = mkUnitInfoMap pkgs1 -- @@ -1580,17 +1584,16 @@ mkUnitState logger cfg = do -- default, because it's almost assuredly not -- what you want (no mix-in linking has occurred). if unitIsExposed p && unitIsDefinite (mkUnit p) && mostPreferable p - then Map.insert (mkUnit p) + then addToUniqMap vm (mkUnit p) UnitVisibility { uv_expose_all = True, uv_renamings = [], uv_package_name = First (Just (fsPackageName p)), - uv_requirements = Map.empty, + uv_requirements = emptyUniqMap, uv_explicit = Nothing } - vm else vm) - Map.empty pkgs1 + emptyUniqMap pkgs1 -- -- Compute a visibility map according to the command-line flags (-package, @@ -1618,9 +1621,9 @@ mkUnitState logger cfg = do case unitConfigFlagsPlugins cfg of -- common case; try to share the old vis_map [] | not hide_plugin_pkgs -> return vis_map - | otherwise -> return Map.empty + | otherwise -> return emptyUniqMap _ -> do let plugin_vis_map1 - | hide_plugin_pkgs = Map.empty + | hide_plugin_pkgs = emptyUniqMap -- Use the vis_map PRIOR to wired in, -- because otherwise applyPackageFlag -- won't work. @@ -1649,9 +1652,9 @@ mkUnitState logger cfg = do -- The requirement context is directly based off of this: we simply -- look for nested unit IDs that are directly fed holes: the requirements -- of those units are precisely the ones we need to track - let explicit_pkgs = [(k, uv_explicit v) | (k, v) <- Map.toList vis_map] - req_ctx = Map.map (Set.toList) - $ Map.unionsWith Set.union (map uv_requirements (Map.elems vis_map)) + let explicit_pkgs = [(k, uv_explicit v) | (k, v) <- nonDetUniqMapToList vis_map] + req_ctx = mapUniqMap (Set.toList) + $ plusUniqMapListWith Set.union (map uv_requirements (nonDetEltsUniqMap vis_map)) -- @@ -1664,11 +1667,11 @@ mkUnitState logger cfg = do -- NB: preload IS important even for type-checking, because we -- need the correct include path to be set. -- - let preload1 = Map.keys (Map.filter (isJust . uv_explicit) vis_map) + let preload1 = nonDetKeysUniqMap (filterUniqMap (isJust . uv_explicit) vis_map) -- add default preload units if they can be found in the db basicLinkedUnits = fmap (RealUnit . Definite) - $ filter (flip Map.member pkg_db) + $ filter (flip elemUniqMap pkg_db) $ unitConfigAutoLink cfg preload3 = ordNub $ (basicLinkedUnits ++ preload1) @@ -1679,7 +1682,7 @@ mkUnitState logger cfg = do let mod_map1 = mkModuleNameProvidersMap logger cfg pkg_db emptyUniqSet vis_map mod_map2 = mkUnusableModuleNameProvidersMap unusable - mod_map = Map.union mod_map1 mod_map2 + mod_map = mod_map2 `plusUniqMap` mod_map1 -- Force the result to avoid leaking input parameters let !state = UnitState @@ -1692,7 +1695,7 @@ mkUnitState logger cfg = do , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger cfg pkg_db emptyUniqSet plugin_vis_map , packageNameMap = pkgname_map , wireMap = wired_map - , unwireMap = Map.fromList [ (v,k) | (k,v) <- Map.toList wired_map ] + , unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ] , requirementContext = req_ctx , allowVirtualUnits = unitConfigAllowVirtual cfg } @@ -1715,7 +1718,7 @@ selectHomeUnits home_units flags = foldl' go Set.empty flags -- that it was recorded as in the package database. unwireUnit :: UnitState -> Unit -> Unit unwireUnit state uid@(RealUnit (Definite def_uid)) = - maybe uid (RealUnit . Definite) (Map.lookup def_uid (unwireMap state)) + maybe uid (RealUnit . Definite) (lookupUniqMap (unwireMap state) def_uid) unwireUnit _ uid = uid -- ----------------------------------------------------------------------------- @@ -1750,36 +1753,35 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map = -- entries for every definite (for non-Backpack) and -- indefinite (for Backpack) package, so that we get the -- hidden entries we need. - Map.foldlWithKey extend_modmap emptyMap vis_map_extended + nonDetFoldUniqMap extend_modmap emptyMap vis_map_extended where - vis_map_extended = Map.union vis_map {- preferred -} default_vis + vis_map_extended = {- preferred -} default_vis `plusUniqMap` vis_map - default_vis = Map.fromList + default_vis = listToUniqMap [ (mkUnit pkg, mempty) - | pkg <- Map.elems pkg_map + | (_, pkg) <- nonDetUniqMapToList pkg_map -- Exclude specific instantiations of an indefinite -- package , unitIsIndefinite pkg || null (unitInstantiations pkg) ] - emptyMap = Map.empty + emptyMap = emptyUniqMap setOrigins m os = fmap (const os) m - extend_modmap modmap uid - UnitVisibility { uv_expose_all = b, uv_renamings = rns } + extend_modmap (uid, UnitVisibility { uv_expose_all = b, uv_renamings = rns }) modmap = addListTo modmap theBindings where pkg = unit_lookup uid - theBindings :: [(ModuleName, Map Module ModuleOrigin)] + theBindings :: [(ModuleName, UniqMap Module ModuleOrigin)] theBindings = newBindings b rns newBindings :: Bool -> [(ModuleName, ModuleName)] - -> [(ModuleName, Map Module ModuleOrigin)] + -> [(ModuleName, UniqMap Module ModuleOrigin)] newBindings e rns = es e ++ hiddens ++ map rnBinding rns rnBinding :: (ModuleName, ModuleName) - -> (ModuleName, Map Module ModuleOrigin) + -> (ModuleName, UniqMap Module ModuleOrigin) rnBinding (orig, new) = (new, setOrigins origEntry fromFlag) where origEntry = case lookupUFM esmap orig of Just r -> r @@ -1788,7 +1790,7 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map = (text "package flag: could not find module name" <+> ppr orig <+> text "in package" <+> ppr pk))) - es :: Bool -> [(ModuleName, Map Module ModuleOrigin)] + es :: Bool -> [(ModuleName, UniqMap Module ModuleOrigin)] es e = do (m, exposedReexport) <- exposed_mods let (pk', m', origin') = @@ -1798,7 +1800,7 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map = (pk', m', fromReexportedModules e pkg) return (m, mkModMap pk' m' origin') - esmap :: UniqFM ModuleName (Map Module ModuleOrigin) + esmap :: UniqFM ModuleName (UniqMap Module ModuleOrigin) esmap = listToUFM (es False) -- parameter here doesn't matter, orig will -- be overwritten @@ -1814,10 +1816,10 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map = -- | Make a 'ModuleNameProvidersMap' covering a set of unusable packages. mkUnusableModuleNameProvidersMap :: UnusableUnits -> ModuleNameProvidersMap mkUnusableModuleNameProvidersMap unusables = - Map.foldl' extend_modmap Map.empty unusables + nonDetFoldUniqMap extend_modmap emptyUniqMap unusables where - extend_modmap modmap (pkg, reason) = addListTo modmap bindings - where bindings :: [(ModuleName, Map Module ModuleOrigin)] + extend_modmap (_uid, (pkg, reason)) modmap = addListTo modmap bindings + where bindings :: [(ModuleName, UniqMap Module ModuleOrigin)] bindings = exposed ++ hidden origin = ModUnusable reason @@ -1826,7 +1828,7 @@ mkUnusableModuleNameProvidersMap unusables = exposed = map get_exposed exposed_mods hidden = [(m, mkModMap pkg_id m origin) | m <- hidden_mods] - get_exposed (mod, Just mod') = (mod, Map.singleton mod' origin) + get_exposed (mod, Just mod') = (mod, unitUniqMap mod' origin) get_exposed (mod, _) = (mod, mkModMap pkg_id mod origin) exposed_mods = unitExposedModules pkg @@ -1837,16 +1839,16 @@ mkUnusableModuleNameProvidersMap unusables = -- The outer map is processed with 'Data.Map.Strict' to prevent memory leaks -- when reloading modules in GHCi (see #4029). This ensures that each -- value is forced before installing into the map. -addListTo :: (Monoid a, Ord k1, Ord k2) - => Map k1 (Map k2 a) - -> [(k1, Map k2 a)] - -> Map k1 (Map k2 a) +addListTo :: (Monoid a, Ord k1, Ord k2, Uniquable k1, Uniquable k2) + => UniqMap k1 (UniqMap k2 a) + -> [(k1, UniqMap k2 a)] + -> UniqMap k1 (UniqMap k2 a) addListTo = foldl' merge - where merge m (k, v) = MapStrict.insertWith (Map.unionWith mappend) k v m + where merge m (k, v) = addToUniqMap_C (plusUniqMap_C mappend) m k v -- | Create a singleton module mapping -mkModMap :: Unit -> ModuleName -> ModuleOrigin -> Map Module ModuleOrigin -mkModMap pkg mod = Map.singleton (mkModule pkg mod) +mkModMap :: Unit -> ModuleName -> ModuleOrigin -> UniqMap Module ModuleOrigin +mkModMap pkg mod = unitUniqMap (mkModule pkg mod) -- ----------------------------------------------------------------------------- @@ -1924,10 +1926,10 @@ lookupModuleWithSuggestions' :: UnitState -> PkgQual -> LookupResult lookupModuleWithSuggestions' pkgs mod_map m mb_pn - = case Map.lookup m mod_map of + = case lookupUniqMap mod_map m of Nothing -> LookupNotFound suggestions Just xs -> - case foldl' classify ([],[],[], []) (Map.toList xs) of + case foldl' classify ([],[],[], []) (sortOn fst $ nonDetUniqMapToList xs) of ([], [], [], []) -> LookupNotFound suggestions (_, _, _, [(m, o)]) -> LookupFound m (mod_unit m, o) (_, _, _, exposed@(_:_)) -> LookupMultiple exposed @@ -1985,8 +1987,8 @@ lookupModuleWithSuggestions' pkgs mod_map m mb_pn all_mods :: [(String, ModuleSuggestion)] -- All modules all_mods = sortBy (comparing fst) $ [ (moduleNameString m, suggestion) - | (m, e) <- Map.toList (moduleNameProvidersMap pkgs) - , suggestion <- map (getSuggestion m) (Map.toList e) + | (m, e) <- nonDetUniqMapToList (moduleNameProvidersMap pkgs) + , suggestion <- map (getSuggestion m) (nonDetUniqMapToList e) ] getSuggestion name (mod, origin) = (if originVisible origin then SuggestVisible else SuggestHidden) @@ -1994,8 +1996,8 @@ lookupModuleWithSuggestions' pkgs mod_map m mb_pn listVisibleModuleNames :: UnitState -> [ModuleName] listVisibleModuleNames state = - map fst (filter visible (Map.toList (moduleNameProvidersMap state))) - where visible (_, ms) = any originVisible (Map.elems ms) + map fst (filter visible (nonDetUniqMapToList (moduleNameProvidersMap state))) + where visible (_, ms) = anyUniqMap originVisible ms -- | Takes a list of UnitIds (and their "parent" dependency, used for error -- messages), and returns the list with dependencies included, in reverse @@ -2006,7 +2008,7 @@ closeUnitDeps pkg_map ps = closeUnitDeps' pkg_map [] ps -- | Similar to closeUnitDeps but takes a list of already loaded units as an -- additional argument. closeUnitDeps' :: UnitInfoMap -> [UnitId] -> [(UnitId,Maybe UnitId)] -> MaybeErr UnitErr [UnitId] -closeUnitDeps' pkg_map current_ids ps = foldM (add_unit pkg_map) current_ids ps +closeUnitDeps' pkg_map current_ids ps = foldM (uncurry . add_unit pkg_map) current_ids ps -- | Add a UnitId and those it depends on (recursively) to the given list of -- UnitIds if they are not already in it. Return a list in reverse dependency @@ -2017,9 +2019,10 @@ closeUnitDeps' pkg_map current_ids ps = foldM (add_unit pkg_map) current_ids ps -- error message ("dependency of "). add_unit :: UnitInfoMap -> [UnitId] - -> (UnitId,Maybe UnitId) + -> UnitId + -> Maybe UnitId -> MaybeErr UnitErr [UnitId] -add_unit pkg_map ps (p, mb_parent) +add_unit pkg_map ps p mb_parent | p `elem` ps = return ps -- Check if we've already added this unit | otherwise = case lookupUnitId' pkg_map p of Nothing -> Failed (CloseUnitErr p mb_parent) @@ -2028,8 +2031,8 @@ add_unit pkg_map ps (p, mb_parent) ps' <- foldM add_unit_key ps (unitDepends info) return (p : ps') where - add_unit_key ps key - = add_unit pkg_map ps (key, Just p) + add_unit_key xs key + = add_unit pkg_map xs key (Just p) data UnitErr = CloseUnitErr !UnitId !(Maybe UnitId) @@ -2073,7 +2076,7 @@ instance Outputable UnitErr where -- to form @mod_name@, or @[]@ if this is not a requirement. requirementMerges :: UnitState -> ModuleName -> [InstantiatedModule] requirementMerges pkgstate mod_name = - fromMaybe [] (Map.lookup mod_name (requirementContext pkgstate)) + fromMaybe [] (lookupUniqMap (requirementContext pkgstate) mod_name) -- ----------------------------------------------------------------------------- @@ -2128,9 +2131,9 @@ pprUnitsSimple = pprUnitsWith pprIPI -- | Show the mapping of modules to where they come from. pprModuleMap :: ModuleNameProvidersMap -> SDoc pprModuleMap mod_map = - vcat (map pprLine (Map.toList mod_map)) + vcat (map pprLine (nonDetUniqMapToList mod_map)) where - pprLine (m,e) = ppr m $$ nest 50 (vcat (map (pprEntry m) (Map.toList e))) + pprLine (m,e) = ppr m $$ nest 50 (vcat (map (pprEntry m) (nonDetUniqMapToList e))) pprEntry :: Outputable a => ModuleName -> (Module, a) -> SDoc pprEntry m (m',o) | m == moduleName m' = ppr (moduleUnit m') <+> parens (ppr o) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit d19850b8046876e92dfef045d8a5558b951f1650 +Subproject commit 03ba53ca764f56a13d12607c110f923f129e809a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b5be05ac29e2ec033e108e15f052f2a13898f24 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b5be05ac29e2ec033e108e15f052f2a13898f24 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 13:43:28 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 09:43:28 -0400 Subject: [Git][ghc/ghc][master] Add structured error messages for GHC.Tc.TyCl Message-ID: <6428350070613_3483da54342c78999135@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30 changed files: - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - testsuite/tests/driver/T11381.hs - testsuite/tests/driver/T11381.stderr - testsuite/tests/gadt/T14719.stderr - testsuite/tests/gadt/gadt11.stderr - testsuite/tests/gadt/gadtSyntaxFail001.stderr - testsuite/tests/gadt/gadtSyntaxFail002.stderr - testsuite/tests/gadt/gadtSyntaxFail003.stderr - testsuite/tests/ghci/prog006/prog006.stderr - testsuite/tests/ghci/scripts/T9293.stderr - testsuite/tests/ghci/scripts/ghci057.stderr - testsuite/tests/ghci/should_run/T7253.stderr - testsuite/tests/indexed-types/should_fail/BadFamInstDecl.stderr - testsuite/tests/indexed-types/should_fail/ClosedFam4.stderr - testsuite/tests/indexed-types/should_fail/Overlap4.stderr - testsuite/tests/indexed-types/should_fail/Overlap5.stderr - testsuite/tests/indexed-types/should_fail/SimpleFail3a.stderr - testsuite/tests/indexed-types/should_fail/T11136.stderr - testsuite/tests/indexed-types/should_fail/T12867.stderr - testsuite/tests/indexed-types/should_fail/T13571.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a84fba6eb5cae43bd79cc1b26eadd7a2aa36099b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a84fba6eb5cae43bd79cc1b26eadd7a2aa36099b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 14:28:31 2023 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Sat, 01 Apr 2023 10:28:31 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23203 Message-ID: <64283f8f53e23_3483da551578cc10066ab@gitlab.mail> Ryan Scott pushed new branch wip/T23203 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23203 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 19:47:51 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 15:47:51 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: driver: Unit State Data.Map -> GHC.Unique.UniqMap Message-ID: <64288a67c48a4_3483da5aa1e8e81057921@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - d92c3c89 by doyougnu at 2023-04-01T15:47:41-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 7b7565a4 by sheaf at 2023-04-01T15:47:46-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 5a912095 by sheaf at 2023-04-01T15:47:46-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/JS/Ppr.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Printer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Map.hs - compiler/GHC/Unit/State.hs - docs/users_guide/9.8.1-notes.rst - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d98ba7d11078368d1d37f505bca67fff2a7832f...5a91209581442d7f36121b72a5ca622d6035c950 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d98ba7d11078368d1d37f505bca67fff2a7832f...5a91209581442d7f36121b72a5ca622d6035c950 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 22:28:13 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 18:28:13 -0400 Subject: [Git][ghc/ghc][master] JS: Linker: use saturated JExpr Message-ID: <6428affd3a055_3483da5d6bf84810844ed@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 2 changed files: - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Linker/Linker.hs Changes: ===================================== compiler/GHC/JS/Transform.hs ===================================== @@ -23,7 +23,6 @@ module GHC.JS.Transform , composOpFold , satJExpr , satJStat - , unsatJStat ) where @@ -321,98 +320,3 @@ satJVal = go go (JHash m) = Sat.JHash (satJExpr <$> m) go (JFunc args body) = Sat.JFunc args (satJStat body) go UnsatVal{} = error "jvalToSatVar: discovered an Sat...impossibly" - -unsatJStat :: Sat.JStat -> JStat -unsatJStat = go_back - where - -- This is an Applicative but we can't use it because no type variables :( - go_back :: Sat.JStat -> JStat - go_back (Sat.DeclStat i rhs) = DeclStat i (fmap unsatJExpr rhs) - go_back (Sat.ReturnStat e) = ReturnStat (unsatJExpr e) - go_back (Sat.IfStat c t e) = IfStat (unsatJExpr c) (go_back t) (go_back e) - go_back (Sat.WhileStat is_do c e) = WhileStat is_do (unsatJExpr c) (go_back e) - go_back (Sat.ForInStat is_each i iter body) = ForInStat is_each i - (unsatJExpr iter) - (go_back body) - go_back (Sat.SwitchStat struct ps def) = SwitchStat - (unsatJExpr struct) - (map (unsatJExpr *** go_back) ps) - (go_back def) - go_back (Sat.TryStat t i c f) = TryStat (go_back t) i (go_back c) (go_back f) - go_back (Sat.BlockStat bs) = BlockStat $! fmap go_back bs - go_back (Sat.ApplStat rator rand) = ApplStat (unsatJExpr rator) (unsatJExpr <$> rand) - go_back (Sat.UOpStat rator rand) = UOpStat (unsatJUOp rator) (unsatJExpr rand) - go_back (Sat.AssignStat lhs rhs) = AssignStat (unsatJExpr lhs) (unsatJExpr rhs) - go_back (Sat.LabelStat lbl stmt) = LabelStat lbl (go_back stmt) - go_back (Sat.BreakStat Nothing) = BreakStat Nothing - go_back (Sat.BreakStat (Just l)) = BreakStat $! Just l - go_back (Sat.ContinueStat Nothing) = ContinueStat Nothing - go_back (Sat.ContinueStat (Just l)) = ContinueStat $! Just l - - -unsatJExpr :: Sat.JExpr -> JExpr -unsatJExpr = go - where - go (Sat.ValExpr v) = ValExpr (unsatJVal v) - go (Sat.SelExpr obj i) = SelExpr (unsatJExpr obj) i - go (Sat.IdxExpr o i) = IdxExpr (unsatJExpr o) (unsatJExpr i) - go (Sat.InfixExpr op l r) = InfixExpr (satOpToJOp op) (unsatJExpr l) (unsatJExpr r) - go (Sat.UOpExpr op r) = UOpExpr (unsatJUOp op) (unsatJExpr r) - go (Sat.IfExpr c t e) = IfExpr (unsatJExpr c) (unsatJExpr t) (unsatJExpr e) - go (Sat.ApplExpr rator rands) = ApplExpr (unsatJExpr rator) (unsatJExpr <$> rands) - -satOpToJOp :: Sat.Op -> JOp -satOpToJOp = go - where - go Sat.EqOp = EqOp - go Sat.StrictEqOp = StrictEqOp - go Sat.NeqOp = NeqOp - go Sat.StrictNeqOp = StrictNeqOp - go Sat.GtOp = GtOp - go Sat.GeOp = GeOp - go Sat.LtOp = LtOp - go Sat.LeOp = LeOp - go Sat.AddOp = AddOp - go Sat.SubOp = SubOp - go Sat.MulOp = MulOp - go Sat.DivOp = DivOp - go Sat.ModOp = ModOp - go Sat.LeftShiftOp = LeftShiftOp - go Sat.RightShiftOp = RightShiftOp - go Sat.ZRightShiftOp = ZRightShiftOp - go Sat.BAndOp = BAndOp - go Sat.BOrOp = BOrOp - go Sat.BXorOp = BXorOp - go Sat.LAndOp = LAndOp - go Sat.LOrOp = LOrOp - go Sat.InstanceofOp = InstanceofOp - go Sat.InOp = InOp - -unsatJUOp :: Sat.UOp -> JUOp -unsatJUOp = go - where - go Sat.NotOp = NotOp - go Sat.BNotOp = BNotOp - go Sat.NegOp = NegOp - go Sat.PlusOp = PlusOp - go Sat.NewOp = NewOp - go Sat.TypeofOp = TypeofOp - go Sat.DeleteOp = DeleteOp - go Sat.YieldOp = YieldOp - go Sat.VoidOp = VoidOp - go Sat.PreIncOp = PreIncOp - go Sat.PostIncOp = PostIncOp - go Sat.PreDecOp = PreDecOp - go Sat.PostDecOp = PostDecOp - -unsatJVal :: Sat.JVal -> JVal -unsatJVal = go - where - go (Sat.JVar i) = JVar i - go (Sat.JList xs) = JList (unsatJExpr <$> xs) - go (Sat.JDouble d) = JDouble (SaneDouble (Sat.unSaneDouble d)) - go (Sat.JInt i) = JInt i - go (Sat.JStr f) = JStr f - go (Sat.JRegEx f) = JRegEx f - go (Sat.JHash m) = JHash (unsatJExpr <$> m) - go (Sat.JFunc args body) = JFunc args (unsatJStat body) ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -31,6 +31,7 @@ import GHC.Platform.Host (hostPlatformArchOS) import GHC.JS.Make import GHC.JS.Unsat.Syntax +import qualified GHC.JS.Syntax as Sat import GHC.JS.Transform import GHC.Driver.Session (DynFlags(..)) @@ -280,7 +281,7 @@ computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDep -- | Compiled module data ModuleCode = ModuleCode { mc_module :: !Module - , mc_js_code :: !JStat + , mc_js_code :: !Sat.JStat , mc_exports :: !B.ByteString -- ^ rendered exports , mc_closures :: ![ClosureInfo] , mc_statics :: ![StaticInfo] @@ -293,7 +294,7 @@ data ModuleCode = ModuleCode -- up into global "metadata" for the whole link. data CompactedModuleCode = CompactedModuleCode { cmc_module :: !Module - , cmc_js_code :: !JStat + , cmc_js_code :: !Sat.JStat , cmc_exports :: !B.ByteString -- ^ rendered exports } @@ -326,7 +327,7 @@ renderLinker h mods jsFiles = do -- modules themselves mod_sizes <- forM compacted_mods $ \m -> do - !mod_size <- fromIntegral <$> putJS (satJStat $! cmc_js_code m) + !mod_size <- fromIntegral <$> putJS (cmc_js_code m) let !mod_mod = cmc_module m pure (mod_mod, mod_size) @@ -565,7 +566,7 @@ extractDeps ar_state units deps loc = mod = depsModule deps newline = BC.pack "\n" mk_exports = mconcat . intersperse newline . filter (not . BS.null) . map oiRaw - mk_js_code = mconcat . map (unsatJStat . oiStat) + mk_js_code = mconcat . map oiStat collectCode l = ModuleCode { mc_module = mod , mc_js_code = mk_js_code l View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e2eb275a1b6d3d1dae9c2864f001bea69d20c2a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e2eb275a1b6d3d1dae9c2864f001bea69d20c2a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 22:29:06 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 01 Apr 2023 18:29:06 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Improve haddocks of template-haskell Con datatype Message-ID: <6428b032e9532_3483da5d75769810919f5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - 15 changed files: - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.8.1-notes.rst - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - testsuite/tests/th/T10828.hs - testsuite/tests/th/T10828b.hs - testsuite/tests/th/T10828b.stderr - testsuite/tests/th/T11345.hs Changes: ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -95,7 +95,7 @@ import Language.Haskell.Syntax.Basic (FieldLabelString(..)) import Data.ByteString ( unpack ) import Control.Monad import Data.List (sort, sortBy) -import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.List.NonEmpty ( NonEmpty(..), toList ) import Data.Function import Control.Monad.Trans.Reader import Control.Monad.Trans.Class @@ -2742,19 +2742,16 @@ repGadtDataCons :: NonEmpty (LocatedN Name) -> LHsType GhcRn -> MetaM (Core (M TH.Con)) repGadtDataCons cons details res_ty - = do ne_tycon <- lift $ dsLookupTyCon nonEmptyTyConName - name_tycon <- lift $ dsLookupTyCon nameTyConName - let mk_nonEmpty = coreListNonEmpty ne_tycon (mkTyConTy name_tycon) - cons' <- mapM lookupLOcc cons -- See Note [Binders and occurrences] + = do cons' <- mapM lookupLOcc cons -- See Note [Binders and occurrences] case details of PrefixConGADT ps -> do arg_tys <- repPrefixConArgs ps res_ty' <- repLTy res_ty - rep2 gadtCName [unC (mk_nonEmpty cons'), unC arg_tys, unC res_ty'] + rep2 gadtCName [ unC (nonEmptyCoreList' cons'), unC arg_tys, unC res_ty'] RecConGADT ips _ -> do arg_vtys <- repRecConArgs ips res_ty' <- repLTy res_ty - rep2 recGadtCName [unC (mk_nonEmpty cons'), unC arg_vtys, + rep2 recGadtCName [unC (nonEmptyCoreList' cons'), unC arg_vtys, unC res_ty'] -- TH currently only supports linear constructors. @@ -3060,6 +3057,9 @@ nonEmptyCoreList :: [Core a] -> Core [a] nonEmptyCoreList [] = panic "coreList: empty argument" nonEmptyCoreList xs@(MkC x:_) = MkC (mkListExpr (exprType x) (map unC xs)) +nonEmptyCoreList' :: NonEmpty (Core a) -> Core [a] +nonEmptyCoreList' xs@(MkC x:|_) = MkC (mkListExpr (exprType x) (toList $ fmap unC xs)) + coreStringLit :: MonadThings m => FastString -> m (Core String) coreStringLit s = do { z <- mkStringExprFS s; return (MkC z) } ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -4831,6 +4831,10 @@ pprConversionFailReason = \case text "Implicit parameters mixed with other bindings" InvalidCCallImpent from -> text (show from) <+> text "is not a valid ccall impent" + RecGadtNoCons -> + quotes (text "RecGadtC") <+> text "must have at least one constructor name" + GadtNoCons -> + quotes (text "GadtC") <+> text "must have at least one constructor name" InvalidTypeInstanceHeader tys -> text "Invalid type instance header:" <+> text (show tys) ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -3683,6 +3683,8 @@ data ConversionFailReason | CasesExprWithoutAlts | ImplicitParamsWithOtherBinds | InvalidCCallImpent !String -- ^ Source + | RecGadtNoCons + | GadtNoCons | InvalidTypeInstanceHeader !TH.Type | InvalidTyFamInstLHS !TH.Type | InvalidImplicitParamBinding ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -143,7 +143,6 @@ import Unsafe.Coerce ( unsafeCoerce ) import Control.Monad import Data.Binary import Data.Binary.Get -import qualified Data.List.NonEmpty as NE ( singleton ) import Data.Maybe import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as LB @@ -2235,7 +2234,7 @@ reifyDataCon isGadtDataCon tys dc dcdBangs r_arg_tys) | not (null fields) -> do { res_ty <- reifyType g_res_ty - ; return $ TH.RecGadtC (NE.singleton name) + ; return $ TH.RecGadtC [name] (zip3 (map reifyFieldLabel fields) dcdBangs r_arg_tys) res_ty } -- We need to check not isGadtDataCon here because GADT @@ -2248,7 +2247,7 @@ reifyDataCon isGadtDataCon tys dc ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } | isGadtDataCon -> do { res_ty <- reifyType g_res_ty - ; return $ TH.GadtC (NE.singleton name) + ; return $ TH.GadtC [name] (dcdBangs `zip` r_arg_tys) res_ty } | otherwise -> return $ TH.NormalC name (dcdBangs `zip` r_arg_tys) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -276,7 +276,11 @@ cvtDec (DataD ctxt tc tvs ksig constrs derivs) cvtDec (NewtypeD ctxt tc tvs ksig constr derivs) = do { (ctxt', tc', tvs') <- cvt_tycl_hdr ctxt tc tvs ; ksig' <- cvtKind `traverse` ksig - ; con' <- cvtConstr (NE.head $ get_cons_names constr) cNameN constr + ; let first_datacon = + case get_cons_names constr of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c + ; con' <- cvtConstr first_datacon cNameN constr ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_cType = Nothing @@ -348,8 +352,10 @@ cvtDec (DataFamilyD tc tvs kind) cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) = do { (ctxt', tc', bndrs', typats') <- cvt_datainst_hdr ctxt bndrs tys ; ksig' <- cvtKind `traverse` ksig - - ; let first_datacon = NE.head $ get_cons_names $ head constrs + ; let first_datacon = + case get_cons_names $ head constrs of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c ; cons' <- mapM (cvtConstr first_datacon cNameN) constrs ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField @@ -372,7 +378,11 @@ cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) cvtDec (NewtypeInstD ctxt bndrs tys ksig constr derivs) = do { (ctxt', tc', bndrs', typats') <- cvt_datainst_hdr ctxt bndrs tys ; ksig' <- cvtKind `traverse` ksig - ; con' <- cvtConstr (NE.head $ get_cons_names $ constr) cNameN constr + ; let first_datacon = + case get_cons_names constr of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c + ; con' <- cvtConstr first_datacon cNameN constr ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_cType = Nothing @@ -507,7 +517,10 @@ cvtGenDataDec type_data ctxt tc tvs ksig constrs derivs ; (ctxt', tc', tvs') <- cvt_tycl_hdr ctxt tc tvs ; ksig' <- cvtKind `traverse` ksig - ; let first_datacon = NE.head $ get_cons_names $ head constrs + ; let first_datacon = + case get_cons_names $ head constrs of + [] -> panic "cvtGenDataDec: empty list of constructors" + c:_ -> c ; cons' <- mapM (cvtConstr first_datacon con_name) constrs ; derivs' <- cvtDerivs derivs @@ -709,18 +722,22 @@ cvtConstr parent_con do_con_name (ForallC tvs ctxt con) where all_tvs = tvs' ++ ex_tvs -cvtConstr _ do_con_name (GadtC cs strtys ty) - = do { cs' <- mapM do_con_name cs - ; args <- mapM cvt_arg strtys - ; ty' <- cvtType ty - ; mk_gadt_decl cs' (PrefixConGADT $ map hsLinear args) ty'} - -cvtConstr parent_con do_con_name (RecGadtC cs varstrtys ty) - = do { cs' <- mapM do_con_name cs - ; ty' <- cvtType ty - ; rec_flds <- mapM (cvt_id_arg parent_con) varstrtys - ; lrec_flds <- returnLA rec_flds - ; mk_gadt_decl cs' (RecConGADT lrec_flds noHsUniTok) ty' } +cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of + Nothing -> failWith GadtNoCons + Just c -> do + { c' <- mapM do_con_name c + ; args <- mapM cvt_arg strtys + ; ty' <- cvtType ty + ; mk_gadt_decl c' (PrefixConGADT $ map hsLinear args) ty'} + +cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of + Nothing -> failWith RecGadtNoCons + Just c -> do + { c' <- mapM do_con_name c + ; ty' <- cvtType ty + ; rec_flds <- mapM (cvt_id_arg parent_con) varstrtys + ; lrec_flds <- returnLA rec_flds + ; mk_gadt_decl c' (RecConGADT lrec_flds noHsUniTok) ty' } mk_gadt_decl :: NonEmpty (LocatedN RdrName) -> HsConDeclGADTDetails GhcPs -> LHsType GhcPs -> CvtM (LConDecl GhcPs) ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -622,6 +622,8 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "CasesExprWithoutAlts" = 91745 GhcDiagnosticCode "ImplicitParamsWithOtherBinds" = 42974 GhcDiagnosticCode "InvalidCCallImpent" = 60220 + GhcDiagnosticCode "RecGadtNoCons" = 18816 + GhcDiagnosticCode "GadtNoCons" = 38140 GhcDiagnosticCode "InvalidTypeInstanceHeader" = 37056 GhcDiagnosticCode "InvalidTyFamInstLHS" = 78486 GhcDiagnosticCode "InvalidImplicitParamBinding" = 51603 @@ -705,8 +707,6 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnNameByTemplateHaskellQuote" = 40027 GhcDiagnosticCode "TcRnIllegalBindingOfBuiltIn" = 69639 GhcDiagnosticCode "TcRnMixedSelectors" = 40887 - GhcDiagnosticCode "RecGadtNoCons" = 18816 - GhcDiagnosticCode "GadtNoCons" = 38140 {- ********************************************************************* * * ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -104,10 +104,6 @@ Runtime system ``template-haskell`` library ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- The ``GadtC`` and ``RecGadtC`` constructors of the ``Con`` datatype now take - non-empty lists of constructors. This means that the ``gadtC`` and ``recGadtC`` - smart constructors also expect non-empty lists as arguments. - - Record fields now belong to separate ``NameSpace``s, keyed by the parent of the record field. This is the name of the first constructor of the parent type, even if this constructor does not have the field in question. ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -23,7 +23,7 @@ import qualified Language.Haskell.TH.Syntax as TH import Control.Applicative(liftA, Applicative(..)) import qualified Data.Kind as Kind (Type) import Data.Word( Word8 ) -import Data.List.NonEmpty ( NonEmpty(..), toList ) +import Data.List.NonEmpty ( NonEmpty(..) ) import GHC.Exts (TYPE) import Prelude hiding (Applicative(..)) @@ -680,10 +680,10 @@ forallC ns ctxt con = do con' <- con pure $ ForallC ns' ctxt' con' -gadtC :: Quote m => NonEmpty Name -> [m StrictType] -> m Type -> m Con +gadtC :: Quote m => [Name] -> [m StrictType] -> m Type -> m Con gadtC cons strtys ty = liftA2 (GadtC cons) (sequenceA strtys) ty -recGadtC :: Quote m => NonEmpty Name -> [m VarStrictType] -> m Type -> m Con +recGadtC :: Quote m => [Name] -> [m VarStrictType] -> m Type -> m Con recGadtC cons varstrtys ty = liftA2 (RecGadtC cons) (sequenceA varstrtys) ty ------------------------------------------------------------------------------- @@ -1177,7 +1177,7 @@ docCons :: (Q Con, Maybe String, [Maybe String]) -> Q () docCons (c, md, arg_docs) = do c' <- c -- Attach docs to the constructors - sequence_ [ putDoc (DeclDoc nm) d | Just d <- [md], nm <- toList $ get_cons_names c' ] + sequence_ [ putDoc (DeclDoc nm) d | Just d <- [md], nm <- get_cons_names c' ] -- Attach docs to the arguments case c' of -- Record selector documentation isn't stored in the argument map, @@ -1188,6 +1188,6 @@ docCons (c, md, arg_docs) = do ] _ -> sequence_ [ putDoc (ArgDoc nm i) arg_doc - | nm <- toList $ get_cons_names c' + | nm <- get_cons_names c' , (i, Just arg_doc) <- zip [0..] arg_docs ] ===================================== libraries/template-haskell/Language/Haskell/TH/Ppr.hs ===================================== @@ -11,7 +11,6 @@ module Language.Haskell.TH.Ppr where import Text.PrettyPrint (render) import Language.Haskell.TH.PprLib import Language.Haskell.TH.Syntax -import qualified Data.List.NonEmpty as NE ( toList ) import Data.Word ( Word8 ) import Data.Char ( toLower, chr) import GHC.Show ( showMultiLineString ) @@ -684,21 +683,21 @@ instance Ppr Con where <+> pprBangType st2 ppr (ForallC ns ctxt (GadtC cs sts ty)) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprForall ns ctxt + = commaSepApplied cs <+> dcolon <+> pprForall ns ctxt <+> pprGadtRHS sts ty ppr (ForallC ns ctxt (RecGadtC cs vsts ty)) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprForall ns ctxt + = commaSepApplied cs <+> dcolon <+> pprForall ns ctxt <+> pprRecFields vsts ty ppr (ForallC ns ctxt con) = pprForall ns ctxt <+> ppr con ppr (GadtC cs sts ty) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprGadtRHS sts ty + = commaSepApplied cs <+> dcolon <+> pprGadtRHS sts ty ppr (RecGadtC cs vsts ty) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprRecFields vsts ty + = commaSepApplied cs <+> dcolon <+> pprRecFields vsts ty instance Ppr PatSynDir where ppr Unidir = text "<-" ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -48,7 +48,6 @@ import System.IO ( hPutStrLn, stderr ) import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import qualified Data.List.NonEmpty as NE ( singleton ) import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio @@ -2685,7 +2684,7 @@ data DecidedStrictness = DecidedLazy -- ^ Field inferred to not have a bang. | DecidedUnpack -- ^ Field inferred to be unpacked. deriving (Show, Eq, Ord, Data, Generic) --- | A single data constructor. +-- | A data constructor. -- -- The constructors for 'Con' can roughly be divided up into two categories: -- those for constructors with \"vanilla\" syntax ('NormalC', 'RecC', and @@ -2718,16 +2717,36 @@ data DecidedStrictness = DecidedLazy -- ^ Field inferred to not have a bang. -- Multiplicity annotations for data types are currently not supported -- in Template Haskell (i.e. all fields represented by Template Haskell -- will be linear). -data Con = NormalC Name [BangType] -- ^ @C Int a@ - | RecC Name [VarBangType] -- ^ @C { v :: Int, w :: a }@ - | InfixC BangType Name BangType -- ^ @Int :+ a@ - | ForallC [TyVarBndr Specificity] Cxt Con -- ^ @forall a. Eq a => C [a]@ - | GadtC (NonEmpty Name) [BangType] - Type -- See Note [GADT return type] - -- ^ @C :: a -> b -> T b Int@ - | RecGadtC (NonEmpty Name) [VarBangType] - Type -- See Note [GADT return type] - -- ^ @C :: { v :: Int } -> T b Int@ +data Con = + -- | @C Int a@ + NormalC Name [BangType] + + -- | @C { v :: Int, w :: a }@ + | RecC Name [VarBangType] + + -- | @Int :+ a@ + | InfixC BangType Name BangType + + -- | @forall a. Eq a => C [a]@ + | ForallC [TyVarBndr Specificity] Cxt Con + + -- @C :: a -> b -> T b Int@ + | GadtC [Name] + -- ^ The list of constructors, corresponding to the GADT constructor + -- syntax @C1, C2 :: a -> T b at . + -- + -- Invariant: the list must be non-empty. + [BangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] + + -- | @C :: { v :: Int } -> T b Int@ + | RecGadtC [Name] + -- ^ The list of constructors, corresponding to the GADT record + -- constructor syntax @C1, C2 :: { fld :: a } -> T b at . + -- + -- Invariant: the list must be non-empty. + [VarBangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] deriving (Show, Eq, Ord, Data, Generic) -- Note [GADT return type] @@ -2925,14 +2944,14 @@ thenCmp :: Ordering -> Ordering -> Ordering thenCmp EQ o2 = o2 thenCmp o1 _ = o1 -get_cons_names :: Con -> NonEmpty Name -get_cons_names (NormalC n _) = NE.singleton n -get_cons_names (RecC n _) = NE.singleton n -get_cons_names (InfixC _ n _) = NE.singleton n +get_cons_names :: Con -> [Name] +get_cons_names (NormalC n _) = [n] +get_cons_names (RecC n _) = [n] +get_cons_names (InfixC _ n _) = [n] get_cons_names (ForallC _ _ con) = get_cons_names con -- GadtC can have multiple names, e.g -- > data Bar a where -- > MkBar1, MkBar2 :: a -> Bar a -- Will have one GadtC with [MkBar1, MkBar2] as names get_cons_names (GadtC ns _ _) = ns -get_cons_names (RecGadtC ns _ _) = ns \ No newline at end of file +get_cons_names (RecGadtC ns _ _) = ns ===================================== libraries/template-haskell/changelog.md ===================================== @@ -2,10 +2,6 @@ ## 2.21.0.0 - * The `GadtC` and `RecGadtC` constructors of the `Con` datatype now take - non-empty lists of constructors. This means that the `gadtC` and `recGadtC` - smart constructors also expect non-empty lists as arguments. - * Record fields now belong to separate `NameSpace`s, keyed by the parent of the record field. This is the name of the first constructor of the parent type, even if this constructor does not have the field in question. ===================================== testsuite/tests/th/T10828.hs ===================================== @@ -6,7 +6,6 @@ module T10828 where import Language.Haskell.TH hiding (Type) import System.IO import Data.Kind (Type) -import qualified Data.List.NonEmpty as NE ( singleton ) $( do { decl <- [d| data family D a :: Type -> Type data instance D Int Bool :: Type where @@ -34,7 +33,7 @@ $( return [ DataD [] (mkName "T") [ PlainTV (mkName "a") () ] (Just StarT) - [ GadtC (NE.singleton (mkName "MkT")) + [ GadtC [mkName "MkT"] [ ( Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ) @@ -47,7 +46,7 @@ $( return , ForallC [PlainTV (mkName "a") SpecifiedSpec, PlainTV (mkName "b") SpecifiedSpec] [AppT (AppT EqualityT (VarT $ mkName "a" ) ) (ConT $ mkName "Int") ] $ - RecGadtC (NE.singleton (mkName "MkC")) + RecGadtC [mkName "MkC"] [ ( mkName "foo" , Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ===================================== testsuite/tests/th/T10828b.hs ===================================== @@ -4,7 +4,6 @@ module T10828b where import Language.Haskell.TH import System.IO -import qualified Data.List.NonEmpty as NE ( singleton ) -- attempting to mix GADT and normal constructors $( return @@ -24,7 +23,7 @@ $( return [AppT (AppT EqualityT (VarT $ mkName "a" ) ) (ConT $ mkName "Int") ] $ RecGadtC - (NE.singleton (mkName "MkC")) + [mkName "MkC"] [ ( mkName "foo" , Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ===================================== testsuite/tests/th/T10828b.stderr ===================================== @@ -1,5 +1,5 @@ -T10828b.hs:10:2: error: [GHC-24104] +T10828b.hs:9:2: error: [GHC-24104] Cannot mix GADT constructors with Haskell 98 constructors When splicing a TH declaration: data T a :: * ===================================== testsuite/tests/th/T11345.hs ===================================== @@ -5,7 +5,6 @@ module Main (main) where import Language.Haskell.TH -import qualified Data.List.NonEmpty as NE ( singleton ) infixr 7 :***: data GADT a where @@ -17,11 +16,11 @@ $(do gadtName <- newName "GADT2" infixName <- newName ":****:" a <- newName "a" return [ DataD [] gadtName [KindedTV a () StarT] Nothing - [ GadtC (NE.singleton prefixName) + [ GadtC [prefixName] [ (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) , (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) ] (AppT (ConT gadtName) (ConT ''Int)) - , GadtC (NE.singleton infixName) + , GadtC [infixName] [ (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) , (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) ] (AppT (ConT gadtName) (ConT ''Int)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e2eb275a1b6d3d1dae9c2864f001bea69d20c2a...3b7bbb39f28c926f8cfd30744253a418854bee31 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e2eb275a1b6d3d1dae9c2864f001bea69d20c2a...3b7bbb39f28c926f8cfd30744253a418854bee31 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 22:41:23 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sat, 01 Apr 2023 18:41:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23070-unify Message-ID: <6428b3137c73f_3483da5d96a4a810943b2@gitlab.mail> Simon Peyton Jones pushed new branch wip/T23070-unify at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23070-unify You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 1 22:43:12 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sat, 01 Apr 2023 18:43:12 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 25 commits: ci: make lint-ci-config job fast again Message-ID: <6428b3809d4ba_3483da5d95653410977c4@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - b316045a by Simon Peyton Jones at 2023-04-01T23:44:40+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 0feb6809 by Simon Peyton Jones at 2023-04-01T23:44:40+01:00 Add some documentation about redundant constraints - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/JS/Ppr.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Object.hs - compiler/GHC/StgToJS/Printer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd615d937a0db7747ef40562f5b3239df79356ed...0feb6809c2c50cfd099c3b5e4b1a2a4d0b24bdb2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd615d937a0db7747ef40562f5b3239df79356ed...0feb6809c2c50cfd099c3b5e4b1a2a4d0b24bdb2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 09:03:55 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 02 Apr 2023 05:03:55 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] First steps killing unifyWanted Message-ID: <642944fb277b7_3483da67a7fab411207e9@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 1f90b89f by Simon Peyton Jones at 2023-04-02T10:05:12+01:00 First steps killing unifyWanted - - - - - 6 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -1932,7 +1932,7 @@ checkExpectedKind hs_ty ty act_kind exp_kind ; if act_kind' `tcEqType` exp_kind then return res_ty -- This is very common - else do { co_k <- uType KindLevel origin act_kind' exp_kind + else do { co_k <- uTypeAndEmit KindLevel origin act_kind' exp_kind ; traceTc "checkExpectedKind" (vcat [ ppr act_kind , ppr exp_kind , ppr co_k ]) ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -653,9 +653,7 @@ can_eq_app :: CtEvidence -- :: s1 t1 ~N s2 t2 can_eq_app ev s1 t1 s2 t2 | CtWanted { ctev_dest = dest, ctev_rewriters = rewriters } <- ev = do { co_s <- unifyWanted rewriters loc Nominal s1 s2 - ; let arg_loc - | isNextArgVisible s1 = loc - | otherwise = updateCtLocOrigin loc toInvisibleOrigin + ; let arg_loc = adjustCtLoc (isNextArgVisible s1) False loc ; co_t <- unifyWanted rewriters arg_loc Nominal t1 t2 ; let co = mkAppCo co_s co_t ; setWantedEq dest co @@ -1213,14 +1211,8 @@ canDecomposableTyConAppOK ev eq_rel tc tys1 tys2 -- do either of these changes. (Forgetting to do so led to #16188) -- -- NB: infinite in length - new_locs = [ new_loc - | bndr <- tyConBinders tc - , let new_loc0 | isNamedTyConBinder bndr = toKindLoc loc - | otherwise = loc - new_loc | isInvisibleTyConBinder bndr - = updateCtLocOrigin new_loc0 toInvisibleOrigin - | otherwise - = new_loc0 ] + new_locs = [ adjustCtLocTyConBinder bndr loc + | bndr <- tyConBinders tc ] ++ repeat loc canDecomposableFunTy :: CtEvidence -> EqRel -> FunTyFlag ===================================== compiler/GHC/Tc/Solver/InertSet.hs ===================================== @@ -8,7 +8,7 @@ module GHC.Tc.Solver.InertSet ( -- * The work list WorkList(..), isEmptyWorkList, emptyWorkList, extendWorkListNonEq, extendWorkListCt, - extendWorkListCts, extendWorkListEq, + extendWorkListCts, extendWorkListEq, extendWorkListEqs, appendWorkList, extendWorkListImplic, workListSize, selectWorkItem, @@ -179,6 +179,9 @@ workListSize (WL { wl_eqs = eqs, wl_rest = rest }) extendWorkListEq :: Ct -> WorkList -> WorkList extendWorkListEq ct wl = wl { wl_eqs = ct : wl_eqs wl } +extendWorkListEqs :: [Ct] -> WorkList -> WorkList +extendWorkListEqs cts wl = wl { wl_eqs = cts ++ wl_eqs wl } + extendWorkListNonEq :: Ct -> WorkList -> WorkList -- Extension by non equality extendWorkListNonEq ct wl = wl { wl_rest = ct : wl_rest wl } ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -179,7 +179,6 @@ import GHC.Data.Bag as Bag import GHC.Data.Pair import GHC.Utils.Monad -import GHC.Utils.Misc( equalLength ) import GHC.Exts (oneShot) import Control.Monad @@ -1954,6 +1953,20 @@ unifyWanted :: RewriterSet -> CtLoc -- Very good short-cut when the two types are equal, or nearly so -- See Note [unifyWanted] -- The returned coercion's role matches the input parameter + +unifyWanted _rewriters loc role ty1 ty2 + = do { (co,cts) <- wrapTcS $ + do { ref <- TcM.newTcRef [] + ; let env = UE { u_role = role + , u_loc = loc + , u_defer = ref } + ; co <- uType env ty1 ty2 + ; cts <- TcM.readTcRef ref + ; return (co, cts) } + ; updWorkListTcS (extendWorkListEqs cts) + ; return co } + +{- unifyWanted rewriters loc Phantom ty1 ty2 = do { kind_co <- unifyWanted rewriters loc Nominal (typeKind ty1) (typeKind ty2) ; return (mkPhantomCo kind_co ty1 ty2) } @@ -1998,7 +2011,7 @@ unifyWanted rewriters loc role orig_ty1 orig_ty2 | ty1 `tcEqType` ty2 = return (mkReflCo role ty1) -- Check for equality; e.g. a ~ a, or (m a) ~ (m a) | otherwise = emitNewWantedEq loc rewriters role orig_ty1 orig_ty2 - +-} {- Note [Decomposing Dependent TyCons and Processing Wanted Equalities] ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -67,7 +67,7 @@ module GHC.Tc.Types.Constraint ( ctLocTypeOrKind_maybe, ctLocDepth, bumpCtLocDepth, isGivenLoc, setCtLocOrigin, updateCtLocOrigin, setCtLocEnv, setCtLocSpan, - pprCtLoc, + pprCtLoc, adjustCtLoc, adjustCtLocTyConBinder, -- CtEvidence CtEvidence(..), TcEvDest(..), @@ -2394,10 +2394,11 @@ dictionaries don't appear in the original source code. -} -data CtLoc = CtLoc { ctl_origin :: CtOrigin - , ctl_env :: TcLclEnv - , ctl_t_or_k :: Maybe TypeOrKind -- OK if we're not sure - , ctl_depth :: !SubGoalDepth } +data CtLoc + = CtLoc { ctl_origin :: CtOrigin + , ctl_env :: TcLclEnv + , ctl_t_or_k :: Maybe TypeOrKind -- Used only to improve error messages + , ctl_depth :: !SubGoalDepth } -- The TcLclEnv includes particularly -- source location: tcl_loc :: RealSrcSpan @@ -2411,6 +2412,26 @@ mkKindLoc s1 s2 loc = setCtLocOrigin (toKindLoc loc) (KindEqOrigin s1 s2 (ctLocOrigin loc) (ctLocTypeOrKind_maybe loc)) +adjustCtLocTyConBinder :: TyConBinder -> CtLoc -> CtLoc +-- Adjust the CtLoc when decomposing a type constructor +adjustCtLocTyConBinder tc_bndr loc + = adjustCtLoc is_invis is_kind loc + where + is_invis = isInvisibleTyConBinder tc_bndr + is_kind = isNamedTyConBinder tc_bndr + +adjustCtLoc :: Bool -- True <=> An invisible argument + -> Bool -- True <=> A kind argument + -> CtLoc -> CtLoc +-- Adjust the CtLoc when decomposing a type constructor, application, etc +adjustCtLoc is_invis is_kind loc + = loc2 + where + loc1 | is_kind = toKindLoc loc + | otherwise = loc + loc2 | is_invis = updateCtLocOrigin loc1 toInvisibleOrigin + | otherwise = loc1 + -- | Take a CtLoc and moves it to the kind level toKindLoc :: CtLoc -> CtLoc toKindLoc loc = loc { ctl_t_or_k = Just KindLevel } ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -21,8 +21,9 @@ module GHC.Tc.Utils.Unify ( -- Various unifications unifyType, unifyKind, unifyExpectedType, - uType, promoteTcType, + uTypeAndEmit, promoteTcType, swapOverTyVars, touchabilityAndShapeTest, + UnifyEnv(..), uType, -------------------------------- -- Holes @@ -1145,7 +1146,7 @@ tcEqMult origin w_actual w_expected = do { -- Note that here we do not call to `submult`, so we check -- for strict equality. - ; coercion <- uType TypeLevel origin w_actual w_expected + ; coercion <- uTypeAndEmit TypeLevel origin w_actual w_expected ; return $ if isReflCo coercion then WpHole else WpMultCoercion coercion } @@ -1711,7 +1712,7 @@ unifyType :: Maybe TypedThing -- ^ If present, the thing that has type ty1 -- Actual and expected types -- Returns a coercion : ty1 ~ ty2 unifyType thing ty1 ty2 - = uType TypeLevel origin ty1 ty2 + = uTypeAndEmit TypeLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty1 , uo_expected = ty2 @@ -1722,7 +1723,7 @@ unifyTypeET :: TcTauType -> TcTauType -> TcM CoercionN -- Like unifyType, but swap expected and actual in error messages -- This is used when typechecking patterns unifyTypeET ty1 ty2 - = uType TypeLevel origin ty1 ty2 + = uTypeAndEmit TypeLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty2 -- NB swapped , uo_expected = ty1 -- NB swapped @@ -1732,13 +1733,26 @@ unifyTypeET ty1 ty2 unifyKind :: Maybe TypedThing -> TcKind -> TcKind -> TcM CoercionN unifyKind mb_thing ty1 ty2 - = uType KindLevel origin ty1 ty2 + = uTypeAndEmit KindLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty1 , uo_expected = ty2 , uo_thing = mb_thing , uo_visible = True } +uTypeAndEmit :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM CoercionN +-- Make a ref-cell, unify, emit the collected constraints +uTypeAndEmit t_or_k orig ty1 ty2 + = do { ref <- newTcRef [] + ; loc <- getCtLocM orig (Just t_or_k) + ; let env = UE { u_loc = loc, u_role = Nominal, u_defer = ref } + + -- The hard work happens here + ; co <- uType env ty1 ty2 + + ; cts <- readTcRef ref + ; unless (null cts) (emitSimples (listToBag cts)) + ; return co } {- %************************************************************************ @@ -1750,42 +1764,67 @@ unifyKind mb_thing ty1 ty2 uType is the heart of the unifier. -} +data UnifyEnv + = UE { u_role :: Role + , u_loc :: CtLoc + , u_defer :: TcRef [Ct] } + +mkKindEnv :: UnifyEnv -> TcType -> TcType -> UnifyEnv +-- Modify the UnifyEnv to be right for unifing +-- the kinds of these two types +mkKindEnv env@(UE { u_loc = ctloc }) ty1 ty2 + | CtLoc { ctl_t_or_k = t_or_k, ctl_origin = origin } <- ctloc + , let kind_origin = KindEqOrigin ty1 ty2 origin t_or_k + = env { u_role = Nominal + , u_loc = ctloc { ctl_origin = kind_origin + , ctl_t_or_k = Just KindLevel } } + uType, uType_defer - :: TypeOrKind - -> CtOrigin + :: UnifyEnv -> TcType -- ty1 is the *actual* type -> TcType -- ty2 is the *expected* type -> TcM CoercionN --------------- -- It is always safe to defer unification to the main constraint solver -- See Note [Deferred unification] --- ty1 is "actual" --- ty2 is "expected" -uType_defer t_or_k origin ty1 ty2 - = do { co <- emitWantedEq origin t_or_k Nominal ty1 ty2 +uType_defer (UE { u_loc = loc, u_defer = ref, u_role = role }) + ty1 ty2 -- ty1 is "actual", ty2 is "expected" + = do { let pred_ty = mkPrimEqPredRole role ty1 ty2 + ; hole <- newCoercionHole pred_ty + ; let ct = mkNonCanonical $ + CtWanted { ctev_pred = pred_ty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = rewriterSetFromTypes [ty1, ty2] } + co = HoleCo hole + ; updTcRef ref (ct :) -- Error trace only -- NB. do *not* call mkErrInfo unless tracing is on, -- because it is hugely expensive (#5631) - ; whenDOptM Opt_D_dump_tc_trace $ do - { ctxt <- getErrCtxt - ; doc <- mkErrInfo emptyTidyEnv ctxt + ; whenDOptM Opt_D_dump_tc_trace $ + do { ctxt <- getErrCtxt + ; doc <- mkErrInfo emptyTidyEnv ctxt ; traceTc "utype_defer" (vcat [ debugPprType ty1 , debugPprType ty2 - , pprCtOrigin origin , doc]) - ; traceTc "utype_defer2" (ppr co) - } + ; traceTc "utype_defer2" (ppr co) } + ; return co } + -------------- -uType t_or_k origin orig_ty1 orig_ty2 +uType env@(UE { u_role = role }) orig_ty1 orig_ty2 + | Phantom <- role + = do { kind_co <- uType (mkKindEnv env orig_ty1 orig_ty2) + (typeKind orig_ty1) (typeKind orig_ty2) + ; return (mkPhantomCo kind_co orig_ty1 orig_ty2) } + + | otherwise = do { tclvl <- getTcLevel ; traceTc "u_tys" $ vcat [ text "tclvl" <+> ppr tclvl - , sep [ ppr orig_ty1, text "~", ppr orig_ty2] - , pprCtOrigin origin] + , sep [ ppr orig_ty1, text "~", ppr orig_ty2] ] ; co <- go orig_ty1 orig_ty2 ; if isReflCo co then traceTc "u_tys yields no coercion" Outputable.empty @@ -1800,12 +1839,12 @@ uType t_or_k origin orig_ty1 orig_ty2 -- recognize (t |> co) ~ (t |> co), which is nice. Previously, we -- didn't do it this way, and then the unification above was deferred. go (CastTy t1 co1) t2 - = do { co_tys <- uType t_or_k origin t1 t2 - ; return (mkCoherenceLeftCo Nominal t1 co1 co_tys) } + = do { co_tys <- uType env t1 t2 + ; return (mkCoherenceLeftCo role t1 co1 co_tys) } go t1 (CastTy t2 co2) - = do { co_tys <- uType t_or_k origin t1 t2 - ; return (mkCoherenceRightCo Nominal t2 co2 co_tys) } + = do { co_tys <- uType env t1 t2 + ; return (mkCoherenceRightCo role t2 co2 co_tys) } -- Variables; go for uUnfilledVar -- Note that we pass in *original* (before synonym expansion), @@ -1816,18 +1855,18 @@ uType t_or_k origin orig_ty1 orig_ty2 ; case lookup_res of Just ty1 -> do { traceTc "found filled tyvar" (ppr tv1 <+> text ":->" <+> ppr ty1) ; go ty1 ty2 } - Nothing -> uUnfilledVar origin t_or_k NotSwapped tv1 ty2 } + Nothing -> uUnfilledVar env NotSwapped tv1 ty2 } go ty1 (TyVarTy tv2) = do { lookup_res <- isFilledMetaTyVar_maybe tv2 ; case lookup_res of Just ty2 -> do { traceTc "found filled tyvar" (ppr tv2 <+> text ":->" <+> ppr ty2) ; go ty1 ty2 } - Nothing -> uUnfilledVar origin t_or_k IsSwapped tv2 ty1 } + Nothing -> uUnfilledVar env IsSwapped tv2 ty1 } -- See Note [Expanding synonyms during unification] go ty1@(TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2 - = return $ mkNomReflCo ty1 + = return $ mkReflCo role ty1 -- See Note [Expanding synonyms during unification] -- @@ -1842,14 +1881,14 @@ uType t_or_k origin orig_ty1 orig_ty2 | Just ty2' <- coreView ty2 = go ty1 ty2' -- Functions (t1 -> t2) just check the two parts - -- Do not attempt (c => t); just defer go (FunTy { ft_af = af1, ft_mult = w1, ft_arg = arg1, ft_res = res1 }) (FunTy { ft_af = af2, ft_mult = w2, ft_arg = arg2, ft_res = res2 }) - | isVisibleFunArg af1, af1 == af2 - = do { co_l <- uType t_or_k origin arg1 arg2 - ; co_r <- uType t_or_k origin res1 res2 - ; co_w <- uType t_or_k origin w1 w2 - ; return $ mkNakedFunCo1 Nominal af1 co_w co_l co_r } + | isVisibleFunArg af1 -- Do not attempt (c => t); just defer + , af1 == af2 -- Important! See #21530 + = do { co_w <- uType (env { u_role = funRole role SelMult }) w1 w2 + ; co_l <- uType (env { u_role = funRole role SelArg }) arg1 arg2 + ; co_r <- uType (env { u_role = funRole role SelRes }) res1 res2 + ; return $ mkNakedFunCo1 role af1 co_w co_l co_r } -- Always defer if a type synonym family (type function) -- is involved. (Data families behave rigidly.) @@ -1861,41 +1900,39 @@ uType t_or_k origin orig_ty1 orig_ty2 go (TyConApp tc1 tys1) (TyConApp tc2 tys2) -- See Note [Mismatched type lists and application decomposition] | tc1 == tc2, equalLength tys1 tys2 - = assertPpr (isGenerativeTyCon tc1 Nominal) (ppr tc1) $ - do { cos <- zipWith3M (uType t_or_k) origins' tys1 tys2 - ; return $ mkTyConAppCo Nominal tc1 cos } - where - origins' = map (\is_vis -> if is_vis then origin else toInvisibleOrigin origin) - (tcTyConVisibilities tc1) + , isInjectiveTyCon tc1 role -- don't look under newtypes at Rep equality + = assertPpr (isGenerativeTyCon tc1 role) (ppr tc1) $ + do { cos <- zipWith4M u_tc_arg (tyConBinders tc1) + (tyConRoleListX role tc1) + tys1 tys2 + ; return $ mkTyConAppCo role tc1 cos } go (LitTy m) ty@(LitTy n) | m == n - = return $ mkNomReflCo ty + = return $ mkReflCo role ty -- See Note [Care with type applications] -- Do not decompose FunTy against App; -- it's often a type error, so leave it for the constraint solver - go (AppTy s1 t1) (AppTy s2 t2) - = go_app (isNextArgVisible s1) s1 t1 s2 t2 + go ty1@(AppTy s1 t1) ty2@(AppTy s2 t2) + = go_app (isNextArgVisible s1) ty1 s1 t1 ty2 s2 t2 - go (AppTy s1 t1) (TyConApp tc2 ts2) + go ty1@(AppTy s1 t1) ty2@(TyConApp tc2 ts2) | Just (ts2', t2') <- snocView ts2 = assert (not (tyConMustBeSaturated tc2)) $ - go_app (isNextTyConArgVisible tc2 ts2') s1 t1 (TyConApp tc2 ts2') t2' + go_app (isNextTyConArgVisible tc2 ts2') + ty1 s1 t1 ty2 (TyConApp tc2 ts2') t2' - go (TyConApp tc1 ts1) (AppTy s2 t2) + go ty1@(TyConApp tc1 ts1) ty2@(AppTy s2 t2) | Just (ts1', t1') <- snocView ts1 = assert (not (tyConMustBeSaturated tc1)) $ - go_app (isNextTyConArgVisible tc1 ts1') (TyConApp tc1 ts1') t1' s2 t2 + go_app (isNextTyConArgVisible tc1 ts1') + ty1 (TyConApp tc1 ts1') t1' ty2 s2 t2 - go (CoercionTy co1) (CoercionTy co2) - = do { let ty1 = coercionType co1 - ty2 = coercionType co2 - ; kco <- uType KindLevel - (KindEqOrigin orig_ty1 orig_ty2 origin - (Just t_or_k)) - ty1 ty2 - ; return $ mkProofIrrelCo Nominal kco co1 co2 } + go ty1@(CoercionTy co1) ty2@(CoercionTy co2) + = do { kco <- uType (mkKindEnv env ty1 ty2) + (coercionType co1) (coercionType co2) + ; return $ mkProofIrrelCo role kco co1 co2 } -- Anything else fails -- E.g. unifying for-all types, which is relative unusual @@ -1903,17 +1940,28 @@ uType t_or_k origin orig_ty1 orig_ty2 ------------------ defer ty1 ty2 -- See Note [Check for equality before deferring] - | ty1 `tcEqType` ty2 = return (mkNomReflCo ty1) - | otherwise = uType_defer t_or_k origin ty1 ty2 + | ty1 `tcEqType` ty2 = return (mkReflCo role ty1) + | otherwise = uType_defer env ty1 ty2 + ------------------ - go_app vis s1 t1 s2 t2 - = do { co_s <- uType t_or_k origin s1 s2 - ; let arg_origin - | vis = origin - | otherwise = toInvisibleOrigin origin - ; co_t <- uType t_or_k arg_origin t1 t2 + u_tc_arg tc_bndr role ty1 ty2 + = uType env_arg ty1 ty2 + where + env_arg = env { u_loc = adjustCtLocTyConBinder tc_bndr (u_loc env) + , u_role = role } + + ------------------ + -- For AppTy, decompose only nominal equalities + -- See Note [Decomposing AppTy equalities] in GHC.Tc.Solver.Equality + go_app vis ty1 s1 t1 ty2 s2 t2 + | Nominal <- role + = do { co_s <- uType env s1 s2 + ; let env_arg = env { u_loc = adjustCtLoc vis False (u_loc env) } + ; co_t <- uType env_arg t1 t2 ; return $ mkAppCo co_s co_t } + | otherwise + = defer ty1 ty2 {- Note [Check for equality before deferring] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2009,45 +2057,36 @@ back into @uTys@ if it turns out that the variable is already bound. -} ---------- -uUnfilledVar :: CtOrigin - -> TypeOrKind - -> SwapFlag - -> TcTyVar -- Tyvar 1: not necessarily a meta-tyvar - -- definitely not a /filled/ meta-tyvar - -> TcTauType -- Type 2 - -> TcM Coercion +uUnfilledVar, uUnfilledVar1 + :: UnifyEnv + -> SwapFlag + -> TcTyVar -- Tyvar 1: not necessarily a meta-tyvar + -- definitely not a /filled/ meta-tyvar + -> TcTauType -- Type 2 + -> TcM CoercionN -- "Unfilled" means that the variable is definitely not a filled-in meta tyvar -- It might be a skolem, or untouchable, or meta -uUnfilledVar origin t_or_k swapped tv1 ty2 - = do { ty2 <- zonkTcType ty2 - -- Zonk to expose things to the - -- occurs check, and so that if ty2 - -- looks like a type variable then it - -- /is/ a type variable - ; uUnfilledVar1 origin t_or_k swapped tv1 ty2 } +uUnfilledVar env swapped tv1 ty2 + = do { ty2 <- zonkTcType ty2 -- Zonk to expose things to the + -- occurs check, and so that if ty2 + -- looks like a type variable then it + -- /is/ a type variable + ; uUnfilledVar1 env swapped tv1 ty2 } ----------- -uUnfilledVar1 :: CtOrigin - -> TypeOrKind - -> SwapFlag - -> TcTyVar -- Tyvar 1: not necessarily a meta-tyvar - -- definitely not a /filled/ meta-tyvar - -> TcTauType -- Type 2, zonked - -> TcM Coercion -uUnfilledVar1 origin t_or_k swapped tv1 ty2 +uUnfilledVar1 env@(UE { u_role = role }) swapped tv1 ty2 -- ty2 is zonked | Just tv2 <- getTyVar_maybe ty2 = go tv2 | otherwise - = uUnfilledVar2 origin t_or_k swapped tv1 ty2 + = uUnfilledVar2 env swapped tv1 ty2 where -- 'go' handles the case where both are -- tyvars so we might want to swap -- E.g. maybe tv2 is a meta-tyvar and tv1 is not go tv2 | tv1 == tv2 -- Same type variable => no-op - = return (mkNomReflCo (mkTyVarTy tv1)) + = return (mkReflCo role (mkTyVarTy tv1)) | swapOverTyVars False tv1 tv2 -- Distinct type variables -- Swap meta tyvar to the left if poss @@ -2056,21 +2095,19 @@ uUnfilledVar1 origin t_or_k swapped tv1 ty2 -- not have happened yet, and it's an invariant of -- uUnfilledTyVar2 that ty2 is fully zonked -- Omitting this caused #16902 - ; uUnfilledVar2 origin t_or_k (flipSwap swapped) - tv2 (mkTyVarTy tv1) } + ; uUnfilledVar2 env (flipSwap swapped) tv2 (mkTyVarTy tv1) } | otherwise - = uUnfilledVar2 origin t_or_k swapped tv1 ty2 + = uUnfilledVar2 env swapped tv1 ty2 ---------- -uUnfilledVar2 :: CtOrigin - -> TypeOrKind +uUnfilledVar2 :: UnifyEnv -> SwapFlag -> TcTyVar -- Tyvar 1: not necessarily a meta-tyvar -- definitely not a /filled/ meta-tyvar -> TcTauType -- Type 2, zonked - -> TcM Coercion -uUnfilledVar2 origin t_or_k swapped tv1 ty2 + -> TcM CoercionN +uUnfilledVar2 env@(UE { u_role = role }) swapped tv1 ty2 = do { cur_lvl <- getTcLevel -- See Note [Unification preconditions], (UNTOUCHABLE) wrinkles -- Here we don't know about given equalities here; so we treat @@ -2079,7 +2116,7 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2 && simpleUnifyCheck False tv1 ty2) then not_ok_so_defer else - do { co_k <- uType KindLevel kind_origin (typeKind ty2) (tyVarKind tv1) + do { co_k <- uType (mkKindEnv env ty1 ty2) (typeKind ty2) (tyVarKind tv1) ; traceTc "uUnfilledVar2 ok" $ vcat [ ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1) , ppr ty2 <+> dcolon <+> ppr (typeKind ty2) @@ -2090,7 +2127,7 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2 -- NB: tv1 should still be unfilled, despite the kind unification -- because tv1 is not free in ty2' (or, hence, in its kind) then do { writeMetaTyVar tv1 ty2 - ; return (mkNomReflCo ty2) } + ; return (mkReflCo role ty2) } else defer -- This cannot be solved now. See GHC.Tc.Solver.Canonical -- Note [Equalities with incompatible kinds] for how @@ -2098,9 +2135,7 @@ uUnfilledVar2 origin t_or_k swapped tv1 ty2 }} where ty1 = mkTyVarTy tv1 - kind_origin = KindEqOrigin ty1 ty2 origin (Just t_or_k) - - defer = unSwap swapped (uType_defer t_or_k origin) ty1 ty2 + defer = unSwap swapped (uType_defer env) ty1 ty2 not_ok_so_defer = do { traceTc "uUnfilledVar2 not ok" (ppr tv1 $$ ppr ty2) @@ -2514,7 +2549,7 @@ matchExpectedFunKind hs_ty n k = go n k , uo_thing = Just hs_ty , uo_visible = True } - ; uType KindLevel origin k new_fun } + ; uTypeAndEmit KindLevel origin k new_fun } {- ********************************************************************* * * @@ -3228,4 +3263,3 @@ checkTopShape info xi _ -> False CycleBreakerTv -> False -- We never unify these _ -> True - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f90b89fdf71e49bf6a69d8813ed34bafbe189a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f90b89fdf71e49bf6a69d8813ed34bafbe189a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 20:39:37 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 02 Apr 2023 16:39:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: JS: Linker: use saturated JExpr Message-ID: <6429e8093d475_3483da72dda988117099e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f842bac2 by Bodigrim at 2023-04-02T16:39:21-04:00 Rework documentation for data Char - - - - - 815449c7 by Bodigrim at 2023-04-02T16:39:22-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - 23 changed files: - compiler/GHC/Cmm/Parser.y - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.8.1-notes.rst - libraries/ghc-prim/GHC/Types.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/cmm/should_run/AtomicFetch.hs - + testsuite/tests/cmm/should_run/AtomicFetch.stdout - + testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm - testsuite/tests/cmm/should_run/all.T - testsuite/tests/th/T10828.hs - testsuite/tests/th/T10828b.hs - testsuite/tests/th/T10828b.stderr - testsuite/tests/th/T11345.hs Changes: ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1137,6 +1137,12 @@ callishMachOps platform = listToUFM $ , allWidths "load_seqcst" (\w -> MO_AtomicRead w MemOrderSeqCst) , allWidths "store_release" (\w -> MO_AtomicWrite w MemOrderRelease) , allWidths "store_seqcst" (\w -> MO_AtomicWrite w MemOrderSeqCst) + , allWidths "fetch_add" (\w -> MO_AtomicRMW w AMO_Add) + , allWidths "fetch_sub" (\w -> MO_AtomicRMW w AMO_Sub) + , allWidths "fetch_and" (\w -> MO_AtomicRMW w AMO_And) + , allWidths "fetch_nand" (\w -> MO_AtomicRMW w AMO_Nand) + , allWidths "fetch_or" (\w -> MO_AtomicRMW w AMO_Or) + , allWidths "fetch_xor" (\w -> MO_AtomicRMW w AMO_Xor) ] where allWidths ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -95,7 +95,7 @@ import Language.Haskell.Syntax.Basic (FieldLabelString(..)) import Data.ByteString ( unpack ) import Control.Monad import Data.List (sort, sortBy) -import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.List.NonEmpty ( NonEmpty(..), toList ) import Data.Function import Control.Monad.Trans.Reader import Control.Monad.Trans.Class @@ -2742,19 +2742,16 @@ repGadtDataCons :: NonEmpty (LocatedN Name) -> LHsType GhcRn -> MetaM (Core (M TH.Con)) repGadtDataCons cons details res_ty - = do ne_tycon <- lift $ dsLookupTyCon nonEmptyTyConName - name_tycon <- lift $ dsLookupTyCon nameTyConName - let mk_nonEmpty = coreListNonEmpty ne_tycon (mkTyConTy name_tycon) - cons' <- mapM lookupLOcc cons -- See Note [Binders and occurrences] + = do cons' <- mapM lookupLOcc cons -- See Note [Binders and occurrences] case details of PrefixConGADT ps -> do arg_tys <- repPrefixConArgs ps res_ty' <- repLTy res_ty - rep2 gadtCName [unC (mk_nonEmpty cons'), unC arg_tys, unC res_ty'] + rep2 gadtCName [ unC (nonEmptyCoreList' cons'), unC arg_tys, unC res_ty'] RecConGADT ips _ -> do arg_vtys <- repRecConArgs ips res_ty' <- repLTy res_ty - rep2 recGadtCName [unC (mk_nonEmpty cons'), unC arg_vtys, + rep2 recGadtCName [unC (nonEmptyCoreList' cons'), unC arg_vtys, unC res_ty'] -- TH currently only supports linear constructors. @@ -3060,6 +3057,9 @@ nonEmptyCoreList :: [Core a] -> Core [a] nonEmptyCoreList [] = panic "coreList: empty argument" nonEmptyCoreList xs@(MkC x:_) = MkC (mkListExpr (exprType x) (map unC xs)) +nonEmptyCoreList' :: NonEmpty (Core a) -> Core [a] +nonEmptyCoreList' xs@(MkC x:|_) = MkC (mkListExpr (exprType x) (toList $ fmap unC xs)) + coreStringLit :: MonadThings m => FastString -> m (Core String) coreStringLit s = do { z <- mkStringExprFS s; return (MkC z) } ===================================== compiler/GHC/JS/Transform.hs ===================================== @@ -23,7 +23,6 @@ module GHC.JS.Transform , composOpFold , satJExpr , satJStat - , unsatJStat ) where @@ -321,98 +320,3 @@ satJVal = go go (JHash m) = Sat.JHash (satJExpr <$> m) go (JFunc args body) = Sat.JFunc args (satJStat body) go UnsatVal{} = error "jvalToSatVar: discovered an Sat...impossibly" - -unsatJStat :: Sat.JStat -> JStat -unsatJStat = go_back - where - -- This is an Applicative but we can't use it because no type variables :( - go_back :: Sat.JStat -> JStat - go_back (Sat.DeclStat i rhs) = DeclStat i (fmap unsatJExpr rhs) - go_back (Sat.ReturnStat e) = ReturnStat (unsatJExpr e) - go_back (Sat.IfStat c t e) = IfStat (unsatJExpr c) (go_back t) (go_back e) - go_back (Sat.WhileStat is_do c e) = WhileStat is_do (unsatJExpr c) (go_back e) - go_back (Sat.ForInStat is_each i iter body) = ForInStat is_each i - (unsatJExpr iter) - (go_back body) - go_back (Sat.SwitchStat struct ps def) = SwitchStat - (unsatJExpr struct) - (map (unsatJExpr *** go_back) ps) - (go_back def) - go_back (Sat.TryStat t i c f) = TryStat (go_back t) i (go_back c) (go_back f) - go_back (Sat.BlockStat bs) = BlockStat $! fmap go_back bs - go_back (Sat.ApplStat rator rand) = ApplStat (unsatJExpr rator) (unsatJExpr <$> rand) - go_back (Sat.UOpStat rator rand) = UOpStat (unsatJUOp rator) (unsatJExpr rand) - go_back (Sat.AssignStat lhs rhs) = AssignStat (unsatJExpr lhs) (unsatJExpr rhs) - go_back (Sat.LabelStat lbl stmt) = LabelStat lbl (go_back stmt) - go_back (Sat.BreakStat Nothing) = BreakStat Nothing - go_back (Sat.BreakStat (Just l)) = BreakStat $! Just l - go_back (Sat.ContinueStat Nothing) = ContinueStat Nothing - go_back (Sat.ContinueStat (Just l)) = ContinueStat $! Just l - - -unsatJExpr :: Sat.JExpr -> JExpr -unsatJExpr = go - where - go (Sat.ValExpr v) = ValExpr (unsatJVal v) - go (Sat.SelExpr obj i) = SelExpr (unsatJExpr obj) i - go (Sat.IdxExpr o i) = IdxExpr (unsatJExpr o) (unsatJExpr i) - go (Sat.InfixExpr op l r) = InfixExpr (satOpToJOp op) (unsatJExpr l) (unsatJExpr r) - go (Sat.UOpExpr op r) = UOpExpr (unsatJUOp op) (unsatJExpr r) - go (Sat.IfExpr c t e) = IfExpr (unsatJExpr c) (unsatJExpr t) (unsatJExpr e) - go (Sat.ApplExpr rator rands) = ApplExpr (unsatJExpr rator) (unsatJExpr <$> rands) - -satOpToJOp :: Sat.Op -> JOp -satOpToJOp = go - where - go Sat.EqOp = EqOp - go Sat.StrictEqOp = StrictEqOp - go Sat.NeqOp = NeqOp - go Sat.StrictNeqOp = StrictNeqOp - go Sat.GtOp = GtOp - go Sat.GeOp = GeOp - go Sat.LtOp = LtOp - go Sat.LeOp = LeOp - go Sat.AddOp = AddOp - go Sat.SubOp = SubOp - go Sat.MulOp = MulOp - go Sat.DivOp = DivOp - go Sat.ModOp = ModOp - go Sat.LeftShiftOp = LeftShiftOp - go Sat.RightShiftOp = RightShiftOp - go Sat.ZRightShiftOp = ZRightShiftOp - go Sat.BAndOp = BAndOp - go Sat.BOrOp = BOrOp - go Sat.BXorOp = BXorOp - go Sat.LAndOp = LAndOp - go Sat.LOrOp = LOrOp - go Sat.InstanceofOp = InstanceofOp - go Sat.InOp = InOp - -unsatJUOp :: Sat.UOp -> JUOp -unsatJUOp = go - where - go Sat.NotOp = NotOp - go Sat.BNotOp = BNotOp - go Sat.NegOp = NegOp - go Sat.PlusOp = PlusOp - go Sat.NewOp = NewOp - go Sat.TypeofOp = TypeofOp - go Sat.DeleteOp = DeleteOp - go Sat.YieldOp = YieldOp - go Sat.VoidOp = VoidOp - go Sat.PreIncOp = PreIncOp - go Sat.PostIncOp = PostIncOp - go Sat.PreDecOp = PreDecOp - go Sat.PostDecOp = PostDecOp - -unsatJVal :: Sat.JVal -> JVal -unsatJVal = go - where - go (Sat.JVar i) = JVar i - go (Sat.JList xs) = JList (unsatJExpr <$> xs) - go (Sat.JDouble d) = JDouble (SaneDouble (Sat.unSaneDouble d)) - go (Sat.JInt i) = JInt i - go (Sat.JStr f) = JStr f - go (Sat.JRegEx f) = JRegEx f - go (Sat.JHash m) = JHash (unsatJExpr <$> m) - go (Sat.JFunc args body) = JFunc args (unsatJStat body) ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -31,6 +31,7 @@ import GHC.Platform.Host (hostPlatformArchOS) import GHC.JS.Make import GHC.JS.Unsat.Syntax +import qualified GHC.JS.Syntax as Sat import GHC.JS.Transform import GHC.Driver.Session (DynFlags(..)) @@ -280,7 +281,7 @@ computeLinkDependencies cfg logger target unit_env units objFiles extraStaticDep -- | Compiled module data ModuleCode = ModuleCode { mc_module :: !Module - , mc_js_code :: !JStat + , mc_js_code :: !Sat.JStat , mc_exports :: !B.ByteString -- ^ rendered exports , mc_closures :: ![ClosureInfo] , mc_statics :: ![StaticInfo] @@ -293,7 +294,7 @@ data ModuleCode = ModuleCode -- up into global "metadata" for the whole link. data CompactedModuleCode = CompactedModuleCode { cmc_module :: !Module - , cmc_js_code :: !JStat + , cmc_js_code :: !Sat.JStat , cmc_exports :: !B.ByteString -- ^ rendered exports } @@ -326,7 +327,7 @@ renderLinker h mods jsFiles = do -- modules themselves mod_sizes <- forM compacted_mods $ \m -> do - !mod_size <- fromIntegral <$> putJS (satJStat $! cmc_js_code m) + !mod_size <- fromIntegral <$> putJS (cmc_js_code m) let !mod_mod = cmc_module m pure (mod_mod, mod_size) @@ -565,7 +566,7 @@ extractDeps ar_state units deps loc = mod = depsModule deps newline = BC.pack "\n" mk_exports = mconcat . intersperse newline . filter (not . BS.null) . map oiRaw - mk_js_code = mconcat . map (unsatJStat . oiStat) + mk_js_code = mconcat . map oiStat collectCode l = ModuleCode { mc_module = mod , mc_js_code = mk_js_code l ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -4831,6 +4831,10 @@ pprConversionFailReason = \case text "Implicit parameters mixed with other bindings" InvalidCCallImpent from -> text (show from) <+> text "is not a valid ccall impent" + RecGadtNoCons -> + quotes (text "RecGadtC") <+> text "must have at least one constructor name" + GadtNoCons -> + quotes (text "GadtC") <+> text "must have at least one constructor name" InvalidTypeInstanceHeader tys -> text "Invalid type instance header:" <+> text (show tys) ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -3683,6 +3683,8 @@ data ConversionFailReason | CasesExprWithoutAlts | ImplicitParamsWithOtherBinds | InvalidCCallImpent !String -- ^ Source + | RecGadtNoCons + | GadtNoCons | InvalidTypeInstanceHeader !TH.Type | InvalidTyFamInstLHS !TH.Type | InvalidImplicitParamBinding ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -143,7 +143,6 @@ import Unsafe.Coerce ( unsafeCoerce ) import Control.Monad import Data.Binary import Data.Binary.Get -import qualified Data.List.NonEmpty as NE ( singleton ) import Data.Maybe import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as LB @@ -2235,7 +2234,7 @@ reifyDataCon isGadtDataCon tys dc dcdBangs r_arg_tys) | not (null fields) -> do { res_ty <- reifyType g_res_ty - ; return $ TH.RecGadtC (NE.singleton name) + ; return $ TH.RecGadtC [name] (zip3 (map reifyFieldLabel fields) dcdBangs r_arg_tys) res_ty } -- We need to check not isGadtDataCon here because GADT @@ -2248,7 +2247,7 @@ reifyDataCon isGadtDataCon tys dc ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } | isGadtDataCon -> do { res_ty <- reifyType g_res_ty - ; return $ TH.GadtC (NE.singleton name) + ; return $ TH.GadtC [name] (dcdBangs `zip` r_arg_tys) res_ty } | otherwise -> return $ TH.NormalC name (dcdBangs `zip` r_arg_tys) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -276,7 +276,11 @@ cvtDec (DataD ctxt tc tvs ksig constrs derivs) cvtDec (NewtypeD ctxt tc tvs ksig constr derivs) = do { (ctxt', tc', tvs') <- cvt_tycl_hdr ctxt tc tvs ; ksig' <- cvtKind `traverse` ksig - ; con' <- cvtConstr (NE.head $ get_cons_names constr) cNameN constr + ; let first_datacon = + case get_cons_names constr of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c + ; con' <- cvtConstr first_datacon cNameN constr ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_cType = Nothing @@ -348,8 +352,10 @@ cvtDec (DataFamilyD tc tvs kind) cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) = do { (ctxt', tc', bndrs', typats') <- cvt_datainst_hdr ctxt bndrs tys ; ksig' <- cvtKind `traverse` ksig - - ; let first_datacon = NE.head $ get_cons_names $ head constrs + ; let first_datacon = + case get_cons_names $ head constrs of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c ; cons' <- mapM (cvtConstr first_datacon cNameN) constrs ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField @@ -372,7 +378,11 @@ cvtDec (DataInstD ctxt bndrs tys ksig constrs derivs) cvtDec (NewtypeInstD ctxt bndrs tys ksig constr derivs) = do { (ctxt', tc', bndrs', typats') <- cvt_datainst_hdr ctxt bndrs tys ; ksig' <- cvtKind `traverse` ksig - ; con' <- cvtConstr (NE.head $ get_cons_names $ constr) cNameN constr + ; let first_datacon = + case get_cons_names constr of + [] -> panic "cvtDec: empty list of constructors" + c:_ -> c + ; con' <- cvtConstr first_datacon cNameN constr ; derivs' <- cvtDerivs derivs ; let defn = HsDataDefn { dd_ext = noExtField , dd_cType = Nothing @@ -507,7 +517,10 @@ cvtGenDataDec type_data ctxt tc tvs ksig constrs derivs ; (ctxt', tc', tvs') <- cvt_tycl_hdr ctxt tc tvs ; ksig' <- cvtKind `traverse` ksig - ; let first_datacon = NE.head $ get_cons_names $ head constrs + ; let first_datacon = + case get_cons_names $ head constrs of + [] -> panic "cvtGenDataDec: empty list of constructors" + c:_ -> c ; cons' <- mapM (cvtConstr first_datacon con_name) constrs ; derivs' <- cvtDerivs derivs @@ -709,18 +722,22 @@ cvtConstr parent_con do_con_name (ForallC tvs ctxt con) where all_tvs = tvs' ++ ex_tvs -cvtConstr _ do_con_name (GadtC cs strtys ty) - = do { cs' <- mapM do_con_name cs - ; args <- mapM cvt_arg strtys - ; ty' <- cvtType ty - ; mk_gadt_decl cs' (PrefixConGADT $ map hsLinear args) ty'} - -cvtConstr parent_con do_con_name (RecGadtC cs varstrtys ty) - = do { cs' <- mapM do_con_name cs - ; ty' <- cvtType ty - ; rec_flds <- mapM (cvt_id_arg parent_con) varstrtys - ; lrec_flds <- returnLA rec_flds - ; mk_gadt_decl cs' (RecConGADT lrec_flds noHsUniTok) ty' } +cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of + Nothing -> failWith GadtNoCons + Just c -> do + { c' <- mapM do_con_name c + ; args <- mapM cvt_arg strtys + ; ty' <- cvtType ty + ; mk_gadt_decl c' (PrefixConGADT $ map hsLinear args) ty'} + +cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of + Nothing -> failWith RecGadtNoCons + Just c -> do + { c' <- mapM do_con_name c + ; ty' <- cvtType ty + ; rec_flds <- mapM (cvt_id_arg parent_con) varstrtys + ; lrec_flds <- returnLA rec_flds + ; mk_gadt_decl c' (RecConGADT lrec_flds noHsUniTok) ty' } mk_gadt_decl :: NonEmpty (LocatedN RdrName) -> HsConDeclGADTDetails GhcPs -> LHsType GhcPs -> CvtM (LConDecl GhcPs) ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -622,6 +622,8 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "CasesExprWithoutAlts" = 91745 GhcDiagnosticCode "ImplicitParamsWithOtherBinds" = 42974 GhcDiagnosticCode "InvalidCCallImpent" = 60220 + GhcDiagnosticCode "RecGadtNoCons" = 18816 + GhcDiagnosticCode "GadtNoCons" = 38140 GhcDiagnosticCode "InvalidTypeInstanceHeader" = 37056 GhcDiagnosticCode "InvalidTyFamInstLHS" = 78486 GhcDiagnosticCode "InvalidImplicitParamBinding" = 51603 @@ -705,8 +707,6 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnNameByTemplateHaskellQuote" = 40027 GhcDiagnosticCode "TcRnIllegalBindingOfBuiltIn" = 69639 GhcDiagnosticCode "TcRnMixedSelectors" = 40887 - GhcDiagnosticCode "RecGadtNoCons" = 18816 - GhcDiagnosticCode "GadtNoCons" = 38140 {- ********************************************************************* * * ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -104,10 +104,6 @@ Runtime system ``template-haskell`` library ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- The ``GadtC`` and ``RecGadtC`` constructors of the ``Con`` datatype now take - non-empty lists of constructors. This means that the ``gadtC`` and ``recGadtC`` - smart constructors also expect non-empty lists as arguments. - - Record fields now belong to separate ``NameSpace``s, keyed by the parent of the record field. This is the name of the first constructor of the parent type, even if this constructor does not have the field in question. ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -202,17 +202,96 @@ data Ordering = LT | EQ | GT * * ********************************************************************* -} -{- | The character type 'Char' is an enumeration whose values represent -Unicode (or equivalently ISO\/IEC 10646) code points (i.e. characters, see - for details). This set extends the ISO 8859-1 -(Latin-1) character set (the first 256 characters), which is itself an extension -of the ASCII character set (the first 128 characters). A character literal in -Haskell has type 'Char'. - -To convert a 'Char' to or from the corresponding 'Int' value defined -by Unicode, use 'Prelude.toEnum' and 'Prelude.fromEnum' from the -'Prelude.Enum' class respectively (or equivalently 'Data.Char.ord' and -'Data.Char.chr'). +{- | The character type 'Char' represents Unicode codespace +and its elements are code points as in definitions +[D9 and D10 of the Unicode Standard](https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf#G2212). + +Character literals in Haskell are single-quoted: @\'Q\'@, @\'Я\'@ or @\'Ω\'@. +To represent a single quote itself use @\'\\''@, and to represent a backslash +use @\'\\\\\'@. The full grammar can be found in the section 2.6 of the +[Haskell 2010 Language Report](https://www.haskell.org/definition/haskell2010.pdf#section.2.6). + +To specify a character by its code point one can use decimal, hexadecimal +or octal notation: @\'\\65\'@, @\'\\x41\'@ and @\'\\o101\'@ are all alternative forms +of @\'A\'@. The largest code point is @\'\\x10ffff\'@. + +There is a special escape syntax for ASCII control characters: + ++-------------+-------------------+---------------------------+ +| Escape | Alternatives | Meaning | ++=============+===================+===========================+ +| @'\\NUL'@ | @'\\0'@ | null character | ++-------------+-------------------+---------------------------+ +| @'\\SOH'@ | @'\\1'@ | start of heading | ++-------------+-------------------+---------------------------+ +| @'\\STX'@ | @'\\2'@ | start of text | ++-------------+-------------------+---------------------------+ +| @'\\ETX'@ | @'\\3'@ | end of text | ++-------------+-------------------+---------------------------+ +| @'\\EOT'@ | @'\\4'@ | end of transmission | ++-------------+-------------------+---------------------------+ +| @'\\ENQ'@ | @'\\5'@ | enquiry | ++-------------+-------------------+---------------------------+ +| @'\\ACK'@ | @'\\6'@ | acknowledge | ++-------------+-------------------+---------------------------+ +| @'\\BEL'@ | @'\\7'@, @'\\a'@ | bell (alert) | ++-------------+-------------------+---------------------------+ +| @'\\BS'@ | @'\\8'@, @'\\b'@ | backspace | ++-------------+-------------------+---------------------------+ +| @'\\HT'@ | @'\\9'@, @'\\t'@ | horizontal tab | ++-------------+-------------------+---------------------------+ +| @'\\LF'@ | @'\\10'@, @'\\n'@ | line feed (new line) | ++-------------+-------------------+---------------------------+ +| @'\\VT'@ | @'\\11'@, @'\\v'@ | vertical tab | ++-------------+-------------------+---------------------------+ +| @'\\FF'@ | @'\\12'@, @'\\f'@ | form feed | ++-------------+-------------------+---------------------------+ +| @'\\CR'@ | @'\\13'@, @'\\r'@ | carriage return | ++-------------+-------------------+---------------------------+ +| @'\\SO'@ | @'\\14'@ | shift out | ++-------------+-------------------+---------------------------+ +| @'\\SI'@ | @'\\15'@ | shift in | ++-------------+-------------------+---------------------------+ +| @'\\DLE'@ | @'\\16'@ | data link escape | ++-------------+-------------------+---------------------------+ +| @'\\DC1'@ | @'\\17'@ | device control 1 | ++-------------+-------------------+---------------------------+ +| @'\\DC2'@ | @'\\18'@ | device control 2 | ++-------------+-------------------+---------------------------+ +| @'\\DC3'@ | @'\\19'@ | device control 3 | ++-------------+-------------------+---------------------------+ +| @'\\DC4'@ | @'\\20'@ | device control 4 | ++-------------+-------------------+---------------------------+ +| @'\\NAK'@ | @'\\21'@ | negative acknowledge | ++-------------+-------------------+---------------------------+ +| @'\\SYN'@ | @'\\22'@ | synchronous idle | ++-------------+-------------------+---------------------------+ +| @'\\ETB'@ | @'\\23'@ | end of transmission block | ++-------------+-------------------+---------------------------+ +| @'\\CAN'@ | @'\\24'@ | cancel | ++-------------+-------------------+---------------------------+ +| @'\\EM'@ | @'\\25'@ | end of medium | ++-------------+-------------------+---------------------------+ +| @'\\SUB'@ | @'\\26'@ | substitute | ++-------------+-------------------+---------------------------+ +| @'\\ESC'@ | @'\\27'@ | escape | ++-------------+-------------------+---------------------------+ +| @'\\FS'@ | @'\\28'@ | file separator | ++-------------+-------------------+---------------------------+ +| @'\\GS'@ | @'\\29'@ | group separator | ++-------------+-------------------+---------------------------+ +| @'\\RS'@ | @'\\30'@ | record separator | ++-------------+-------------------+---------------------------+ +| @'\\US'@ | @'\\31'@ | unit separator | ++-------------+-------------------+---------------------------+ +| @'\\SP'@ | @'\\32'@, @' '@ | space | ++-------------+-------------------+---------------------------+ +| @'\\DEL'@ | @'\\127'@ | delete | ++-------------+-------------------+---------------------------+ + +[Data.Char](https://hackage.haskell.org/package/base/docs/Data-Char.html) +provides utilities to work with 'Char'. + -} data {-# CTYPE "HsChar" #-} Char = C# Char# ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -23,7 +23,7 @@ import qualified Language.Haskell.TH.Syntax as TH import Control.Applicative(liftA, Applicative(..)) import qualified Data.Kind as Kind (Type) import Data.Word( Word8 ) -import Data.List.NonEmpty ( NonEmpty(..), toList ) +import Data.List.NonEmpty ( NonEmpty(..) ) import GHC.Exts (TYPE) import Prelude hiding (Applicative(..)) @@ -680,10 +680,10 @@ forallC ns ctxt con = do con' <- con pure $ ForallC ns' ctxt' con' -gadtC :: Quote m => NonEmpty Name -> [m StrictType] -> m Type -> m Con +gadtC :: Quote m => [Name] -> [m StrictType] -> m Type -> m Con gadtC cons strtys ty = liftA2 (GadtC cons) (sequenceA strtys) ty -recGadtC :: Quote m => NonEmpty Name -> [m VarStrictType] -> m Type -> m Con +recGadtC :: Quote m => [Name] -> [m VarStrictType] -> m Type -> m Con recGadtC cons varstrtys ty = liftA2 (RecGadtC cons) (sequenceA varstrtys) ty ------------------------------------------------------------------------------- @@ -1177,7 +1177,7 @@ docCons :: (Q Con, Maybe String, [Maybe String]) -> Q () docCons (c, md, arg_docs) = do c' <- c -- Attach docs to the constructors - sequence_ [ putDoc (DeclDoc nm) d | Just d <- [md], nm <- toList $ get_cons_names c' ] + sequence_ [ putDoc (DeclDoc nm) d | Just d <- [md], nm <- get_cons_names c' ] -- Attach docs to the arguments case c' of -- Record selector documentation isn't stored in the argument map, @@ -1188,6 +1188,6 @@ docCons (c, md, arg_docs) = do ] _ -> sequence_ [ putDoc (ArgDoc nm i) arg_doc - | nm <- toList $ get_cons_names c' + | nm <- get_cons_names c' , (i, Just arg_doc) <- zip [0..] arg_docs ] ===================================== libraries/template-haskell/Language/Haskell/TH/Ppr.hs ===================================== @@ -11,7 +11,6 @@ module Language.Haskell.TH.Ppr where import Text.PrettyPrint (render) import Language.Haskell.TH.PprLib import Language.Haskell.TH.Syntax -import qualified Data.List.NonEmpty as NE ( toList ) import Data.Word ( Word8 ) import Data.Char ( toLower, chr) import GHC.Show ( showMultiLineString ) @@ -684,21 +683,21 @@ instance Ppr Con where <+> pprBangType st2 ppr (ForallC ns ctxt (GadtC cs sts ty)) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprForall ns ctxt + = commaSepApplied cs <+> dcolon <+> pprForall ns ctxt <+> pprGadtRHS sts ty ppr (ForallC ns ctxt (RecGadtC cs vsts ty)) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprForall ns ctxt + = commaSepApplied cs <+> dcolon <+> pprForall ns ctxt <+> pprRecFields vsts ty ppr (ForallC ns ctxt con) = pprForall ns ctxt <+> ppr con ppr (GadtC cs sts ty) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprGadtRHS sts ty + = commaSepApplied cs <+> dcolon <+> pprGadtRHS sts ty ppr (RecGadtC cs vsts ty) - = commaSepApplied (NE.toList cs) <+> dcolon <+> pprRecFields vsts ty + = commaSepApplied cs <+> dcolon <+> pprRecFields vsts ty instance Ppr PatSynDir where ppr Unidir = text "<-" ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -48,7 +48,6 @@ import System.IO ( hPutStrLn, stderr ) import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) import Data.Int import Data.List.NonEmpty ( NonEmpty(..) ) -import qualified Data.List.NonEmpty as NE ( singleton ) import Data.Void ( Void, absurd ) import Data.Word import Data.Ratio @@ -2685,7 +2684,7 @@ data DecidedStrictness = DecidedLazy -- ^ Field inferred to not have a bang. | DecidedUnpack -- ^ Field inferred to be unpacked. deriving (Show, Eq, Ord, Data, Generic) --- | A single data constructor. +-- | A data constructor. -- -- The constructors for 'Con' can roughly be divided up into two categories: -- those for constructors with \"vanilla\" syntax ('NormalC', 'RecC', and @@ -2718,16 +2717,36 @@ data DecidedStrictness = DecidedLazy -- ^ Field inferred to not have a bang. -- Multiplicity annotations for data types are currently not supported -- in Template Haskell (i.e. all fields represented by Template Haskell -- will be linear). -data Con = NormalC Name [BangType] -- ^ @C Int a@ - | RecC Name [VarBangType] -- ^ @C { v :: Int, w :: a }@ - | InfixC BangType Name BangType -- ^ @Int :+ a@ - | ForallC [TyVarBndr Specificity] Cxt Con -- ^ @forall a. Eq a => C [a]@ - | GadtC (NonEmpty Name) [BangType] - Type -- See Note [GADT return type] - -- ^ @C :: a -> b -> T b Int@ - | RecGadtC (NonEmpty Name) [VarBangType] - Type -- See Note [GADT return type] - -- ^ @C :: { v :: Int } -> T b Int@ +data Con = + -- | @C Int a@ + NormalC Name [BangType] + + -- | @C { v :: Int, w :: a }@ + | RecC Name [VarBangType] + + -- | @Int :+ a@ + | InfixC BangType Name BangType + + -- | @forall a. Eq a => C [a]@ + | ForallC [TyVarBndr Specificity] Cxt Con + + -- @C :: a -> b -> T b Int@ + | GadtC [Name] + -- ^ The list of constructors, corresponding to the GADT constructor + -- syntax @C1, C2 :: a -> T b at . + -- + -- Invariant: the list must be non-empty. + [BangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] + + -- | @C :: { v :: Int } -> T b Int@ + | RecGadtC [Name] + -- ^ The list of constructors, corresponding to the GADT record + -- constructor syntax @C1, C2 :: { fld :: a } -> T b at . + -- + -- Invariant: the list must be non-empty. + [VarBangType] -- ^ The constructor arguments + Type -- ^ See Note [GADT return type] deriving (Show, Eq, Ord, Data, Generic) -- Note [GADT return type] @@ -2925,14 +2944,14 @@ thenCmp :: Ordering -> Ordering -> Ordering thenCmp EQ o2 = o2 thenCmp o1 _ = o1 -get_cons_names :: Con -> NonEmpty Name -get_cons_names (NormalC n _) = NE.singleton n -get_cons_names (RecC n _) = NE.singleton n -get_cons_names (InfixC _ n _) = NE.singleton n +get_cons_names :: Con -> [Name] +get_cons_names (NormalC n _) = [n] +get_cons_names (RecC n _) = [n] +get_cons_names (InfixC _ n _) = [n] get_cons_names (ForallC _ _ con) = get_cons_names con -- GadtC can have multiple names, e.g -- > data Bar a where -- > MkBar1, MkBar2 :: a -> Bar a -- Will have one GadtC with [MkBar1, MkBar2] as names get_cons_names (GadtC ns _ _) = ns -get_cons_names (RecGadtC ns _ _) = ns \ No newline at end of file +get_cons_names (RecGadtC ns _ _) = ns ===================================== libraries/template-haskell/changelog.md ===================================== @@ -2,10 +2,6 @@ ## 2.21.0.0 - * The `GadtC` and `RecGadtC` constructors of the `Con` datatype now take - non-empty lists of constructors. This means that the `gadtC` and `recGadtC` - smart constructors also expect non-empty lists as arguments. - * Record fields now belong to separate `NameSpace`s, keyed by the parent of the record field. This is the name of the first constructor of the parent type, even if this constructor does not have the field in question. ===================================== testsuite/tests/cmm/should_run/AtomicFetch.hs ===================================== @@ -0,0 +1,54 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} + +-- This is not a test of atomic semantics, +-- just checking that GHC can parse %fetch_fooXX + +import GHC.Exts +import GHC.Int +import GHC.ST + +foreign import prim "cmm_foo8" cmm_foo8 + :: MutableByteArray# s -> State# s -> (# State# s, Int8# #) + +foreign import prim "cmm_foo16" cmm_foo16 + :: MutableByteArray# s -> State# s -> (# State# s, Int16# #) + +foreign import prim "cmm_foo32" cmm_foo32 + :: MutableByteArray# s -> State# s -> (# State# s, Int32# #) + +foreign import prim "cmm_foo64" cmm_foo64 + :: MutableByteArray# s -> State# s -> (# State# s, Int64# #) + +go8 :: Int8 +go8 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo8 mba s1 of + (# s2, n' #) -> (# s2, I8# n' #) + +go16 :: Int16 +go16 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo16 mba s1 of + (# s2, n' #) -> (# s2, I16# n' #) + +go32 :: Int32 +go32 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo32 mba s1 of + (# s2, n' #) -> (# s2, I32# n' #) + +go64 :: Int64 +go64 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo64 mba s1 of + (# s2, n' #) -> (# s2, I64# n' #) + +main = do + print go8 + print go16 + print go32 + print go64 ===================================== testsuite/tests/cmm/should_run/AtomicFetch.stdout ===================================== @@ -0,0 +1,4 @@ +-4 +-4 +-4 +-4 ===================================== testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm ===================================== @@ -0,0 +1,80 @@ +#include "Cmm.h" + +// This is not a test of atomic semantics, +// just checking that GHC can parse %fetch_fooXX + +cmm_foo64 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits64 x; + + prim %store_seqcst64(q, 42); + (x) = prim %fetch_add64(q, 5); + (x) = prim %fetch_sub64(q, 10); + (x) = prim %fetch_and64(q, 120); + (x) = prim %fetch_or64(q, 2); + (x) = prim %fetch_xor64(q, 33); + (x) = prim %fetch_nand64(q, 127); + (x) = prim %load_seqcst64(q); + return (x); +} + +cmm_foo32 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits32 x; + + prim %store_seqcst32(q, 42); + (x) = prim %fetch_add32(q, 5); + (x) = prim %fetch_sub32(q, 10); + (x) = prim %fetch_and32(q, 120); + (x) = prim %fetch_or32(q, 2); + (x) = prim %fetch_xor32(q, 33); + (x) = prim %fetch_nand32(q, 127); + (x) = prim %load_seqcst32(q); + return (x); +} + +cmm_foo16 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits16 x; + + prim %store_seqcst16(q, 42); + (x) = prim %fetch_add16(q, 5); + (x) = prim %fetch_sub16(q, 10); + (x) = prim %fetch_and16(q, 120); + (x) = prim %fetch_or16(q, 2); + (x) = prim %fetch_xor16(q, 33); + (x) = prim %fetch_nand16(q, 127); + (x) = prim %load_seqcst16(q); + return (x); +} + +cmm_foo8 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits8 x; + + prim %store_seqcst8(q, 42); + (x) = prim %fetch_add8(q, 5); + (x) = prim %fetch_sub8(q, 10); + (x) = prim %fetch_and8(q, 120); + (x) = prim %fetch_or8(q, 2); + (x) = prim %fetch_xor8(q, 33); + (x) = prim %fetch_nand8(q, 127); + (x) = prim %load_seqcst8(q); + return (x); +} ===================================== testsuite/tests/cmm/should_run/all.T ===================================== @@ -34,3 +34,12 @@ test('T22871', ], multi_compile_and_run, ['T22871', [('T22871_cmm.cmm', '')], '']) + +test('AtomicFetch', + [ extra_run_opts('"' + config.libdir + '"') + , omit_ways(['ghci']) + , req_cmm + , when(arch('i386'), skip) # https://gitlab.haskell.org/ghc/ghc/-/issues/23217 + ], + multi_compile_and_run, + ['AtomicFetch', [('AtomicFetch_cmm.cmm', '')], '']) ===================================== testsuite/tests/th/T10828.hs ===================================== @@ -6,7 +6,6 @@ module T10828 where import Language.Haskell.TH hiding (Type) import System.IO import Data.Kind (Type) -import qualified Data.List.NonEmpty as NE ( singleton ) $( do { decl <- [d| data family D a :: Type -> Type data instance D Int Bool :: Type where @@ -34,7 +33,7 @@ $( return [ DataD [] (mkName "T") [ PlainTV (mkName "a") () ] (Just StarT) - [ GadtC (NE.singleton (mkName "MkT")) + [ GadtC [mkName "MkT"] [ ( Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ) @@ -47,7 +46,7 @@ $( return , ForallC [PlainTV (mkName "a") SpecifiedSpec, PlainTV (mkName "b") SpecifiedSpec] [AppT (AppT EqualityT (VarT $ mkName "a" ) ) (ConT $ mkName "Int") ] $ - RecGadtC (NE.singleton (mkName "MkC")) + RecGadtC [mkName "MkC"] [ ( mkName "foo" , Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ===================================== testsuite/tests/th/T10828b.hs ===================================== @@ -4,7 +4,6 @@ module T10828b where import Language.Haskell.TH import System.IO -import qualified Data.List.NonEmpty as NE ( singleton ) -- attempting to mix GADT and normal constructors $( return @@ -24,7 +23,7 @@ $( return [AppT (AppT EqualityT (VarT $ mkName "a" ) ) (ConT $ mkName "Int") ] $ RecGadtC - (NE.singleton (mkName "MkC")) + [mkName "MkC"] [ ( mkName "foo" , Bang NoSourceUnpackedness NoSourceStrictness , VarT (mkName "a") ===================================== testsuite/tests/th/T10828b.stderr ===================================== @@ -1,5 +1,5 @@ -T10828b.hs:10:2: error: [GHC-24104] +T10828b.hs:9:2: error: [GHC-24104] Cannot mix GADT constructors with Haskell 98 constructors When splicing a TH declaration: data T a :: * ===================================== testsuite/tests/th/T11345.hs ===================================== @@ -5,7 +5,6 @@ module Main (main) where import Language.Haskell.TH -import qualified Data.List.NonEmpty as NE ( singleton ) infixr 7 :***: data GADT a where @@ -17,11 +16,11 @@ $(do gadtName <- newName "GADT2" infixName <- newName ":****:" a <- newName "a" return [ DataD [] gadtName [KindedTV a () StarT] Nothing - [ GadtC (NE.singleton prefixName) + [ GadtC [prefixName] [ (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) , (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) ] (AppT (ConT gadtName) (ConT ''Int)) - , GadtC (NE.singleton infixName) + , GadtC [infixName] [ (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) , (Bang NoSourceUnpackedness NoSourceStrictness,ConT ''Int) ] (AppT (ConT gadtName) (ConT ''Int)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5a91209581442d7f36121b72a5ca622d6035c950...815449c72ddf3b37b61db83f5f1e721e8a172e49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5a91209581442d7f36121b72a5ca622d6035c950...815449c72ddf3b37b61db83f5f1e721e8a172e49 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 21:20:00 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 02 Apr 2023 17:20:00 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Fix a boo boo Message-ID: <6429f180c0cb1_3483da739cfe00117999f@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 8a07526c by Simon Peyton Jones at 2023-04-02T22:21:29+01:00 Fix a boo boo - - - - - 1 changed file: - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1805,7 +1805,8 @@ uType_defer (UE { u_loc = loc, u_defer = ref, u_role = role }) ; whenDOptM Opt_D_dump_tc_trace $ do { ctxt <- getErrCtxt ; doc <- mkErrInfo emptyTidyEnv ctxt - ; traceTc "utype_defer" (vcat [ debugPprType ty1 + ; traceTc "utype_defer" (vcat [ ppr role + , debugPprType ty1 , debugPprType ty2 , doc]) ; traceTc "utype_defer2" (ppr co) } @@ -1824,7 +1825,7 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 = do { tclvl <- getTcLevel ; traceTc "u_tys" $ vcat [ text "tclvl" <+> ppr tclvl - , sep [ ppr orig_ty1, text "~", ppr orig_ty2] ] + , sep [ ppr orig_ty1, text "~" <> ppr role, ppr orig_ty2] ] ; co <- go orig_ty1 orig_ty2 ; if isReflCo co then traceTc "u_tys yields no coercion" Outputable.empty @@ -1854,14 +1855,15 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 = do { lookup_res <- isFilledMetaTyVar_maybe tv1 ; case lookup_res of Just ty1 -> do { traceTc "found filled tyvar" (ppr tv1 <+> text ":->" <+> ppr ty1) - ; go ty1 ty2 } - Nothing -> uUnfilledVar env NotSwapped tv1 ty2 } + ; uType env ty1 orig_ty2 } + Nothing -> uUnfilledVar env NotSwapped tv1 ty2 } + go ty1 (TyVarTy tv2) = do { lookup_res <- isFilledMetaTyVar_maybe tv2 ; case lookup_res of Just ty2 -> do { traceTc "found filled tyvar" (ppr tv2 <+> text ":->" <+> ppr ty2) - ; go ty1 ty2 } - Nothing -> uUnfilledVar env IsSwapped tv2 ty1 } + ; uType env orig_ty1 ty2 } + Nothing -> uUnfilledVar env IsSwapped tv2 ty1 } -- See Note [Expanding synonyms during unification] go ty1@(TyConApp tc1 []) (TyConApp tc2 []) @@ -1941,7 +1943,7 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 ------------------ defer ty1 ty2 -- See Note [Check for equality before deferring] | ty1 `tcEqType` ty2 = return (mkReflCo role ty1) - | otherwise = uType_defer env ty1 ty2 + | otherwise = uType_defer env orig_ty1 orig_ty2 ------------------ @@ -2066,15 +2068,23 @@ uUnfilledVar, uUnfilledVar1 -> TcM CoercionN -- "Unfilled" means that the variable is definitely not a filled-in meta tyvar -- It might be a skolem, or untouchable, or meta - +-- +-- Precondition: u_role env = Nominal uUnfilledVar env swapped tv1 ty2 - = do { ty2 <- zonkTcType ty2 -- Zonk to expose things to the - -- occurs check, and so that if ty2 - -- looks like a type variable then it + | Nominal <- u_role env + = do { ty2 <- zonkTcType ty2 -- Zonk to expose things to the occurs check, and so + -- that if ty2 looks like a type variable then it -- /is/ a type variable ; uUnfilledVar1 env swapped tv1 ty2 } -uUnfilledVar1 env@(UE { u_role = role }) swapped tv1 ty2 -- ty2 is zonked + | otherwise -- See Note [Do not unify representational equalities] + -- in GHC.Tc.Solver.Equality + = unSwap swapped (uType_defer env) (mkTyVarTy tv1) ty2 + +uUnfilledVar1 env -- u_role==Nominal + swapped + tv1 + ty2 -- ty2 is zonked | Just tv2 <- getTyVar_maybe ty2 = go tv2 @@ -2086,7 +2096,7 @@ uUnfilledVar1 env@(UE { u_role = role }) swapped tv1 ty2 -- ty2 is zonked -- tyvars so we might want to swap -- E.g. maybe tv2 is a meta-tyvar and tv1 is not go tv2 | tv1 == tv2 -- Same type variable => no-op - = return (mkReflCo role (mkTyVarTy tv1)) + = return (mkNomReflCo (mkTyVarTy tv1)) | swapOverTyVars False tv1 tv2 -- Distinct type variables -- Swap meta tyvar to the left if poss @@ -2107,7 +2117,7 @@ uUnfilledVar2 :: UnifyEnv -- definitely not a /filled/ meta-tyvar -> TcTauType -- Type 2, zonked -> TcM CoercionN -uUnfilledVar2 env@(UE { u_role = role }) swapped tv1 ty2 +uUnfilledVar2 env swapped tv1 ty2 = do { cur_lvl <- getTcLevel -- See Note [Unification preconditions], (UNTOUCHABLE) wrinkles -- Here we don't know about given equalities here; so we treat @@ -2127,7 +2137,7 @@ uUnfilledVar2 env@(UE { u_role = role }) swapped tv1 ty2 -- NB: tv1 should still be unfilled, despite the kind unification -- because tv1 is not free in ty2' (or, hence, in its kind) then do { writeMetaTyVar tv1 ty2 - ; return (mkReflCo role ty2) } + ; return (mkNomReflCo ty2) } else defer -- This cannot be solved now. See GHC.Tc.Solver.Canonical -- Note [Equalities with incompatible kinds] for how View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a07526caf34c77e528c805eeed918a693fdaac6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a07526caf34c77e528c805eeed918a693fdaac6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 21:49:38 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 02 Apr 2023 17:49:38 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Fix another error: missing kick-out Message-ID: <6429f87244fd5_3483da742373e01180232@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: aec52b60 by Simon Peyton Jones at 2023-04-02T22:51:05+01:00 Fix another error: missing kick-out - - - - - 2 changed files: - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -1955,15 +1955,26 @@ unifyWanted :: RewriterSet -> CtLoc -- The returned coercion's role matches the input parameter unifyWanted _rewriters loc role ty1 ty2 - = do { (co,cts) <- wrapTcS $ - do { ref <- TcM.newTcRef [] + = do { (co, unified, cts) <- wrapTcS $ + do { defer_ref <- TcM.newTcRef [] + ; unified_ref <- TcM.newTcRef [] ; let env = UE { u_role = role , u_loc = loc - , u_defer = ref } + , u_defer = defer_ref + , u_unified = Just unified_ref} ; co <- uType env ty1 ty2 - ; cts <- TcM.readTcRef ref - ; return (co, cts) } + ; cts <- TcM.readTcRef defer_ref + ; unified <- TcM.readTcRef unified_ref + ; return (co, unified, cts) } + + -- Emit the deferred constraints ; updWorkListTcS (extendWorkListEqs cts) + + -- And kick out any inert constraint that we have unified + -- ToDo: treating the tyvars together might + -- be more efficient than one by one + ; mapM_ kickOutAfterUnification unified + ; return co } {- ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1745,7 +1745,8 @@ uTypeAndEmit :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM CoercionN uTypeAndEmit t_or_k orig ty1 ty2 = do { ref <- newTcRef [] ; loc <- getCtLocM orig (Just t_or_k) - ; let env = UE { u_loc = loc, u_role = Nominal, u_defer = ref } + ; let env = UE { u_loc = loc, u_role = Nominal + , u_defer = ref, u_unified = Nothing } -- The hard work happens here ; co <- uType env ty1 ty2 @@ -1765,9 +1766,15 @@ uType is the heart of the unifier. -} data UnifyEnv - = UE { u_role :: Role - , u_loc :: CtLoc - , u_defer :: TcRef [Ct] } + = UE { u_role :: Role + , u_loc :: CtLoc + + , u_defer :: TcRef [Ct] + -- Deferred constraints + + , u_unified :: Maybe (TcRef [TcTyVar]) + -- If Just, track unified type variables + } mkKindEnv :: UnifyEnv -> TcType -> TcType -> UnifyEnv -- Modify the UnifyEnv to be right for unifing @@ -2137,7 +2144,10 @@ uUnfilledVar2 env swapped tv1 ty2 -- NB: tv1 should still be unfilled, despite the kind unification -- because tv1 is not free in ty2' (or, hence, in its kind) then do { writeMetaTyVar tv1 ty2 - ; return (mkNomReflCo ty2) } + ; case u_unified env of + Nothing -> return () + Just uref -> updTcRef uref (tv1 :) + ; return (mkNomReflCo ty2) } -- Unification is always Nominal else defer -- This cannot be solved now. See GHC.Tc.Solver.Canonical -- Note [Equalities with incompatible kinds] for how View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aec52b60ff62c9faf71f46f1a17d36f7a0f72e9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aec52b60ff62c9faf71f46f1a17d36f7a0f72e9d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 22:59:45 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 02 Apr 2023 18:59:45 -0400 Subject: [Git][ghc/ghc][master] Rework documentation for data Char Message-ID: <642a08e17c370_3483da7529f5341188179@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 1 changed file: - libraries/ghc-prim/GHC/Types.hs Changes: ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -202,17 +202,96 @@ data Ordering = LT | EQ | GT * * ********************************************************************* -} -{- | The character type 'Char' is an enumeration whose values represent -Unicode (or equivalently ISO\/IEC 10646) code points (i.e. characters, see - for details). This set extends the ISO 8859-1 -(Latin-1) character set (the first 256 characters), which is itself an extension -of the ASCII character set (the first 128 characters). A character literal in -Haskell has type 'Char'. - -To convert a 'Char' to or from the corresponding 'Int' value defined -by Unicode, use 'Prelude.toEnum' and 'Prelude.fromEnum' from the -'Prelude.Enum' class respectively (or equivalently 'Data.Char.ord' and -'Data.Char.chr'). +{- | The character type 'Char' represents Unicode codespace +and its elements are code points as in definitions +[D9 and D10 of the Unicode Standard](https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf#G2212). + +Character literals in Haskell are single-quoted: @\'Q\'@, @\'Я\'@ or @\'Ω\'@. +To represent a single quote itself use @\'\\''@, and to represent a backslash +use @\'\\\\\'@. The full grammar can be found in the section 2.6 of the +[Haskell 2010 Language Report](https://www.haskell.org/definition/haskell2010.pdf#section.2.6). + +To specify a character by its code point one can use decimal, hexadecimal +or octal notation: @\'\\65\'@, @\'\\x41\'@ and @\'\\o101\'@ are all alternative forms +of @\'A\'@. The largest code point is @\'\\x10ffff\'@. + +There is a special escape syntax for ASCII control characters: + ++-------------+-------------------+---------------------------+ +| Escape | Alternatives | Meaning | ++=============+===================+===========================+ +| @'\\NUL'@ | @'\\0'@ | null character | ++-------------+-------------------+---------------------------+ +| @'\\SOH'@ | @'\\1'@ | start of heading | ++-------------+-------------------+---------------------------+ +| @'\\STX'@ | @'\\2'@ | start of text | ++-------------+-------------------+---------------------------+ +| @'\\ETX'@ | @'\\3'@ | end of text | ++-------------+-------------------+---------------------------+ +| @'\\EOT'@ | @'\\4'@ | end of transmission | ++-------------+-------------------+---------------------------+ +| @'\\ENQ'@ | @'\\5'@ | enquiry | ++-------------+-------------------+---------------------------+ +| @'\\ACK'@ | @'\\6'@ | acknowledge | ++-------------+-------------------+---------------------------+ +| @'\\BEL'@ | @'\\7'@, @'\\a'@ | bell (alert) | ++-------------+-------------------+---------------------------+ +| @'\\BS'@ | @'\\8'@, @'\\b'@ | backspace | ++-------------+-------------------+---------------------------+ +| @'\\HT'@ | @'\\9'@, @'\\t'@ | horizontal tab | ++-------------+-------------------+---------------------------+ +| @'\\LF'@ | @'\\10'@, @'\\n'@ | line feed (new line) | ++-------------+-------------------+---------------------------+ +| @'\\VT'@ | @'\\11'@, @'\\v'@ | vertical tab | ++-------------+-------------------+---------------------------+ +| @'\\FF'@ | @'\\12'@, @'\\f'@ | form feed | ++-------------+-------------------+---------------------------+ +| @'\\CR'@ | @'\\13'@, @'\\r'@ | carriage return | ++-------------+-------------------+---------------------------+ +| @'\\SO'@ | @'\\14'@ | shift out | ++-------------+-------------------+---------------------------+ +| @'\\SI'@ | @'\\15'@ | shift in | ++-------------+-------------------+---------------------------+ +| @'\\DLE'@ | @'\\16'@ | data link escape | ++-------------+-------------------+---------------------------+ +| @'\\DC1'@ | @'\\17'@ | device control 1 | ++-------------+-------------------+---------------------------+ +| @'\\DC2'@ | @'\\18'@ | device control 2 | ++-------------+-------------------+---------------------------+ +| @'\\DC3'@ | @'\\19'@ | device control 3 | ++-------------+-------------------+---------------------------+ +| @'\\DC4'@ | @'\\20'@ | device control 4 | ++-------------+-------------------+---------------------------+ +| @'\\NAK'@ | @'\\21'@ | negative acknowledge | ++-------------+-------------------+---------------------------+ +| @'\\SYN'@ | @'\\22'@ | synchronous idle | ++-------------+-------------------+---------------------------+ +| @'\\ETB'@ | @'\\23'@ | end of transmission block | ++-------------+-------------------+---------------------------+ +| @'\\CAN'@ | @'\\24'@ | cancel | ++-------------+-------------------+---------------------------+ +| @'\\EM'@ | @'\\25'@ | end of medium | ++-------------+-------------------+---------------------------+ +| @'\\SUB'@ | @'\\26'@ | substitute | ++-------------+-------------------+---------------------------+ +| @'\\ESC'@ | @'\\27'@ | escape | ++-------------+-------------------+---------------------------+ +| @'\\FS'@ | @'\\28'@ | file separator | ++-------------+-------------------+---------------------------+ +| @'\\GS'@ | @'\\29'@ | group separator | ++-------------+-------------------+---------------------------+ +| @'\\RS'@ | @'\\30'@ | record separator | ++-------------+-------------------+---------------------------+ +| @'\\US'@ | @'\\31'@ | unit separator | ++-------------+-------------------+---------------------------+ +| @'\\SP'@ | @'\\32'@, @' '@ | space | ++-------------+-------------------+---------------------------+ +| @'\\DEL'@ | @'\\127'@ | delete | ++-------------+-------------------+---------------------------+ + +[Data.Char](https://hackage.haskell.org/package/base/docs/Data-Char.html) +provides utilities to work with 'Char'. + -} data {-# CTYPE "HsChar" #-} Char = C# Char# View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f60f6110c1d08cb1885dce1984d5051de03dce8e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f60f6110c1d08cb1885dce1984d5051de03dce8e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 2 23:00:27 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 02 Apr 2023 19:00:27 -0400 Subject: [Git][ghc/ghc][master] cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Message-ID: <642a090b88851_3483da7529f53411935fd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - 5 changed files: - compiler/GHC/Cmm/Parser.y - + testsuite/tests/cmm/should_run/AtomicFetch.hs - + testsuite/tests/cmm/should_run/AtomicFetch.stdout - + testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm - testsuite/tests/cmm/should_run/all.T Changes: ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1137,6 +1137,12 @@ callishMachOps platform = listToUFM $ , allWidths "load_seqcst" (\w -> MO_AtomicRead w MemOrderSeqCst) , allWidths "store_release" (\w -> MO_AtomicWrite w MemOrderRelease) , allWidths "store_seqcst" (\w -> MO_AtomicWrite w MemOrderSeqCst) + , allWidths "fetch_add" (\w -> MO_AtomicRMW w AMO_Add) + , allWidths "fetch_sub" (\w -> MO_AtomicRMW w AMO_Sub) + , allWidths "fetch_and" (\w -> MO_AtomicRMW w AMO_And) + , allWidths "fetch_nand" (\w -> MO_AtomicRMW w AMO_Nand) + , allWidths "fetch_or" (\w -> MO_AtomicRMW w AMO_Or) + , allWidths "fetch_xor" (\w -> MO_AtomicRMW w AMO_Xor) ] where allWidths ===================================== testsuite/tests/cmm/should_run/AtomicFetch.hs ===================================== @@ -0,0 +1,54 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedFFITypes #-} + +-- This is not a test of atomic semantics, +-- just checking that GHC can parse %fetch_fooXX + +import GHC.Exts +import GHC.Int +import GHC.ST + +foreign import prim "cmm_foo8" cmm_foo8 + :: MutableByteArray# s -> State# s -> (# State# s, Int8# #) + +foreign import prim "cmm_foo16" cmm_foo16 + :: MutableByteArray# s -> State# s -> (# State# s, Int16# #) + +foreign import prim "cmm_foo32" cmm_foo32 + :: MutableByteArray# s -> State# s -> (# State# s, Int32# #) + +foreign import prim "cmm_foo64" cmm_foo64 + :: MutableByteArray# s -> State# s -> (# State# s, Int64# #) + +go8 :: Int8 +go8 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo8 mba s1 of + (# s2, n' #) -> (# s2, I8# n' #) + +go16 :: Int16 +go16 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo16 mba s1 of + (# s2, n' #) -> (# s2, I16# n' #) + +go32 :: Int32 +go32 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo32 mba s1 of + (# s2, n' #) -> (# s2, I32# n' #) + +go64 :: Int64 +go64 = runST $ ST $ \s0 -> + case newByteArray# 8# s0 of + (# s1, mba #) -> case cmm_foo64 mba s1 of + (# s2, n' #) -> (# s2, I64# n' #) + +main = do + print go8 + print go16 + print go32 + print go64 ===================================== testsuite/tests/cmm/should_run/AtomicFetch.stdout ===================================== @@ -0,0 +1,4 @@ +-4 +-4 +-4 +-4 ===================================== testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm ===================================== @@ -0,0 +1,80 @@ +#include "Cmm.h" + +// This is not a test of atomic semantics, +// just checking that GHC can parse %fetch_fooXX + +cmm_foo64 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits64 x; + + prim %store_seqcst64(q, 42); + (x) = prim %fetch_add64(q, 5); + (x) = prim %fetch_sub64(q, 10); + (x) = prim %fetch_and64(q, 120); + (x) = prim %fetch_or64(q, 2); + (x) = prim %fetch_xor64(q, 33); + (x) = prim %fetch_nand64(q, 127); + (x) = prim %load_seqcst64(q); + return (x); +} + +cmm_foo32 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits32 x; + + prim %store_seqcst32(q, 42); + (x) = prim %fetch_add32(q, 5); + (x) = prim %fetch_sub32(q, 10); + (x) = prim %fetch_and32(q, 120); + (x) = prim %fetch_or32(q, 2); + (x) = prim %fetch_xor32(q, 33); + (x) = prim %fetch_nand32(q, 127); + (x) = prim %load_seqcst32(q); + return (x); +} + +cmm_foo16 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits16 x; + + prim %store_seqcst16(q, 42); + (x) = prim %fetch_add16(q, 5); + (x) = prim %fetch_sub16(q, 10); + (x) = prim %fetch_and16(q, 120); + (x) = prim %fetch_or16(q, 2); + (x) = prim %fetch_xor16(q, 33); + (x) = prim %fetch_nand16(q, 127); + (x) = prim %load_seqcst16(q); + return (x); +} + +cmm_foo8 (P_ p) +{ + // p points to a ByteArray header, q points to its first element + P_ q; + q = p + SIZEOF_StgHeader + WDS(1); + + bits8 x; + + prim %store_seqcst8(q, 42); + (x) = prim %fetch_add8(q, 5); + (x) = prim %fetch_sub8(q, 10); + (x) = prim %fetch_and8(q, 120); + (x) = prim %fetch_or8(q, 2); + (x) = prim %fetch_xor8(q, 33); + (x) = prim %fetch_nand8(q, 127); + (x) = prim %load_seqcst8(q); + return (x); +} ===================================== testsuite/tests/cmm/should_run/all.T ===================================== @@ -34,3 +34,12 @@ test('T22871', ], multi_compile_and_run, ['T22871', [('T22871_cmm.cmm', '')], '']) + +test('AtomicFetch', + [ extra_run_opts('"' + config.libdir + '"') + , omit_ways(['ghci']) + , req_cmm + , when(arch('i386'), skip) # https://gitlab.haskell.org/ghc/ghc/-/issues/23217 + ], + multi_compile_and_run, + ['AtomicFetch', [('AtomicFetch_cmm.cmm', '')], '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43ebd5dcdb7ff65b6afccbdee22d2c27f9df6b1c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/43ebd5dcdb7ff65b6afccbdee22d2c27f9df6b1c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 05:31:23 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 03 Apr 2023 01:31:23 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Better assertion message Message-ID: <642a64abe604b_3483da7bcf09ec12041b8@gitlab.mail> Spam detection software, running on the system "mail.haskell.org", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 57bd525c by Sven Tennie at 2023-04-03T05:31:05+00:00 Better assertion message - - - - - [...] Content analysis details: (6.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 1.1 URI_HEX URI: URI hostname has long hexadecimal sequence 5.0 UNWANTED_LANGUAGE_BODY BODY: Message written in an undesired language 0.0 HTML_MESSAGE BODY: HTML included in message 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% [score: 0.5000] 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid The original message was not completely plain text, and may be unsafe to open with some email clients; in particular, it may contain a virus, or confirm that your address can receive spam. If you wish to view it, it may be safer to save it to a file and open it with an editor. -------------- next part -------------- An embedded message was scrubbed... From: "Sven Tennie (@supersven)" Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Better assertion message Date: Mon, 03 Apr 2023 01:31:23 -0400 Size: 19966 URL: From gitlab at gitlab.haskell.org Mon Apr 3 09:05:21 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 05:05:21 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Rework documentation for data Char Message-ID: <642a96d182827_3483da7fa49be0123893@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - 65f9cd64 by Sylvain Henry at 2023-04-03T05:05:03-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - c8e53747 by Matthew Pickering at 2023-04-03T05:05:03-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - 2ffd25ff by Matthew Pickering at 2023-04-03T05:05:03-04:00 ci: Add job to test 9.6 bootstrapping - - - - - d6f47868 by Krzysztof Gogolewski at 2023-04-03T05:05:04-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - 56016fd9 by Sylvain Henry at 2023-04-03T05:05:15-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 7 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/Parser.y - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json - hadrian/bootstrap/plan-9_2_4.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/815449c72ddf3b37b61db83f5f1e721e8a172e49...56016fd980f5286b484f110711dcc2ba550d4d2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/815449c72ddf3b37b61db83f5f1e721e8a172e49...56016fd980f5286b484f110711dcc2ba550d4d2e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 09:23:17 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 03 Apr 2023 05:23:17 -0400 Subject: [Git][ghc/ghc][wip/T23083] 4 commits: Core.Ppr: Omit case binder for empty case alternatives Message-ID: <642a9b05a271c_11425fda55c16184@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: e04ec8f5 by Sebastian Graf at 2023-04-03T11:16:25+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - 18578d31 by Sebastian Graf at 2023-04-03T11:19:33+02:00 exprIsTrivial: Factor out shared implementation and introduce TrivialExpr The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` (along with its lacking check that the returned Var is indeed an Id) has been bugging me for a long time. This patch introduces a inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe TrivialExpr`, so when it is inlined, it fuses to similar code as before. This allows us to export a generalisation of `getIdFromTrivialExpr_maybe` that returns any `TrivialExpr` I dubbed `trivialExpr[_maybe]`. It will be of use in !10088 during CoreToStg, where we want to look into scrutinees of empty case alternatives and thus is ultimately part of #23083. - - - - - 105494e0 by Sebastian Graf at 2023-04-03T11:19:54+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 26ff3536 by Sebastian Graf at 2023-04-03T11:21:42+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - testsuite/tests/corelint/T21115b.stderr - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/simplCore/should_compile/T13143.stderr - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/T9400.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0bcf3702b2c5a701525b3a0e95ca8213e6e1d52...26ff3536bf7de746899a5a5de9cfb0295227bfba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0bcf3702b2c5a701525b3a0e95ca8213e6e1d52...26ff3536bf7de746899a5a5de9cfb0295227bfba You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 11:16:41 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 03 Apr 2023 07:16:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23113 Message-ID: <642ab599af61e_11425f21db648421d8@gitlab.mail> Sebastian Graf pushed new branch wip/T23113 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23113 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 11:23:29 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 03 Apr 2023 07:23:29 -0400 Subject: [Git][ghc/ghc][wip/T23113] WorkWrap: Relax "splitFun" warning for join points (#23113) Message-ID: <642ab73171157_11425f22e63d0561ad@gitlab.mail> Sebastian Graf pushed to branch wip/T23113 at Glasgow Haskell Compiler / GHC Commits: 08bf6a65 by Sebastian Graf at 2023-04-03T13:23:24+02:00 WorkWrap: Relax "splitFun" warning for join points (#23113) ... and document our ponderings in `Note [Threshold arity for join points]`. I also introduced a new warning in `finaliseArgBoxities` to see where we currently are a bit too optimistic wrt. boxity. Fixes #23113 - - - - - 3 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Types/Demand.hs Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -1940,6 +1940,12 @@ finaliseArgBoxities env fn threshold_arity rhs_dmds div rhs -- vcat [text "function:" <+> ppr fn -- , text "dmds before:" <+> ppr (map idDemandInfo (filter isId bndrs)) -- , text "dmds after: " <+> ppr arg_dmds' ]) $ + warnPprTrace (isJoinId fn && length rhs_dmds > threshold_arity) + "finaliseArgBoxities: excess rhs_dmds of join point" + (ppr fn <+> ppr threshold_arity <+> ppr rhs_dmds) $ + -- It is far from clear that it's OK to ignore excess rhs_dmds + -- here rather than zap all boxity. Hence we warn to collect + -- some examples. See Note [Threshold arity of join points] (arg_dmds', set_lam_dmds arg_dmds' rhs) -- set_lam_dmds: we must attach the final boxities to the lambda-binders -- of the function, both because that's kosher, and because CPR analysis ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -758,9 +758,11 @@ by LitRubbish (see Note [Drop absent bindings]) so there is no great harm. splitFun :: WwOpts -> Id -> CoreExpr -> UniqSM [(Id, CoreExpr)] splitFun ww_opts fn_id rhs | Just (arg_vars, body) <- collectNValBinders_maybe (length wrap_dmds) rhs - = warnPprTrace (not (wrap_dmds `lengthIs` (arityInfo fn_info))) + = warnPprTrace (if isJoinId fn_id + then not (arg_vars `lengthAtMost` idJoinArity fn_id) -- See Note [Threshold arity of join points] + else not (wrap_dmds `lengthIs` (arityInfo fn_info))) "splitFun" - (ppr fn_id <+> (ppr wrap_dmds $$ ppr cpr)) $ + (sep [ ppr fn_id, ppr (arityInfo fn_info), ppr wrap_dmds, ppr cpr]) $ do { mb_stuff <- mkWwBodies ww_opts fn_id arg_vars (exprType body) wrap_dmds cpr ; case mb_stuff of Nothing -> -- No useful wrapper; leave the binding alone ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -2143,6 +2143,74 @@ type's depth! So in mkDmdSigForArity we make sure to trim the list of argument demands to the given threshold arity. Call sites will make sure that this corresponds to the arity of the call demand that elicited the wrapped demand type. See also Note [What are demand signatures?]. + +See also Note [Threshold arity of join points] for how the threshold arity of +join points is special. + +Note [Threshold arity of join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The threshold arity in the demand signature of a join point might be + + * Less than `idArity`: + join j x = \pqr. blah in ...(jump j 1)... (jump j 2)... + Here idArity is 4, but join-arity is 1. + * More than `idArity`: + f g = g 42 :: + h x = f (join j y = (+) y in ... j 13 ...) + Note that f's demand on its arg must apply is put on the join expr and hence + its RHS. + How this is achieved is described in Note [Demand Analysis for join points]. + In this Note, we refer to it as the know-context assumption. + +The latter example is interesting, because there analysis ends up with a demand +/type/ of <1!L><1!L> for the RHS of the `j`, based on the arity 2 signature of +`(+)`. + +Why trim down demand signatures? +-------------------------------- +When we finalise the demand /signature/ for `j`, we have to trim this signature +to have a depth (number of arg dmds) of 1. + +The reason for that is a tension between the most precise demand signature +possible (<1L><1L>) and its piggy-backed /boxity/ signature (). The latter +is relevant to WW and if we keep length 2, WW would end up eta-expanding `j` for +arity 2, destroying its joinpointhood. + +So `finaliseArgBoxities` will instead drop one arg, but /keep the boxity info +on it/. The former is sound because demand analysis knows that `j` will always +be called with 2 arguments anyway, but the latter may introduce reboxing for `j` +above if we don't inline `(+)` (which presumably we'll do only for arity 2): + join j y = case y of I# y# -> $wj y# + $wj y# = (+) (I# y#) + in ... +Note the reboxing in $wj. On the other hand, all reboxing would +vanish if we inlined `(+)`, so for now we simply emit a warning in +GHC.Core.Opt.WorkWrap.splitFun to collect examples when such a potentially +undesirable split happens. + +Undesirable consequence of trimming +----------------------------------- +The final demand signature for `j` above is `<1L>` (nevermind boxity here), but +the *correct* threshold arity is still that of the original demand type, +namely 2. So we violate the coupling of arg dmds and threshold arity in demand +signatures we so painfully stated in Note [Understanding DmdType and DmdSig]. + +It would be unsound to unleash the signature in an arity 1 call context such as +`Just (j x)`, for example. Nevertheless, because `j` is a join point, all its +call contexts are fixed and won't change unless the demand on the whole join +expression changes, so every practical use of the signature is sound even for +arity 1 (all calls of syntactic arity 1 will ultimately be a call with arity 2). + +BUT, certain transformations can destroy the known-context assumption. For +example, when we demote `j` to a let binding and realise that its RHS does not +reference `x`, we might be tempted to float it to the top-level. If we do so, +we should be sure to discard its demand signature, because there is nothing +preventing to e.g., CSE two calls `j 13` and/or perform it repeatedly. + +FloatOut will actually float join points to top-level but is unconcerned about +this issue. Fortunately, Demand Analysis runs after FloatOut, so this has not +become an issue in practice; still, it is worth keeping an eye out for and at +least documenting this potential issue. -} -- | The depth of the wrapped 'DmdType' encodes the arity at which it is safe View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/08bf6a65c355cc18bfcb754a8331d70de3a9e505 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/08bf6a65c355cc18bfcb754a8331d70de3a9e505 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 12:07:24 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 03 Apr 2023 08:07:24 -0400 Subject: [Git][ghc/ghc][wip/T23113] WorkWrap: Relax "splitFun" warning for join points (#23113) Message-ID: <642ac17c452a4_11425f31c1990643da@gitlab.mail> Sebastian Graf pushed to branch wip/T23113 at Glasgow Haskell Compiler / GHC Commits: 0317038c by Sebastian Graf at 2023-04-03T14:07:10+02:00 WorkWrap: Relax "splitFun" warning for join points (#23113) ... and document our ponderings in `Note [Threshold arity for join points]`. I also introduced a new warning in `finaliseArgBoxities` to see where we currently are a bit too optimistic wrt. boxity. Fixes #23113 - - - - - 3 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Types/Demand.hs Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -1940,6 +1940,12 @@ finaliseArgBoxities env fn threshold_arity rhs_dmds div rhs -- vcat [text "function:" <+> ppr fn -- , text "dmds before:" <+> ppr (map idDemandInfo (filter isId bndrs)) -- , text "dmds after: " <+> ppr arg_dmds' ]) $ + warnPprTrace (isJoinId fn && length rhs_dmds > threshold_arity) + "finaliseArgBoxities: excess rhs_dmds of join point" + (ppr fn <+> ppr threshold_arity <+> ppr rhs_dmds) $ + -- It is far from clear that it's OK to ignore excess rhs_dmds + -- here rather than zap all boxity. Hence we warn to collect + -- some examples. See Note [Threshold arity of join points] (arg_dmds', set_lam_dmds arg_dmds' rhs) -- set_lam_dmds: we must attach the final boxities to the lambda-binders -- of the function, both because that's kosher, and because CPR analysis ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -758,9 +758,11 @@ by LitRubbish (see Note [Drop absent bindings]) so there is no great harm. splitFun :: WwOpts -> Id -> CoreExpr -> UniqSM [(Id, CoreExpr)] splitFun ww_opts fn_id rhs | Just (arg_vars, body) <- collectNValBinders_maybe (length wrap_dmds) rhs - = warnPprTrace (not (wrap_dmds `lengthIs` (arityInfo fn_info))) + = warnPprTrace (if isJoinId fn_id + then not (arg_vars `lengthAtMost` idJoinArity fn_id) -- See Note [Threshold arity of join points] + else not (wrap_dmds `lengthIs` (arityInfo fn_info))) "splitFun" - (ppr fn_id <+> (ppr wrap_dmds $$ ppr cpr)) $ + (sep [ ppr fn_id, ppr (arityInfo fn_info), ppr wrap_dmds, ppr cpr]) $ do { mb_stuff <- mkWwBodies ww_opts fn_id arg_vars (exprType body) wrap_dmds cpr ; case mb_stuff of Nothing -> -- No useful wrapper; leave the binding alone ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -2143,6 +2143,74 @@ type's depth! So in mkDmdSigForArity we make sure to trim the list of argument demands to the given threshold arity. Call sites will make sure that this corresponds to the arity of the call demand that elicited the wrapped demand type. See also Note [What are demand signatures?]. + +See also Note [Threshold arity of join points] for how the threshold arity of +join points is special. + +Note [Threshold arity of join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The threshold arity in the demand signature of a join point might be + + * Less than `idArity`: + join j x = \pqr. blah in ...(jump j 1)... (jump j 2)... + Here idArity is 4, but join-arity is 1. + * More than `idArity`: + f g = g 42 :: + h x = f (join j y = (+) y in ... j 13 ...) + Note that f's demand on its arg must apply is put on the join expr and hence + its RHS. + How this is achieved is described in Note [Demand analysis for join points]. + In this Note, we refer to it as the know-context assumption. + +The latter example is interesting, because there analysis ends up with a demand +/type/ of <1!L><1!L> for the RHS of the `j`, based on the arity 2 signature of +`(+)`. + +Why trim down demand signatures? +-------------------------------- +When we finalise the demand /signature/ for `j`, we have to trim this signature +to have a depth (number of arg dmds) of 1. + +The reason for that is a tension between the most precise demand signature +possible (<1L><1L>) and its piggy-backed /boxity/ signature (). The latter +is relevant to WW and if we keep length 2, WW would end up eta-expanding `j` for +arity 2, destroying its joinpointhood. + +So `finaliseArgBoxities` will instead drop one arg, but /keep the boxity info +on it/. The former is sound because demand analysis knows that `j` will always +be called with 2 arguments anyway, but the latter may introduce reboxing for `j` +above if we don't inline `(+)` (which presumably we'll do only for arity 2): + join j y = case y of I# y# -> $wj y# + $wj y# = (+) (I# y#) + in ... +Note the reboxing in $wj. On the other hand, all reboxing would +vanish if we inlined `(+)`, so for now we simply emit a warning in +GHC.Core.Opt.WorkWrap.splitFun to collect examples when such a potentially +undesirable split happens. + +Undesirable consequence of trimming +----------------------------------- +The final demand signature for `j` above is `<1L>` (nevermind boxity here), but +the *correct* threshold arity is still that of the original demand type, +namely 2. So we violate the coupling of arg dmds and threshold arity in demand +signatures we so painfully stated in Note [Understanding DmdType and DmdSig]. + +It would be unsound to unleash the signature in an arity 1 call context such as +`Just (j x)`, for example. Nevertheless, because `j` is a join point, all its +call contexts are fixed and won't change unless the demand on the whole join +expression changes, so every practical use of the signature is sound even for +arity 1 (all calls of syntactic arity 1 will ultimately be a call with arity 2). + +BUT, certain transformations can destroy the known-context assumption. For +example, when we demote `j` to a let binding and realise that its RHS does not +reference `x`, we might be tempted to float it to the top-level. If we do so, +we should be sure to discard its demand signature, because there is nothing +preventing to e.g., CSE two calls `j 13` and/or perform it repeatedly. + +FloatOut will actually float join points to top-level but is unconcerned about +this issue. Fortunately, Demand Analysis runs after FloatOut, so this has not +become an issue in practice; still, it is worth keeping an eye out for and at +least documenting this potential issue. -} -- | The depth of the wrapped 'DmdType' encodes the arity at which it is safe View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0317038c1013ef91b67f0897d28dfce946931fb7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0317038c1013ef91b67f0897d28dfce946931fb7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 12:15:45 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 08:15:45 -0400 Subject: [Git][ghc/ghc][master] ghc-heap: remove wrong Addr# coercion (#23181) Message-ID: <642ac371dc668_11425f338772067893@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 3 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/tests/heap_all.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -120,7 +120,7 @@ instance Word64# ~ a => HasHeapRep (a :: TYPE 'Word64Rep) where instance Addr# ~ a => HasHeapRep (a :: TYPE 'AddrRep) where getClosureData x = return $ - AddrClosure { ptipe = PAddr, addrVal = I# (unsafeCoerce# x) } + AddrClosure { ptipe = PAddr, addrVal = Ptr x } instance Float# ~ a => HasHeapRep (a :: TYPE 'FloatRep) where getClosureData x = return $ ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -329,7 +329,7 @@ data GenClosure b -- | Primitive Addr | AddrClosure { ptipe :: PrimType - , addrVal :: !Int } + , addrVal :: !(Ptr ()) } -- | Primitive Float | FloatClosure ===================================== libraries/ghc-heap/tests/heap_all.hs ===================================== @@ -12,6 +12,7 @@ import GHC.Int import GHC.IO import GHC.IORef import GHC.MVar +import GHC.Ptr import GHC.Stack import GHC.STRef import GHC.Weak @@ -176,7 +177,7 @@ exWord64Closure = Word64Closure exAddrClosure :: Closure exAddrClosure = AddrClosure - { ptipe = PAddr, addrVal = 42 } + { ptipe = PAddr, addrVal = nullPtr `plusPtr` 42 } exFloatClosure :: Closure exFloatClosure = FloatClosure @@ -328,7 +329,7 @@ main = do -- assertClosuresEq exWord64Closure -- Primitive Addr - let v = unsafeCoerce# 42# :: Addr# + let (Ptr v) = nullPtr `plusPtr` 42 getClosureData v >>= assertClosuresEq exAddrClosure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab9cd52d4fac34a2b37ce07bc9e9e2943c92d181 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab9cd52d4fac34a2b37ce07bc9e9e2943c92d181 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 12:16:23 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 08:16:23 -0400 Subject: [Git][ghc/ghc][master] 2 commits: hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Message-ID: <642ac3972abe0_11425f34fed88727da@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 6 changed files: - .gitlab-ci.yml - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json - hadrian/bootstrap/plan-9_2_4.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab9cd52d4fac34a2b37ce07bc9e9e2943c92d181...c2605e25bb166245310a13386e7f77915e9c2c3f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ab9cd52d4fac34a2b37ce07bc9e9e2943c92d181...c2605e25bb166245310a13386e7f77915e9c2c3f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 12:16:53 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 08:16:53 -0400 Subject: [Git][ghc/ghc][master] hadrian: Improve option parsing Message-ID: <642ac3b5323bb_11425f37afd8476161@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - 1 changed file: - hadrian/src/CommandLine.hs Changes: ===================================== hadrian/src/CommandLine.hs ===================================== @@ -127,32 +127,26 @@ readBignum (Just ms) = Right $ \flags -> case break (== '-') (lower ms) of ("check",'-':backend) -> flags { bignum = Just backend, bignumCheck = True } _ -> flags { bignum = Just (lower ms) } -readBuildRoot :: Maybe FilePath -> Either String (CommandLineArgs -> CommandLineArgs) +readBuildRoot :: FilePath -> Either String (CommandLineArgs -> CommandLineArgs) readBuildRoot ms = - maybe (Left "Cannot parse build-root") (Right . set) (go =<< ms) - where - go :: String -> Maybe BuildRoot - go = Just . BuildRoot - set :: BuildRoot -> CommandLineArgs -> CommandLineArgs - set flag flags = flags { buildRoot = flag } + Right $ \flags -> flags { buildRoot = BuildRoot ms } readFreeze1, readFreeze2, readSkipDepends :: Either String (CommandLineArgs -> CommandLineArgs) readFreeze1 = Right $ \flags -> flags { freeze1 = True } readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True } readSkipDepends = Right $ \flags -> flags { skipDepends = True } -readProgressInfo :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) +readProgressInfo :: String -> Either String (CommandLineArgs -> CommandLineArgs) readProgressInfo ms = - maybe (Left "Cannot parse progress-info") (Right . set) (go =<< lower <$> ms) + case lower ms of + "none" -> set None + "brief" -> set Brief + "normal" -> set Normal + "unicorn" -> set Unicorn + _ -> Left "Cannot parse progress-info" where - go :: String -> Maybe ProgressInfo - go "none" = Just None - go "brief" = Just Brief - go "normal" = Just Normal - go "unicorn" = Just Unicorn - go _ = Nothing - set :: ProgressInfo -> CommandLineArgs -> CommandLineArgs - set flag flags = flags { progressInfo = flag } + set :: ProgressInfo -> Either String (CommandLineArgs -> CommandLineArgs) + set flag = Right $ \flags -> flags { progressInfo = flag } readTestKeepFiles :: Either String (CommandLineArgs -> CommandLineArgs) readTestKeepFiles = Right $ \flags -> flags { testArgs = (testArgs flags) { testKeepFiles = True } } @@ -163,24 +157,16 @@ readTestAccept = Right $ \flags -> flags { testArgs = (testArgs flags) { testAcc readTestHasInTreeFiles :: Either String (CommandLineArgs -> CommandLineArgs) readTestHasInTreeFiles = Right $ \flags -> flags { testArgs = (testArgs flags) { testHasInTreeFiles = True } } -readTestCompiler :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) -readTestCompiler compiler = maybe (Left "Cannot parse compiler") (Right . set) compiler - where - set compiler = \flags -> flags { testArgs = (testArgs flags) { testCompiler = compiler } } +readTestCompiler :: String -> Either String (CommandLineArgs -> CommandLineArgs) +readTestCompiler compiler = Right $ \flags -> flags { testArgs = (testArgs flags) { testCompiler = compiler } } -readTestConfig :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) -readTestConfig config = - case config of - Nothing -> Right id - Just conf -> Right $ \flags -> +readTestConfig :: String -> Either String (CommandLineArgs -> CommandLineArgs) +readTestConfig conf = Right $ \flags -> let configs = conf : testConfigs (testArgs flags) in flags { testArgs = (testArgs flags) { testConfigs = configs } } -readTestConfigFile :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) -readTestConfigFile filepath = - maybe (Left "Cannot parse test-config-file") (Right . set) filepath - where - set filepath flags = flags { testArgs = (testArgs flags) { testConfigFile = filepath } } +readTestConfigFile :: String -> Either String (CommandLineArgs -> CommandLineArgs) +readTestConfigFile filepath = Right $ \flags -> flags { testArgs = (testArgs flags) { testConfigFile = filepath } } readTestJUnit :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readTestJUnit filepath = Right $ \flags -> flags { testArgs = (testArgs flags) { testJUnit = filepath } } @@ -215,17 +201,16 @@ readTestRootDirs rootdirs = Right $ \flags -> where rootdirs' = maybe [] (splitOn ":") rootdirs rootdirs'' flags = testRootDirs (testArgs flags) ++ rootdirs' -readTestSpeed :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) +readTestSpeed :: String -> Either String (CommandLineArgs -> CommandLineArgs) readTestSpeed ms = - maybe (Left "Cannot parse test-speed") (Right . set) (go =<< lower <$> ms) + case lower ms of + "fast" -> set TestFast + "slow" -> set TestSlow + "normal" -> set TestNormal + _ -> Left "Cannot parse test-speed" where - go :: String -> Maybe TestSpeed - go "fast" = Just TestFast - go "slow" = Just TestSlow - go "normal" = Just TestNormal - go _ = Nothing - set :: TestSpeed -> CommandLineArgs -> CommandLineArgs - set flag flags = flags { testArgs = (testArgs flags) {testSpeed = flag} } + set :: TestSpeed -> Either String (CommandLineArgs -> CommandLineArgs) + set flag = Right $ \flags -> flags { testArgs = (testArgs flags) {testSpeed = flag} } readTestSummary :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readTestSummary filepath = Right $ \flags -> flags { testArgs = (testArgs flags) { testSummary = filepath } } @@ -233,19 +218,15 @@ readTestSummary filepath = Right $ \flags -> flags { testArgs = (testArgs flags) readTestVerbose :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readTestVerbose verbose = Right $ \flags -> flags { testArgs = (testArgs flags) { testVerbosity = verbose } } -readTestWay :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) +readTestWay :: String -> Either String (CommandLineArgs -> CommandLineArgs) readTestWay way = - case way of - Nothing -> Right id - Just way -> Right $ \flags -> + Right $ \flags -> let newWays = way : testWays (testArgs flags) in flags { testArgs = (testArgs flags) {testWays = newWays} } -readBrokenTests :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) -readBrokenTests way = - case way of - Nothing -> Left "--broken-tests expects argument" - Just tests -> Right $ \flags -> +readBrokenTests :: String -> Either String (CommandLineArgs -> CommandLineArgs) +readBrokenTests tests = + Right $ \flags -> let newTests = words tests ++ brokenTests (testArgs flags) in flags { testArgs = (testArgs flags) {brokenTests = newTests} } @@ -255,33 +236,32 @@ readPrefix ms = Right $ \flags -> flags { prefix = ms } readCompleteStg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readCompleteStg ms = Right $ \flags -> flags { completeStg = ms } -readDocsArg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) -readDocsArg ms = maybe (Left "Cannot parse docs argument") (Right . set) (go =<< ms) +readDocsArg :: String -> Either String (CommandLineArgs -> CommandLineArgs) +readDocsArg ms = + case ms of + "none" -> set (const Set.empty) + "no-haddocks" -> set (Set.delete Haddocks) + "no-sphinx-html" -> set (Set.delete SphinxHTML) + "no-sphinx-pdfs" -> set (Set.delete SphinxPDFs) + "no-sphinx-man" -> set (Set.delete SphinxMan) + "no-sphinx-info" -> set (Set.delete SphinxInfo) + "no-sphinx" -> set (Set.delete SphinxHTML + . Set.delete SphinxPDFs + . Set.delete SphinxMan + . Set.delete SphinxInfo) + _ -> Left "Cannot parse docs argument" where - go :: String -> Maybe (DocTargets -> DocTargets) - go "none" = Just (const Set.empty) - go "no-haddocks" = Just (Set.delete Haddocks) - go "no-sphinx-html" = Just (Set.delete SphinxHTML) - go "no-sphinx-pdfs" = Just (Set.delete SphinxPDFs) - go "no-sphinx-man" = Just (Set.delete SphinxMan) - go "no-sphinx-info" = Just (Set.delete SphinxInfo) - go "no-sphinx" = Just (Set.delete SphinxHTML - . Set.delete SphinxPDFs - . Set.delete SphinxMan - . Set.delete SphinxInfo) - go _ = Nothing - - set :: (DocTargets -> DocTargets) -> CommandLineArgs -> CommandLineArgs - set tweakTargets flags = flags - { docTargets = tweakTargets (docTargets flags) } + set :: (DocTargets -> DocTargets) -> Either String (CommandLineArgs -> CommandLineArgs) + set tweakTargets = Right $ \flags -> + flags { docTargets = tweakTargets (docTargets flags) } -- | Standard 'OptDescr' descriptions of Hadrian's command line arguments. optDescrs :: [OptDescr (Either String (CommandLineArgs -> CommandLineArgs))] optDescrs = [ Option ['c'] ["configure"] (NoArg readConfigure) "Deprecated: Run the boot and configure scripts." - , Option ['o'] ["build-root"] (OptArg readBuildRoot "BUILD_ROOT") + , Option ['o'] ["build-root"] (ReqArg readBuildRoot "BUILD_ROOT") "Where to store build artifacts. (Default _build)." , Option [] ["flavour"] (OptArg readFlavour "FLAVOUR") "Build flavour (Default, Devel1, Devel2, Perf, Prof, Quick or Quickest)." @@ -293,17 +273,17 @@ optDescrs = "Skip rebuilding dependency information." , Option [] ["bignum"] (OptArg readBignum "BACKEND") "Select ghc-bignum backend: native, gmp (default), check-gmp, ffi." - , Option [] ["progress-info"] (OptArg readProgressInfo "STYLE") + , Option [] ["progress-info"] (ReqArg readProgressInfo "STYLE") "Progress info style (None, Brief, Normal or Unicorn)." - , Option [] ["docs"] (OptArg readDocsArg "TARGET") + , Option [] ["docs"] (ReqArg readDocsArg "TARGET") "Strip down docs targets (none, no-haddocks, no-sphinx[-{html, pdfs, man}]." , Option ['k'] ["keep-test-files"] (NoArg readTestKeepFiles) "Keep all the files generated when running the testsuite." - , Option [] ["test-compiler"] (OptArg readTestCompiler "TEST_COMPILER") + , Option [] ["test-compiler"] (ReqArg readTestCompiler "TEST_COMPILER") "Use given compiler [Default=stage2]." - , Option [] ["test-config-file"] (OptArg readTestConfigFile "CONFIG_FILE") + , Option [] ["test-config-file"] (ReqArg readTestConfigFile "CONFIG_FILE") "configuration file for testsuite. Default=testsuite/config/ghc" - , Option [] ["config"] (OptArg readTestConfig "EXTRA_TEST_CONFIG") + , Option [] ["config"] (ReqArg readTestConfig "EXTRA_TEST_CONFIG") "Configurations to run test, in key=value format." , Option [] ["summary-junit"] (OptArg readTestJUnit "TEST_SUMMARY_JUNIT") "Output testsuite summary in JUnit format." @@ -317,15 +297,15 @@ optDescrs = "Skip performance tests." , Option [] ["test-root-dirs"] (OptArg readTestRootDirs "DIR1:[DIR2:...:DIRn]") "Test root directories to look at (all by default)." - , Option [] ["test-speed"] (OptArg readTestSpeed "SPEED") + , Option [] ["test-speed"] (ReqArg readTestSpeed "SPEED") "fast, slow or normal. Normal by default" , Option [] ["summary"] (OptArg readTestSummary "TEST_SUMMARY") "Where to output the test summary file." , Option [] ["test-verbose"] (OptArg readTestVerbose "TEST_VERBOSE") "A verbosity value between 0 and 5. 0 is silent, 4 and higher activates extra output." - , Option [] ["test-way"] (OptArg readTestWay "TEST_WAY") + , Option [] ["test-way"] (ReqArg readTestWay "TEST_WAY") "only run these ways" - , Option [] ["broken-test"] (OptArg readBrokenTests "TEST_NAME") + , Option [] ["broken-test"] (ReqArg readBrokenTests "TEST_NAME") "consider these tests to be broken" , Option ['a'] ["test-accept"] (NoArg readTestAccept) "Accept new output of tests" , Option [] ["test-have-intree-files"] (NoArg readTestHasInTreeFiles) "Run the in-tree tests even with an out of tree compiler" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53e4d513a55df3c13424e7b649ce85b8113fa4c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53e4d513a55df3c13424e7b649ce85b8113fa4c2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 12:17:31 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 08:17:31 -0400 Subject: [Git][ghc/ghc][master] JS: fix issues with FD api support Message-ID: <642ac3db86e0b_11425f3254f607922a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 2 changed files: - libraries/base/System/Posix/Internals.hs - libraries/base/jsbits/base.js Changes: ===================================== libraries/base/System/Posix/Internals.hs ===================================== @@ -139,10 +139,10 @@ ioe_unknownfiletype = IOError Nothing UnsupportedOperation "fdType" Nothing fdGetMode :: FD -> IO IOMode -#if defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) || defined(javascript_HOST_ARCH) fdGetMode _ = do -- We don't have a way of finding out which flags are set on FDs - -- on Windows, so make a handle that thinks that anything goes. + -- on Windows/JS, so make a handle that thinks that anything goes. let flags = o_RDWR #else fdGetMode fd = do ===================================== libraries/base/jsbits/base.js ===================================== @@ -450,6 +450,15 @@ function h$base_c_s_isdir(mode) { function h$base_c_s_isfifo(mode) { return 0; } +function h$base_c_fcntl_read(fd,cmd) { + return -1; +} +function h$base_c_fcntl_write(fd,cmd,value) { + return -1; +} +function h$base_c_fcntl_lock(fd,cmd,ptr,ptr_o) { + return -1; +} #ifndef GHCJS_BROWSER // The `fileStat` is filled according to the layout of Emscripten's `stat` View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8e36892689bd6b8fb472844f79aeeddeda92e0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a8e36892689bd6b8fb472844f79aeeddeda92e0a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 14:14:22 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 03 Apr 2023 10:14:22 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] More iterations to get more underflow frames Message-ID: <642adf3eec5d0_11425f5dd35c411091c@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: ff3bb3eb by Sven Tennie at 2023-04-03T14:13:55+00:00 More iterations to get more underflow frames - - - - - 1 changed file: - libraries/ghc-heap/tests/stack_underflow.hs Changes: ===================================== libraries/ghc-heap/tests/stack_underflow.hs ===================================== @@ -13,7 +13,7 @@ import GHC.Stack (HasCallStack) import GHC.Stack.CloneStack import TestUtils -main = loop 128 +main = loop 256 {-# NOINLINE loop #-} loop 0 = Control.Monad.void getStack View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ff3bb3ebc18fb94bb8b3ce912a3325c1c00e4fdc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ff3bb3ebc18fb94bb8b3ce912a3325c1c00e4fdc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 15:34:54 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 03 Apr 2023 11:34:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/js-boundsCheck Message-ID: <642af21e91ef9_11425f70a0be8128999@gitlab.mail> Josh Meredith pushed new branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/js-boundsCheck You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 16:14:57 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 03 Apr 2023 12:14:57 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 89 commits: Rename () into Unit, (,,...,,) into Tuple (#21294) Message-ID: <642afb818eccc_11425f7d3a17413461@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - b8123b2c by romes at 2023-04-03T10:20:02+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - f939dfc1 by romes at 2023-04-03T10:20:02+01:00 Validate compatibility of ghcs when loading plugins - - - - - c9b48a23 by romes at 2023-04-03T10:20:02+01:00 Add hashes to unit-ids created by hadrian Co-author: @mpickering - - - - - 6e7abf19 by GHC GitLab CI at 2023-04-03T10:20:02+01:00 Fix sed command in install makefile - - - - - 13824cd5 by Matthew Pickering at 2023-04-03T17:14:10+01:00 fixes - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bff5210c4f6781033474b239ac0673bd198ec6b3...13824cd5c871bd11e802ae157eee010fa40580e6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bff5210c4f6781033474b239ac0673bd198ec6b3...13824cd5c871bd11e802ae157eee010fa40580e6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 16:20:30 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 12:20:30 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: ghc-heap: remove wrong Addr# coercion (#23181) Message-ID: <642afcce7f086_11425f81940581351ce@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 9eedc848 by Krzysztof Gogolewski at 2023-04-03T12:20:19-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - ae2b002e by sheaf at 2023-04-03T12:20:25-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - 10 changed files: - .gitlab-ci.yml - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Name/Occurrence.hs - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json - hadrian/bootstrap/plan-9_2_4.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56016fd980f5286b484f110711dcc2ba550d4d2e...ae2b002e357b7db02c82705508a3b99019a9b763 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56016fd980f5286b484f110711dcc2ba550d4d2e...ae2b002e357b7db02c82705508a3b99019a9b763 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 16:35:48 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 03 Apr 2023 12:35:48 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 2 commits: add flag Message-ID: <642b0064c7396_11425f84c60c81438e4@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 104c2b4c by Matthew Pickering at 2023-04-03T17:31:17+01:00 add flag - - - - - 5d179c5d by Matthew Pickering at 2023-04-03T17:33:33+01:00 Use hash-unit-ids in release jobs - - - - - 4 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - hadrian/src/CommandLine.hs - hadrian/src/Hadrian/Haskell/Hash.hs Changes: ===================================== .gitlab/gen_ci.hs ===================================== @@ -760,7 +760,7 @@ nightly arch opsys bc = release :: Arch -> Opsys -> BuildConfig -> NamedJob Job release arch opsys bc = let NamedJob n j = job arch opsys (bc { buildFlavour = Release }) - in NamedJob { name = "release-" ++ n, jobInfo = addJobRule ReleaseOnly . keepArtifacts "1 year" . ignorePerfFailures . highCompression $ j} + in NamedJob { name = "release-" ++ n, jobInfo = addJobRule ReleaseOnly . keepArtifacts "1 year" . ignorePerfFailures . useHashUnitIds . highCompression $ j} -- Specific job modification functions @@ -785,6 +785,9 @@ ignorePerfFailures = addVariable "IGNORE_PERF_FAILURES" "all" highCompression :: Job -> Job highCompression = addVariable "XZ_OPT" "-9" +useHashUnitIds :: Job -> Job +useHashUnitIds = addVariable "HADRIAN_ARGS" "--hash-unit-ids" + -- | Mark the validate job to run in fast-ci mode fastCI :: JobGroup Job -> JobGroup Job fastCI = modifyValidateJobs (addJobRule FastCI) ===================================== .gitlab/jobs.yaml ===================================== @@ -2222,7 +2222,7 @@ "BIN_DIST_NAME": "ghc-aarch64-darwin-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MACOSX_DEPLOYMENT_TARGET": "11.0", @@ -2286,6 +2286,7 @@ "BIN_DIST_NAME": "ghc-aarch64-linux-deb10-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "aarch64-linux-deb10-release+no_split_sections", "XZ_OPT": "-9" @@ -2346,6 +2347,7 @@ "BIN_DIST_NAME": "ghc-i386-linux-deb9-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "i386-linux-deb9-release+no_split_sections", "XZ_OPT": "-9" @@ -2406,7 +2408,7 @@ "BIN_DIST_NAME": "ghc-x86_64-darwin-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MACOSX_DEPLOYMENT_TARGET": "10.10", @@ -2473,7 +2475,7 @@ "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", "BUILD_FLAVOUR": "release+fully_static", "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", "TEST_ENV": "x86_64-linux-alpine3_12-int_native-release+fully_static", @@ -2536,7 +2538,7 @@ "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", "BUILD_FLAVOUR": "release+fully_static+no_split_sections", "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", "TEST_ENV": "x86_64-linux-alpine3_12-release+fully_static+no_split_sections", @@ -2598,7 +2600,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-centos7-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-centos7-release+no_split_sections", "XZ_OPT": "-9" @@ -2659,6 +2661,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb10-release", "XZ_OPT": "-9" @@ -2719,6 +2722,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb10-release+debug_info", "XZ_OPT": "-9" @@ -2779,6 +2783,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb11-release", "XZ_OPT": "-9" @@ -2839,6 +2844,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-release+boot_nonmoving_gc", "BUILD_FLAVOUR": "release+boot_nonmoving_gc", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", "TEST_ENV": "x86_64-linux-deb11-release+boot_nonmoving_gc", @@ -2900,6 +2906,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb9-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb9-release+no_split_sections", "XZ_OPT": "-9" @@ -2960,6 +2967,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3022,6 +3030,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3084,7 +3093,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--haddock-base-url", + "HADRIAN_ARGS": "--haddock-base-url --hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3147,7 +3156,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-rocky8-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-rocky8-release", "XZ_OPT": "-9" @@ -3208,6 +3217,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu18_04-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-ubuntu18_04-release", "XZ_OPT": "-9" @@ -3268,6 +3278,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu20_04-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-ubuntu20_04-release", "XZ_OPT": "-9" @@ -3325,7 +3336,7 @@ "CABAL_INSTALL_VERSION": "3.8.1.0", "CONFIGURE_ARGS": "", "GHC_VERSION": "9.4.3", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MSYSTEM": "CLANG64", @@ -3385,7 +3396,7 @@ "CABAL_INSTALL_VERSION": "3.8.1.0", "CONFIGURE_ARGS": "", "GHC_VERSION": "9.4.3", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MSYSTEM": "CLANG64", ===================================== hadrian/src/CommandLine.hs ===================================== @@ -1,7 +1,7 @@ module CommandLine ( optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, lookupSkipDepends, cmdBignum, cmdBignumCheck, cmdProgressInfo, cmdCompleteSetting, - cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs, + cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs, cmdPrefix, DocArgs(..), defaultDocArgs ) where @@ -28,6 +28,7 @@ data CommandLineArgs = CommandLineArgs , freeze1 :: Bool , freeze2 :: Bool , skipDepends :: Bool + , unitIdHash :: Bool , bignum :: Maybe String , bignumCheck :: Bool , progressInfo :: ProgressInfo @@ -47,6 +48,7 @@ defaultCommandLineArgs = CommandLineArgs , freeze1 = False , freeze2 = False , skipDepends = False + , unitIdHash = False , bignum = Nothing , bignumCheck = False , progressInfo = Brief @@ -141,6 +143,9 @@ readFreeze1 = Right $ \flags -> flags { freeze1 = True } readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True } readSkipDepends = Right $ \flags -> flags { skipDepends = True } +readUnitIdHash :: Either String (CommandLineArgs -> CommandLineArgs) +readUnitIdHash = Right $ \flags -> flags { unitIdHash = True } + readProgressInfo :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readProgressInfo ms = maybe (Left "Cannot parse progress-info") (Right . set) (go =<< lower <$> ms) @@ -289,6 +294,8 @@ optDescrs = "Freeze Stage1 GHC." , Option [] ["freeze2"] (NoArg readFreeze2) "Freeze Stage2 GHC." + , Option [] ["hash-unit-ids"] (NoArg readUnitIdHash) + "Include package hashes in unit ids." , Option [] ["skip-depends"] (NoArg readSkipDepends) "Skip rebuilding dependency information." , Option [] ["bignum"] (OptArg readBignum "BACKEND") @@ -400,6 +407,9 @@ lookupFreeze2 = freeze2 . lookupExtra defaultCommandLineArgs lookupSkipDepends :: Map.HashMap TypeRep Dynamic -> Bool lookupSkipDepends = skipDepends . lookupExtra defaultCommandLineArgs +cmdUnitIdHash :: Action Bool +cmdUnitIdHash = unitIdHash <$> cmdLineArgs + cmdBignum :: Action (Maybe String) cmdBignum = bignum <$> cmdLineArgs ===================================== hadrian/src/Hadrian/Haskell/Hash.hs ===================================== @@ -35,6 +35,7 @@ import Utilities import Base import Context import System.Directory.Extra (listFilesRecursive) +import CommandLine -- | Read a Cabal file and return the package identifier, e.g. @base-4.10.0.0-abcd at . @@ -43,7 +44,7 @@ pkgUnitId :: Context -> Package -> Action String pkgUnitId ctx' pkg = do let ctx = ctx'{package = pkg} pid <- pkgSimpleIdentifier (package ctx) - phash <- pkgHash ctx + use_hash <- cmdUnitIdHash if pkgName pkg == "rts" -- The unit-id will change depending on the way, we need to treat the rts separately then pure pid @@ -52,7 +53,13 @@ pkgUnitId ctx' pkg = do -- can have hadrian generate a different unit-id for them just as cabal does -- because the boot packages unit-ids are overriden by setting -this-unit-id -- in the cabal file - pure $ pid <> "-" <> truncateHash 4 phash + hash <- if use_hash + then do + phash <- pkgHash ctx + return $ truncateHash 4 phash + else + return "inplace" + pure $ pid <> "-" <> hash where truncateHash :: Int -> String -> String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13824cd5c871bd11e802ae157eee010fa40580e6...5d179c5d73e643dd8457457b95f4666e288eaf5d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13824cd5c871bd11e802ae157eee010fa40580e6...5d179c5d73e643dd8457457b95f4666e288eaf5d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 16:39:41 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 03 Apr 2023 12:39:41 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 3 commits: fixes Message-ID: <642b014d3c5db_11425f84c8094144492@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 94015f4b by Matthew Pickering at 2023-04-03T17:39:19+01:00 fixes - - - - - 29d874e9 by Matthew Pickering at 2023-04-03T17:39:24+01:00 add flag - - - - - c689e100 by Matthew Pickering at 2023-04-03T17:39:24+01:00 Use hash-unit-ids in release jobs - - - - - 21 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - hadrian/src/CommandLine.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/Builder/Git.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - hadrian/src/Hadrian/Haskell/Hash.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Default.hs-boot - hadrian/src/Settings/Flavours/Benchmark.hs - hadrian/src/Settings/Flavours/Development.hs - hadrian/src/Settings/Flavours/GhcInGhci.hs - hadrian/src/Settings/Flavours/Performance.hs - hadrian/src/Settings/Flavours/Quick.hs - hadrian/src/Settings/Flavours/QuickCross.hs - hadrian/src/Settings/Flavours/Quickest.hs - hadrian/src/Settings/Flavours/Validate.hs - utils/ghc-pkg/Main.hs Changes: ===================================== .gitlab/gen_ci.hs ===================================== @@ -760,7 +760,7 @@ nightly arch opsys bc = release :: Arch -> Opsys -> BuildConfig -> NamedJob Job release arch opsys bc = let NamedJob n j = job arch opsys (bc { buildFlavour = Release }) - in NamedJob { name = "release-" ++ n, jobInfo = addJobRule ReleaseOnly . keepArtifacts "1 year" . ignorePerfFailures . highCompression $ j} + in NamedJob { name = "release-" ++ n, jobInfo = addJobRule ReleaseOnly . keepArtifacts "1 year" . ignorePerfFailures . useHashUnitIds . highCompression $ j} -- Specific job modification functions @@ -785,6 +785,9 @@ ignorePerfFailures = addVariable "IGNORE_PERF_FAILURES" "all" highCompression :: Job -> Job highCompression = addVariable "XZ_OPT" "-9" +useHashUnitIds :: Job -> Job +useHashUnitIds = addVariable "HADRIAN_ARGS" "--hash-unit-ids" + -- | Mark the validate job to run in fast-ci mode fastCI :: JobGroup Job -> JobGroup Job fastCI = modifyValidateJobs (addJobRule FastCI) ===================================== .gitlab/jobs.yaml ===================================== @@ -2222,7 +2222,7 @@ "BIN_DIST_NAME": "ghc-aarch64-darwin-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MACOSX_DEPLOYMENT_TARGET": "11.0", @@ -2286,6 +2286,7 @@ "BIN_DIST_NAME": "ghc-aarch64-linux-deb10-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "aarch64-linux-deb10-release+no_split_sections", "XZ_OPT": "-9" @@ -2346,6 +2347,7 @@ "BIN_DIST_NAME": "ghc-i386-linux-deb9-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "i386-linux-deb9-release+no_split_sections", "XZ_OPT": "-9" @@ -2406,7 +2408,7 @@ "BIN_DIST_NAME": "ghc-x86_64-darwin-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MACOSX_DEPLOYMENT_TARGET": "10.10", @@ -2473,7 +2475,7 @@ "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", "BUILD_FLAVOUR": "release+fully_static", "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", "TEST_ENV": "x86_64-linux-alpine3_12-int_native-release+fully_static", @@ -2536,7 +2538,7 @@ "BROKEN_TESTS": "encoding004 T10458 ghcilink002 linker_unload_native", "BUILD_FLAVOUR": "release+fully_static+no_split_sections", "CONFIGURE_ARGS": "--disable-ld-override ", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--disable-ld-override", "TEST_ENV": "x86_64-linux-alpine3_12-release+fully_static+no_split_sections", @@ -2598,7 +2600,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-centos7-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-centos7-release+no_split_sections", "XZ_OPT": "-9" @@ -2659,6 +2661,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb10-release", "XZ_OPT": "-9" @@ -2719,6 +2722,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb10-release+debug_info", "XZ_OPT": "-9" @@ -2779,6 +2783,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb11-release", "XZ_OPT": "-9" @@ -2839,6 +2844,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-release+boot_nonmoving_gc", "BUILD_FLAVOUR": "release+boot_nonmoving_gc", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "RUNTEST_ARGS": "--way=nonmoving --way=nonmoving_thr --way=nonmoving_thr_sanity", "TEST_ENV": "x86_64-linux-deb11-release+boot_nonmoving_gc", @@ -2900,6 +2906,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-deb9-release+no_split_sections", "BUILD_FLAVOUR": "release+no_split_sections", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-deb9-release+no_split_sections", "XZ_OPT": "-9" @@ -2960,6 +2967,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3022,6 +3030,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3084,7 +3093,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--haddock-base-url", + "HADRIAN_ARGS": "--haddock-base-url --hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "LLC": "/bin/false", "OPT": "/bin/false", @@ -3147,7 +3156,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-rocky8-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-rocky8-release", "XZ_OPT": "-9" @@ -3208,6 +3217,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu18_04-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-ubuntu18_04-release", "XZ_OPT": "-9" @@ -3268,6 +3278,7 @@ "BIN_DIST_NAME": "ghc-x86_64-linux-ubuntu20_04-release", "BUILD_FLAVOUR": "release", "CONFIGURE_ARGS": "", + "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "TEST_ENV": "x86_64-linux-ubuntu20_04-release", "XZ_OPT": "-9" @@ -3325,7 +3336,7 @@ "CABAL_INSTALL_VERSION": "3.8.1.0", "CONFIGURE_ARGS": "", "GHC_VERSION": "9.4.3", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MSYSTEM": "CLANG64", @@ -3385,7 +3396,7 @@ "CABAL_INSTALL_VERSION": "3.8.1.0", "CONFIGURE_ARGS": "", "GHC_VERSION": "9.4.3", - "HADRIAN_ARGS": "--docs=no-sphinx", + "HADRIAN_ARGS": "--hash-unit-ids --docs=no-sphinx", "IGNORE_PERF_FAILURES": "all", "LANG": "en_US.UTF-8", "MSYSTEM": "CLANG64", ===================================== hadrian/src/CommandLine.hs ===================================== @@ -1,7 +1,7 @@ module CommandLine ( optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, lookupSkipDepends, cmdBignum, cmdBignumCheck, cmdProgressInfo, cmdCompleteSetting, - cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs, + cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs, cmdPrefix, DocArgs(..), defaultDocArgs ) where @@ -28,6 +28,7 @@ data CommandLineArgs = CommandLineArgs , freeze1 :: Bool , freeze2 :: Bool , skipDepends :: Bool + , unitIdHash :: Bool , bignum :: Maybe String , bignumCheck :: Bool , progressInfo :: ProgressInfo @@ -47,6 +48,7 @@ defaultCommandLineArgs = CommandLineArgs , freeze1 = False , freeze2 = False , skipDepends = False + , unitIdHash = False , bignum = Nothing , bignumCheck = False , progressInfo = Brief @@ -141,6 +143,9 @@ readFreeze1 = Right $ \flags -> flags { freeze1 = True } readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True } readSkipDepends = Right $ \flags -> flags { skipDepends = True } +readUnitIdHash :: Either String (CommandLineArgs -> CommandLineArgs) +readUnitIdHash = Right $ \flags -> flags { unitIdHash = True } + readProgressInfo :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readProgressInfo ms = maybe (Left "Cannot parse progress-info") (Right . set) (go =<< lower <$> ms) @@ -289,6 +294,8 @@ optDescrs = "Freeze Stage1 GHC." , Option [] ["freeze2"] (NoArg readFreeze2) "Freeze Stage2 GHC." + , Option [] ["hash-unit-ids"] (NoArg readUnitIdHash) + "Include package hashes in unit ids." , Option [] ["skip-depends"] (NoArg readSkipDepends) "Skip rebuilding dependency information." , Option [] ["bignum"] (OptArg readBignum "BACKEND") @@ -400,6 +407,9 @@ lookupFreeze2 = freeze2 . lookupExtra defaultCommandLineArgs lookupSkipDepends :: Map.HashMap TypeRep Dynamic -> Bool lookupSkipDepends = skipDepends . lookupExtra defaultCommandLineArgs +cmdUnitIdHash :: Action Bool +cmdUnitIdHash = unitIdHash <$> cmdLineArgs + cmdBignum :: Action (Maybe String) cmdBignum = bignum <$> cmdLineArgs ===================================== hadrian/src/Flavour.hs ===================================== @@ -112,7 +112,7 @@ parseFlavour baseFlavours transformers str = -- | Add arguments to the 'args' of a 'Flavour'. addArgs :: Args -> Flavour -> Flavour -addArgs args' fl = fl { args = args fl <> args' } +addArgs args' fl = fl { extraArgs = extraArgs fl <> args' } -- | Turn on -Werror for packages built with the stage1 compiler. -- It mimics the CI settings so is useful to turn on when developing. @@ -468,7 +468,7 @@ applySetting (KeyVal ks op v) = case runSettingsM ks builderPredicate of Left err -> throwError $ "error while setting `" ++ intercalate "`." ks ++ ": " ++ err Right pred -> Right $ \flav -> flav - { args = update (args flav) pred } + { extraArgs = update (extraArgs flav) pred } where override arguments predicate = do holds <- predicate ===================================== hadrian/src/Flavour/Type.hs ===================================== @@ -14,8 +14,8 @@ import Data.Set (Set) data Flavour = Flavour { -- | Flavour name, to select this flavour from command line. name :: String, - -- | Use these command line arguments. - args :: Args, + -- | Use these extra command line arguments. + extraArgs :: Args, -- | Build these packages. packages :: Stage -> Action [Package], -- | Bignum backend: 'native', 'gmp', 'ffi', etc. ===================================== hadrian/src/Hadrian/Builder/Git.hs ===================================== @@ -2,12 +2,13 @@ module Hadrian.Builder.Git (gitArgs) where import Expression --- | Default command line arguments for invoking the archiving utility @tar at . +-- | Default command line arguments for invoking the archiving utility @git at . gitArgs :: Args gitArgs = mconcat [ builder (Git ListFiles) ? mconcat [ arg "ls-files" , arg "--recurse-submodules" , arg "-z" + , getInputs ] ] ===================================== hadrian/src/Hadrian/Haskell/Cabal/Parse.hs ===================================== @@ -63,7 +63,6 @@ import Hadrian.Target import Base import Builder import Context -import Flavour import Settings import Distribution.Simple.LocalBuildInfo import qualified Distribution.Simple.Register as C @@ -158,9 +157,8 @@ configurePackage context at Context {..} = do pure $ if configureExists then C.autoconfUserHooks else C.simpleUserHooks -- Compute the list of flags, and the Cabal configuration arguments - flavourArgs <- args <$> flavour - flagList <- interpret (target context (Cabal Flags stage) [] []) flavourArgs - argList <- interpret (target context (Cabal Setup stage) [] []) flavourArgs + flagList <- interpret (target context (Cabal Flags stage) [] []) getArgs + argList <- interpret (target context (Cabal Setup stage) [] []) getArgs trackArgsHash (target context (Cabal Flags stage) [] []) trackArgsHash (target context (Cabal Setup stage) [] []) verbosity <- getVerbosity ===================================== hadrian/src/Hadrian/Haskell/Hash.hs ===================================== @@ -14,6 +14,7 @@ import Hadrian.Package import qualified Crypto.Hash.SHA256 as SHA256 import qualified Data.ByteString.Base16 as Base16 import qualified Data.ByteString.Char8 as BS +import Data.ByteString as BS (readFile) import Data.Map (Map) import qualified Data.Map as Map import qualified Data.Set as Set @@ -26,11 +27,15 @@ import Hadrian.Expression import Builder import Flavour.Type import Settings -import Way.Type import Way import Packages import Development.Shake.Classes import Control.Monad +import Utilities +import Base +import Context +import System.Directory.Extra (listFilesRecursive) +import CommandLine -- | Read a Cabal file and return the package identifier, e.g. @base-4.10.0.0-abcd at . @@ -39,7 +44,7 @@ pkgUnitId :: Context -> Package -> Action String pkgUnitId ctx' pkg = do let ctx = ctx'{package = pkg} pid <- pkgSimpleIdentifier (package ctx) - phash <- pkgHash ctx + use_hash <- cmdUnitIdHash if pkgName pkg == "rts" -- The unit-id will change depending on the way, we need to treat the rts separately then pure pid @@ -48,7 +53,13 @@ pkgUnitId ctx' pkg = do -- can have hadrian generate a different unit-id for them just as cabal does -- because the boot packages unit-ids are overriden by setting -this-unit-id -- in the cabal file - pure $ pid <> "-" <> truncateHash 4 phash + hash <- if use_hash + then do + phash <- pkgHash ctx + return $ truncateHash 4 phash + else + return "inplace" + pure $ pid <> "-" <> hash where truncateHash :: Int -> String -> String @@ -71,31 +82,31 @@ data PackageHashConfigInputs = PackageHashConfigInputs { pkgHashCompilerId :: String, pkgHashPlatform :: String, pkgHashFlagAssignment :: [String], -- complete not partial - -- pkgHashConfigureScriptArgs :: [String], -- just ./configure for build-type Configure pkgHashVanillaLib :: Bool, pkgHashSharedLib :: Bool, pkgHashDynExe :: Bool, - pkgHashFullyStaticExe :: Bool, pkgHashGHCiLib :: Bool, pkgHashProfLib :: Bool, pkgHashProfExe :: Bool, --- pkgHashProfLibDetail :: ProfDetailLevel, --- pkgHashProfExeDetail :: ProfDetailLevel, - pkgHashCoverage :: Bool, - pkgHashOptimization :: Int, pkgHashSplitObjs :: Bool, pkgHashSplitSections :: Bool, pkgHashStripLibs :: Bool, pkgHashStripExes :: Bool, --- pkgHashDebugInfo :: DebugInfoLevel, - pkgHashProgramArgs :: Map String [String], - pkgHashExtraLibDirs :: [FilePath], - pkgHashExtraLibDirsStatic :: [FilePath], - pkgHashExtraFrameworkDirs :: [FilePath], - pkgHashExtraIncludeDirs :: [FilePath] + pkgHashProgramArgs :: Map String [String] -- pkgHashProgPrefix :: Maybe PathTemplate, -- pkgHashProgSuffix :: Maybe PathTemplate, -- pkgHashPackageDbs :: [Maybe PackageDB] + -- Captured by extraArgs +-- pkgHashDebugInfo :: DebugInfoLevel, +-- pkgHashCoverage :: Bool, +-- pkgHashFullyStaticExe :: Bool, +-- pkgHashProfLibDetail :: ProfDetailLevel, +-- pkgHashOptimization :: Int, +-- pkgHashProfExeDetail :: ProfDetailLevel, +-- pkgHashExtraLibDirs :: [FilePath], +-- pkgHashExtraLibDirsStatic :: [FilePath], +-- pkgHashExtraFrameworkDirs :: [FilePath], +-- pkgHashExtraIncludeDirs :: [FilePath] } deriving Show @@ -115,56 +126,92 @@ pkgHashOracle = void $ addOracleCache $ \(PkgHashKey ctx) -> do stagePkgs <- stagePackages stag depsHashes <- mapM (\pkg -> pkgHash (ctx { package = pkg })) [pkg | pkg <- packageDependencies pkg_data, pkg `elem` stagePkgs] flav <- flavour - let flavourArgs = args flav + let flavourArgs = extraArgs flav targetOs <- setting TargetOs - let pkgHashCompilerId = "" + projectVersion <- setting ProjectVersionInt + let pkgHashCompilerId = "ghc-" ++ projectVersion pkgHashPlatform = targetOs + libWays <- interpretInContext ctx (libraryWays flav) dyn_ghc <- dynamicGhcPrograms flav - flags <- interpret (target ctx (Cabal Flags stag) [] []) flavourArgs + flags <- interpret (target ctx (Cabal Flags stag) [] []) getArgs let pkgHashFlagAssignment = flags - pkgHashConfigureScriptArgs = "" pkgHashVanillaLib = vanilla `Set.member` libWays pkgHashSharedLib = dynamic `Set.member` libWays pkgHashDynExe = dyn_ghc - pkgHashFullyStaticExe = False -- TODO: fullyStatic flavour transformer pkgHashGHCiLib = False pkgHashProfLib = profiling `Set.member` libWays pkgHashProfExe = package ctx == ghc && ghcProfiled flav stag - pkgHashCoverage = False -- Can't configure this - pkgHashOptimization = 0 -- TODO: A bit tricky to configure pkgHashSplitObjs = False -- Deprecated pkgHashSplitSections = ghcSplitSections flav pkgHashStripExes = False pkgHashStripLibs = False - pkgHashDebugInfo = undefined - -- ghcArgs <- interpret (target ctx (Cabal Setup stag) [] []) flavourArgs - let pkgHashProgramArgs = mempty -- TODO: Map.singleton "ghc" ghcArgs, - -- but the above call to 'interpret' causes a - -- build-time loop - pkgHashExtraLibDirs = [] - pkgHashExtraLibDirsStatic = [] - pkgHashExtraFrameworkDirs = [] - pkgHashExtraIncludeDirs = [] + ghcArgs <- interpret (target ctx (Ghc CompileHs stag) [] []) flavourArgs + ghcCArgs <- interpret (target ctx (Ghc CompileCWithGhc stag) [] []) flavourArgs + linkArgs <- interpret (target ctx (Ghc LinkHs stag) [] []) flavourArgs + ccArgs <- interpret (target ctx (Cc CompileC stag) [] []) flavourArgs + hsc2hsArgs <- interpret (target ctx (Hsc2Hs stag) [] []) flavourArgs + -- TODO: Other arguments for other things (a user could pass extra options to any + -- builder we know about and we need to enumerate them here) + let pkgHashProgramArgs = Map.fromList [("ghc", ghcArgs) + ,("ghc-c", ghcCArgs) + ,("ghc-link", linkArgs) + ,("hsc2hs", hsc2hsArgs) + ,("cc", ccArgs) + ] let other_config = PackageHashConfigInputs{..} + files <- allFilesInDirectory (pkgPath (package ctx)) + need files + files_hash <- liftIO (SHA256.finalize <$> hashFiles (SHA256.init) files) + return $ BS.unpack $ Base16.encode $ SHA256.hash $ renderPackageHashInputs $ PackageHashInputs { pkgHashPkgId = name , pkgHashComponent = pkgType (package ctx) - , pkgHashSourceHash = "" + , pkgHashSourceHash = files_hash , pkgHashDirectDeps = Set.fromList depsHashes , pkgHashOtherConfig = other_config } +-- Either use git ls-tree if we are in a git repo, otherwise just get all the +-- files in the given directory. +allFilesInDirectory :: FilePath -> Action [FilePath] +allFilesInDirectory dir = do + git_tree <- isInGitTree + if git_tree + then do + let gitFiles = filter fileFilter . split (=='\NUL') + fileFilter file = not (null file) && ((dir ++ "/*") ?== file) + gitFiles <$> askWithResources [] (target (vanillaContext stage0Boot compiler) -- This value doesn't matter. + (Git ListFiles) [dir] []) + else + liftIO $ listFilesRecursive dir + +isInGitTree :: Action Bool +isInGitTree = do + git_commit <- setting ProjectGitCommitId + -- git_commit is not set if we are in a source dist + return $ not ("" == git_commit) + + prettyShow, showHashValue :: Show a => a -> String prettyShow = show showHashValue = show +hashFiles :: SHA256.Ctx -> [FilePath] -> IO SHA256.Ctx +hashFiles = foldM hashFile + +hashFile :: SHA256.Ctx -> FilePath -> IO SHA256.Ctx +hashFile !ctx fp = do + contents <- BS.readFile fp + return $! SHA256.update ctx contents + + renderPackageHashInputs :: PackageHashInputs -> BS.ByteString renderPackageHashInputs PackageHashInputs{ pkgHashPkgId, @@ -180,51 +227,27 @@ renderPackageHashInputs PackageHashInputs{ -- unnecessarily when new configuration inputs are added into the hash. BS.pack $ unlines $ catMaybes $ [ entry "pkgid" prettyShow pkgHashPkgId --- , mentry "component" show pkgHashComponent + , entry "component" show pkgHashComponent , entry "src" showHashValue pkgHashSourceHash - {- - , entry "pkg-config-deps" - (intercalate ", " . map (\(pn, mb_v) -> prettyShow pn ++ - case mb_v of - Nothing -> "" - Just v -> " " ++ prettyShow v) - . Set.toList) pkgHashPkgConfigDeps - -} , entry "deps" (intercalate ", " . map prettyShow . Set.toList) pkgHashDirectDeps -- and then all the config , entry "compilerid" prettyShow pkgHashCompilerId , entry "platform" prettyShow pkgHashPlatform , opt "flags" mempty show pkgHashFlagAssignment --- , opt "configure-script" [] unwords pkgHashConfigureScriptArgs , opt "vanilla-lib" True prettyShow pkgHashVanillaLib , opt "shared-lib" False prettyShow pkgHashSharedLib , opt "dynamic-exe" False prettyShow pkgHashDynExe - , opt "fully-static-exe" False prettyShow pkgHashFullyStaticExe , opt "ghci-lib" False prettyShow pkgHashGHCiLib , opt "prof-lib" False prettyShow pkgHashProfLib , opt "prof-exe" False prettyShow pkgHashProfExe - -- , opt "prof-lib-detail" ProfDetailDefault showProfDetailLevel pkgHashProfLibDetail - -- , opt "prof-exe-detail" ProfDetailDefault showProfDetailLevel pkgHashProfExeDetail - , opt "hpc" False prettyShow pkgHashCoverage - , opt "optimisation" 0 (show) pkgHashOptimization , opt "split-objs" False prettyShow pkgHashSplitObjs , opt "split-sections" False prettyShow pkgHashSplitSections , opt "stripped-lib" False prettyShow pkgHashStripLibs , opt "stripped-exe" True prettyShow pkgHashStripExes --- , opt "debug-info" NormalDebugInfo (show . fromEnum) pkgHashDebugInfo - , opt "extra-lib-dirs" [] unwords pkgHashExtraLibDirs - , opt "extra-lib-dirs-static" [] unwords pkgHashExtraLibDirsStatic - , opt "extra-framework-dirs" [] unwords pkgHashExtraFrameworkDirs - , opt "extra-include-dirs" [] unwords pkgHashExtraIncludeDirs --- , opt "prog-prefix" Nothing (maybe "" fromPathTemplate) pkgHashProgPrefix --- , opt "prog-suffix" Nothing (maybe "" fromPathTemplate) pkgHashProgSuffix --- , opt "package-dbs" [] (unwords . map show) pkgHashPackageDbs - ] ++ Map.foldrWithKey (\prog args acc -> opt (prog ++ "-options") [] unwords args : acc) [] pkgHashProgramArgs where entry key format value = Just (key ++ ": " ++ format value) - mentry key format value = fmap (\v -> key ++ ": " ++ format v) value opt key def format value | value == def = Nothing | otherwise = entry key format value ===================================== hadrian/src/Settings.hs ===================================== @@ -1,7 +1,7 @@ {-# LANGUAGE TupleSections #-} module Settings ( - getArgs, getLibraryWays, getRtsWays, flavour, knownPackages, + getExtraArgs, getArgs, getLibraryWays, getRtsWays, flavour, knownPackages, findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath, isLibrary, stagePackages, getBignumBackend, getBignumCheck, completeSetting ) where @@ -25,8 +25,11 @@ import Settings.Flavours.Validate import Settings.Flavours.Release +getExtraArgs :: Args +getExtraArgs = expr flavour >>= extraArgs + getArgs :: Args -getArgs = expr flavour >>= args +getArgs = mconcat [ defaultBuilderArgs, getExtraArgs, defaultPackageArgs ] getLibraryWays :: Ways getLibraryWays = expr flavour >>= libraryWays ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -228,6 +228,8 @@ commonGhcArgs = do -- input hash to avoid superfluous recompilation, avoiding -- #18672. arg "-fdiagnostics-color=always" + -- Important this is last.. as these options can override the default options + , getContextData hcOpts ] -- TODO: Do '-ticky' in all debug ways? ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -7,7 +7,7 @@ module Settings.Default ( -- * Default command line arguments for various builders SourceArgs (..), sourceArgs, defaultBuilderArgs, defaultPackageArgs, - defaultArgs, + defaultExtraArgs, -- * Default build flavour and BigNum backend defaultFlavour, defaultBignumBackend @@ -17,7 +17,6 @@ import qualified Data.Set as Set import qualified Hadrian.Builder.Sphinx import qualified Hadrian.Builder.Tar -import Hadrian.Haskell.Cabal.Type import CommandLine import Expression @@ -206,9 +205,8 @@ data SourceArgs = SourceArgs -- | Concatenate source arguments in appropriate order. sourceArgs :: SourceArgs -> Args -sourceArgs SourceArgs {..} = builder Ghc ? mconcat +sourceArgs SourceArgs {..} = builder Ghc ? mconcat [] [ hsDefault - , getContextData hcOpts -- `compiler` is also a library but the specific arguments that we want -- to apply to that are given by the hsCompiler option. `ghc` is an -- executable so we don't have to exclude that. @@ -217,11 +215,8 @@ sourceArgs SourceArgs {..} = builder Ghc ? mconcat , package ghc ? hsGhc ] -- | All default command line arguments. -defaultArgs :: Args -defaultArgs = mconcat - [ defaultBuilderArgs - , sourceArgs defaultSourceArgs - , defaultPackageArgs ] +defaultExtraArgs :: Args +defaultExtraArgs = sourceArgs defaultSourceArgs -- | Default source arguments, e.g. optimisation settings. defaultSourceArgs :: SourceArgs @@ -239,7 +234,7 @@ defaultSourceArgs = SourceArgs defaultFlavour :: Flavour defaultFlavour = Flavour { name = "default" - , args = defaultArgs + , extraArgs = defaultExtraArgs , packages = defaultPackages , bignumBackend = defaultBignumBackend , bignumCheck = False ===================================== hadrian/src/Settings/Default.hs-boot ===================================== @@ -1,6 +1,6 @@ module Settings.Default ( SourceArgs (..), sourceArgs, defaultBuilderArgs, defaultPackageArgs, - defaultArgs, defaultLibraryWays, defaultRtsWays, + defaultExtraArgs, defaultLibraryWays, defaultRtsWays, defaultFlavour, defaultBignumBackend ) where @@ -15,7 +15,7 @@ data SourceArgs = SourceArgs sourceArgs :: SourceArgs -> Args -defaultBuilderArgs, defaultPackageArgs, defaultArgs :: Args +defaultBuilderArgs, defaultPackageArgs, defaultExtraArgs :: Args defaultLibraryWays, defaultRtsWays :: Ways defaultFlavour :: Flavour defaultBignumBackend :: String ===================================== hadrian/src/Settings/Flavours/Benchmark.hs ===================================== @@ -10,7 +10,7 @@ import {-# SOURCE #-} Settings.Default benchmarkFlavour :: Flavour benchmarkFlavour = defaultFlavour { name = "bench" - , args = defaultBuilderArgs <> benchmarkArgs <> defaultPackageArgs + , extraArgs = benchmarkArgs , libraryWays = pure $ Set.fromList [vanilla] , rtsWays = Set.fromList <$> mconcat [pure [vanilla], targetSupportsThreadedRts ? pure [threaded]] } ===================================== hadrian/src/Settings/Flavours/Development.hs ===================================== @@ -12,7 +12,7 @@ import {-# SOURCE #-} Settings.Default developmentFlavour :: Stage -> Flavour developmentFlavour ghcStage = defaultFlavour { name = "devel" ++ stageString ghcStage - , args = defaultBuilderArgs <> developmentArgs ghcStage <> defaultPackageArgs + , extraArgs = developmentArgs ghcStage , libraryWays = pure $ Set.fromList [vanilla] , rtsWays = Set.fromList <$> mconcat [pure [vanilla, debug], targetSupportsThreadedRts ? pure [threaded, threadedDebug]] , dynamicGhcPrograms = return False ===================================== hadrian/src/Settings/Flavours/GhcInGhci.hs ===================================== @@ -11,7 +11,7 @@ import {-# SOURCE #-} Settings.Default ghcInGhciFlavour :: Flavour ghcInGhciFlavour = defaultFlavour { name = "ghc-in-ghci" - , args = defaultBuilderArgs <> ghciArgs <> defaultPackageArgs + , extraArgs = ghciArgs -- We can't build DLLs on Windows (yet). Actually we should only -- include the dynamic way when we have a dynamic host GHC, but just -- checking for Windows seems simpler for now. ===================================== hadrian/src/Settings/Flavours/Performance.hs ===================================== @@ -8,7 +8,7 @@ import {-# SOURCE #-} Settings.Default performanceFlavour :: Flavour performanceFlavour = splitSections $ defaultFlavour { name = "perf" - , args = defaultBuilderArgs <> performanceArgs <> defaultPackageArgs } + , extraArgs = performanceArgs } performanceArgs :: Args performanceArgs = sourceArgs SourceArgs ===================================== hadrian/src/Settings/Flavours/Quick.hs ===================================== @@ -15,7 +15,7 @@ import {-# SOURCE #-} Settings.Default quickFlavour :: Flavour quickFlavour = defaultFlavour { name = "quick" - , args = defaultBuilderArgs <> quickArgs <> defaultPackageArgs + , extraArgs = quickArgs , libraryWays = Set.fromList <$> mconcat [ pure [vanilla] ===================================== hadrian/src/Settings/Flavours/QuickCross.hs ===================================== @@ -11,7 +11,7 @@ import {-# SOURCE #-} Settings.Default quickCrossFlavour :: Flavour quickCrossFlavour = defaultFlavour { name = "quick-cross" - , args = defaultBuilderArgs <> quickCrossArgs <> defaultPackageArgs + , extraArgs = quickCrossArgs , dynamicGhcPrograms = pure False , libraryWays = Set.fromList <$> mconcat ===================================== hadrian/src/Settings/Flavours/Quickest.hs ===================================== @@ -11,7 +11,7 @@ import {-# SOURCE #-} Settings.Default quickestFlavour :: Flavour quickestFlavour = defaultFlavour { name = "quickest" - , args = defaultBuilderArgs <> quickestArgs <> defaultPackageArgs + , extraArgs = quickestArgs , libraryWays = pure (Set.fromList [vanilla]) , rtsWays = pure (Set.fromList [vanilla]) <> (targetSupportsThreadedRts ? pure (Set.fromList [threaded])) , dynamicGhcPrograms = return False } ===================================== hadrian/src/Settings/Flavours/Validate.hs ===================================== @@ -12,7 +12,7 @@ import {-# SOURCE #-} Settings.Default validateFlavour :: Flavour validateFlavour = enableLinting $ werror $ defaultFlavour { name = "validate" - , args = defaultBuilderArgs <> validateArgs <> defaultPackageArgs + , extraArgs = validateArgs , libraryWays = Set.fromList <$> mconcat [ pure [vanilla] , notStage0 ? platformSupportsSharedLibs ? pure [dynamic] @@ -60,4 +60,4 @@ quickValidateArgs = sourceArgs SourceArgs quickValidateFlavour :: Flavour quickValidateFlavour = werror $ validateFlavour { name = "quick-validate" - , args = defaultBuilderArgs <> quickValidateArgs <> defaultPackageArgs } + , extraArgs = quickValidateArgs } ===================================== utils/ghc-pkg/Main.hs ===================================== @@ -23,7 +23,6 @@ module Main (main) where -import Debug.Trace import qualified GHC.Unit.Database as GhcPkg import GHC.Unit.Database hiding (mkMungePathUrl) import GHC.HandleEncoding @@ -1601,7 +1600,7 @@ listPackages verbosity my_flags mPackageName mModuleName = do simplePackageList :: [Flag] -> [InstalledPackageInfo] -> IO () simplePackageList my_flags pkgs = do let showPkg :: InstalledPackageInfo -> String - showPkg | FlagShowUnitIds `elem` my_flags = traceId . display . installedUnitId + showPkg | FlagShowUnitIds `elem` my_flags = display . installedUnitId | FlagNamesOnly `elem` my_flags = display . mungedName . mungedId | otherwise = display . mungedId strs = map showPkg pkgs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d179c5d73e643dd8457457b95f4666e288eaf5d...c689e100666bf5c9f41f49136b344a84d94c02a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d179c5d73e643dd8457457b95f4666e288eaf5d...c689e100666bf5c9f41f49136b344a84d94c02a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 16:52:45 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 03 Apr 2023 12:52:45 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 4 commits: Add hashes to unit-ids created by hadrian Message-ID: <642b045dd6624_11425f8bc19041468d8@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: f790e812 by romes at 2023-04-03T17:51:35+01:00 Add hashes to unit-ids created by hadrian (Fix sed command in install makefile) Co-author: @mpickering - - - - - 829e0acb by Matthew Pickering at 2023-04-03T17:52:03+01:00 fixes - - - - - 254fe48f by Matthew Pickering at 2023-04-03T17:52:03+01:00 add flag - - - - - cd7de7c2 by Matthew Pickering at 2023-04-03T17:52:03+01:00 Use hash-unit-ids in release jobs - - - - - 30 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - hadrian/bindist/Makefile - hadrian/hadrian.cabal - hadrian/src/CommandLine.hs - hadrian/src/Context.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/BuildPath.hs - hadrian/src/Hadrian/Builder/Git.hs - hadrian/src/Hadrian/Haskell/Cabal.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - + hadrian/src/Hadrian/Haskell/Hash.hs - + hadrian/src/Hadrian/Haskell/Hash.hs-boot - hadrian/src/Hadrian/Package.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Library.hs - hadrian/src/Rules/Register.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Ghc.hs - hadrian/src/Settings/Builders/Haddock.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Default.hs-boot - hadrian/src/Settings/Flavours/Benchmark.hs - hadrian/src/Settings/Flavours/Development.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c689e100666bf5c9f41f49136b344a84d94c02a8...cd7de7c22aad12d1b945142f800ae4bc95302098 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c689e100666bf5c9f41f49136b344a84d94c02a8...cd7de7c22aad12d1b945142f800ae4bc95302098 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 17:18:14 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 03 Apr 2023 13:18:14 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 11 commits: ghc-heap: remove wrong Addr# coercion (#23181) Message-ID: <642b0a568823a_11425f9190cf415144e@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - ae655c5c by romes at 2023-04-03T18:09:48+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 7313e490 by romes at 2023-04-03T18:09:48+01:00 Validate compatibility of ghcs when loading plugins - - - - - 6ea7335c by romes at 2023-04-03T18:09:48+01:00 Add hashes to unit-ids created by hadrian (Fix sed command in install makefile) Co-author: @mpickering - - - - - 1db3b607 by Matthew Pickering at 2023-04-03T18:09:48+01:00 fixes - - - - - d62cbaf7 by Matthew Pickering at 2023-04-03T18:10:52+01:00 add flag - - - - - 4ab30288 by Matthew Pickering at 2023-04-03T18:10:54+01:00 Use hash-unit-ids in release jobs - - - - - 13 changed files: - .gitlab-ci.yml - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Driver/Session.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Unit/Types.hs - compiler/Setup.hs - compiler/ghc.cabal.in - hadrian/bindist/Makefile - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd7de7c22aad12d1b945142f800ae4bc95302098...4ab30288e9fc996c8ef4add845e77aaa14fbe4ed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd7de7c22aad12d1b945142f800ae4bc95302098...4ab30288e9fc996c8ef4add845e77aaa14fbe4ed You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 17:30:29 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 03 Apr 2023 13:30:29 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 56 commits: Handle records in the renamer Message-ID: <642b0d354e3c1_11425f978a808152425@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 4455ae19 by Sven Tennie at 2023-04-03T17:30:06+00:00 ghc-heap: Decode StgStack and its frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - 8722a465 by Sven Tennie at 2023-04-03T17:30:06+00:00 Splitting StackFrames from Closures: Compiles - - - - - cfe2d005 by Sven Tennie at 2023-04-03T17:30:06+00:00 Fix tests - - - - - 2de3d3e6 by Sven Tennie at 2023-04-03T17:30:06+00:00 Validate - - - - - 95e9596f by Sven Tennie at 2023-04-03T17:30:06+00:00 Remove unnecessary instances - - - - - 01a5fc17 by Sven Tennie at 2023-04-03T17:30:06+00:00 Smaller diff - - - - - 7cf22153 by Sven Tennie at 2023-04-03T17:30:06+00:00 Add comment - - - - - 6e42a07b by Sven Tennie at 2023-04-03T17:30:06+00:00 Add comment - - - - - c6773540 by Sven Tennie at 2023-04-03T17:30:07+00:00 Add C function signatures to Cmm for readability - - - - - 05acf548 by Sven Tennie at 2023-04-03T17:30:07+00:00 Better assertion message - - - - - 8c2bbf8f by Sven Tennie at 2023-04-03T17:30:07+00:00 More iterations to get more underflow frames - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/TyCon/Env.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString/Env.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/ImpExp.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff3bb3ebc18fb94bb8b3ce912a3325c1c00e4fdc...8c2bbf8f83d6d82c66746d3de47266e92408c2fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff3bb3ebc18fb94bb8b3ce912a3325c1c00e4fdc...8c2bbf8f83d6d82c66746d3de47266e92408c2fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 17:59:38 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 03 Apr 2023 13:59:38 -0400 Subject: [Git][ghc/ghc][wip/T23134] 46 commits: Handle records in the renamer Message-ID: <642b140a37ab_11425fa024e781585d2@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23134 at Glasgow Haskell Compiler / GHC Commits: 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8502169d by Krzysztof Gogolewski at 2023-04-03T14:59:57+02:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/TyCon/Env.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString/Env.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/ImpExp.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0c0aa58720c6b313499e4e39e2219e98335eb30...8502169db9384f588751aca2803a2a57acd47a1e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0c0aa58720c6b313499e4e39e2219e98335eb30...8502169db9384f588751aca2803a2a57acd47a1e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 17:59:50 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 03 Apr 2023 13:59:50 -0400 Subject: [Git][ghc/ghc][wip/T23134] Fix unification with oversaturated type families Message-ID: <642b141626e31_11425fa0070d01588b@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23134 at Glasgow Haskell Compiler / GHC Commits: 040986cf by Krzysztof Gogolewski at 2023-04-03T19:59:40+02:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - 4 changed files: - compiler/GHC/Core/Unify.hs - + testsuite/tests/simplCore/should_run/T23134.hs - + testsuite/tests/simplCore/should_run/T23134.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -1,6 +1,6 @@ -- (c) The University of Glasgow 2006 -{-# LANGUAGE ScopedTypeVariables, PatternSynonyms #-} +{-# LANGUAGE ScopedTypeVariables, PatternSynonyms, MultiWayIf #-} {-# LANGUAGE DeriveFunctor #-} @@ -47,6 +47,7 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set import GHC.Exts( oneShot ) +import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Data.FastString @@ -994,6 +995,59 @@ These two TyConApps have the same TyCon at the front but they (legitimately) have different numbers of arguments. They are surelyApart, so we can report that without looking any further (see #15704). + +Note [Unifying type applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Unifying type applications is quite subtle, as we found +in #23134 and #22647, when type families are involved. + +Suppose + type family F a :: Type -> Type + type family G k :: k = r | r -> k + +and consider these examples: + +* F Int ~ F Char, where F is injective + Since F is injective, we can reduce this to Int ~ Char, + therefore SurelyApart. + +* F Int ~ F Char, where F is not injective + Without injectivity, return MaybeApart. + +* G Type ~ G (Type -> Type) Int + Even though G is injective and the arguments to G are different, + we cannot deduce apartness because the RHS is oversaturated. + For example, G might be defined as + G Type = Maybe Int + G (Type -> Type) = Maybe + So we return MaybeApart. + +* F Int Bool ~ F Int Char -- SurelyApart (since Bool is apart from Char) + F Int Bool ~ Maybe a -- MaybeApart + F Int Bool ~ a b -- MaybeApart + F Int Bool ~ Char -> Bool -- MaybeApart + An oversaturated type family can match an application, + whether it's a TyConApp, AppTy or FunTy. Decompose. + +* F Int ~ a b + We cannot decompose a saturated, or under-saturated + type family application. We return MaybeApart. + +To handle all those conditions, unify_ty goes through +the following checks in sequence, where Fn is a type family +of arity n: + +* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n + A saturated application. + Here we can unify arguments in which Fn is injective. +* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n + A saturated type family can match anything - we return MaybeApart. +* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n + An oversaturated type family can be decomposed. +* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n + If we couldn't decompose in the previous step, we return SurelyApart. + +Afterwards, the rest of the code doesn't have to worry about type families. -} -------------- unify_ty: the main workhorse ----------- @@ -1035,31 +1089,63 @@ unify_ty env ty1 (TyVarTy tv2) kco = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco) unify_ty env ty1 ty2 _kco + + -- Handle non-oversaturated type families first + -- See Note [Unifying type applications] + -- + -- (C1) If we have T x1 ... xn ~ T y1 ... yn, use injectivity information of T + -- Note that both sides must not be oversaturated + | Just (tc1, tys1) <- isSatTyFamApp mb_tc_app1 + , Just (tc2, tys2) <- isSatTyFamApp mb_tc_app2 + , tc1 == tc2 + = do { let inj = case tyConInjectivityInfo tc1 of + NotInjective -> repeat False + Injective bs -> bs + + (inj_tys1, noninj_tys1) = partitionByList inj tys1 + (inj_tys2, noninj_tys2) = partitionByList inj tys2 + + ; unify_tys env inj_tys1 inj_tys2 + ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] + don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } + + | Just _ <- isSatTyFamApp mb_tc_app1 -- (C2) A (not-over-saturated) type-family application + = maybeApart MARTypeFamily -- behaves like a type variable; might match + + | Just _ <- isSatTyFamApp mb_tc_app2 -- (C2) A (not-over-saturated) type-family application + -- behaves like a type variable; might unify + -- but doesn't match (as in the TyVarTy case) + = if um_unif env then maybeApart MARTypeFamily else surelyApart + + -- Handle oversaturated type families. + -- + -- They can match an application (TyConApp/FunTy/AppTy), this is handled + -- the same way as in the AppTy case below. + -- + -- If there is no application, an oversaturated type family can only + -- match a type variable or a saturated type family, + -- both of which we handled earlier. So we can say surelyApart. + | Just (tc1, _) <- mb_tc_app1 + , isTypeFamilyTyCon tc1 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + | Just (tc2, _) <- mb_tc_app2 + , isTypeFamilyTyCon tc2 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + -- At this point, neither tc1 nor tc2 can be a type family. | Just (tc1, tys1) <- mb_tc_app1 , Just (tc2, tys2) <- mb_tc_app2 , tc1 == tc2 - = if isInjectiveTyCon tc1 Nominal - then unify_tys env tys1 tys2 - else do { let inj | isTypeFamilyTyCon tc1 - = case tyConInjectivityInfo tc1 of - NotInjective -> repeat False - Injective bs -> bs - | otherwise - = repeat False - - (inj_tys1, noninj_tys1) = partitionByList inj tys1 - (inj_tys2, noninj_tys2) = partitionByList inj tys2 - - ; unify_tys env inj_tys1 inj_tys2 - ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] - don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } - - | isTyFamApp mb_tc_app1 -- A (not-over-saturated) type-family application - = maybeApart MARTypeFamily -- behaves like a type variable; might match - - | isTyFamApp mb_tc_app2 -- A (not-over-saturated) type-family application - , um_unif env -- behaves like a type variable; might unify - = maybeApart MARTypeFamily + = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1) + ; unify_tys env tys1 tys2 + } -- TYPE and CONSTRAINT are not Apart -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim @@ -1160,16 +1246,16 @@ unify_tys env orig_xs orig_ys -- Possibly different saturations of a polykinded tycon -- See Note [Polykinded tycon applications] -isTyFamApp :: Maybe (TyCon, [Type]) -> Bool --- True if we have a saturated or under-saturated type family application +isSatTyFamApp :: Maybe (TyCon, [Type]) -> Maybe (TyCon, [Type]) +-- Return the argument if we have a saturated type family application -- If it is /over/ saturated then we return False. E.g. -- unify_ty (F a b) (c d) where F has arity 1 -- we definitely want to decompose that type application! (#22647) -isTyFamApp (Just (tc, tys)) - = not (isGenerativeTyCon tc Nominal) -- Type family-ish +isSatTyFamApp tapp@(Just (tc, tys)) + | isTypeFamilyTyCon tc && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated -isTyFamApp Nothing - = False + = tapp +isSatTyFamApp _ = Nothing --------------------------------- uVar :: UMEnv ===================================== testsuite/tests/simplCore/should_run/T23134.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE GHC2021, DataKinds, TypeFamilies #-} +module Main where + +import Data.Maybe +import Data.Kind + +main :: IO () +main = putStrLn str + +str :: String +str = case runInstrImpl @(TOption TUnit) mm MAP of + C VOption -> "good" + C Unused -> "bad" + +runInstrImpl :: forall inp out. Value (MapOpRes inp TUnit) -> Instr inp out -> Rec out +runInstrImpl m MAP = C m + +type MapOpRes :: T -> T -> T +type family MapOpRes c :: T -> T +type instance MapOpRes ('TOption x) = 'TOption + +mm :: Value (TOption TUnit) +mm = VOption +{-# NOINLINE mm #-} + +type Value :: T -> Type +data Value t where + VOption :: Value ('TOption t) + Unused :: Value t + +data T = TOption T | TUnit + +data Instr (inp :: T) (out :: T) where + MAP :: Instr c (TOption (MapOpRes c TUnit)) + +data Rec :: T -> Type where + C :: Value r -> Rec (TOption r) ===================================== testsuite/tests/simplCore/should_run/T23134.stdout ===================================== @@ -0,0 +1 @@ +good ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -110,4 +110,4 @@ test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #208 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) - +test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/040986cfb89901a8e7465a99297b65f3060ca466 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/040986cfb89901a8e7465a99297b65f3060ca466 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 20:21:04 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 16:21:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage Message-ID: <642b3530bd692_11425fc48e6ec18598c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6d5bcc20 by Haskell-mouse at 2023-04-03T16:20:59-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 841d10c2 by Krzysztof Gogolewski at 2023-04-03T16:20:59-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Error/Codes.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/ghci/should_run/T16096.stdout - testsuite/tests/ghci/should_run/T21052.stdout - testsuite/tests/linear/should_fail/T18888.stderr - testsuite/tests/module/mod61.stderr - testsuite/tests/overloadedrecflds/should_fail/T13132_duplicaterecflds.stderr - testsuite/tests/parser/should_fail/readFail016.stderr - testsuite/tests/parser/should_fail/readFail023.stderr - testsuite/tests/polykinds/BadKindVar.stderr - testsuite/tests/polykinds/T14710.stderr - testsuite/tests/polykinds/T16762b.stderr - testsuite/tests/polykinds/T7151.stderr - testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr - testsuite/tests/rename/should_compile/T5331.stderr - testsuite/tests/rename/should_fail/T11663.stderr - testsuite/tests/rename/should_fail/rnfail017.stderr - testsuite/tests/rename/should_fail/rnfail019.stderr - testsuite/tests/saks/should_fail/T16722.stderr - testsuite/tests/th/T8412.stderr - testsuite/tests/th/TH_Promoted1Tuple.stderr - testsuite/tests/th/TH_unresolvedInfix2.stderr - testsuite/tests/typecheck/should_fail/T18252a.stderr - testsuite/tests/typecheck/should_fail/T8306.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae2b002e357b7db02c82705508a3b99019a9b763...841d10c29ded1fe856ca127ed0fb4f42a0d6d9df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae2b002e357b7db02c82705508a3b99019a9b763...841d10c29ded1fe856ca127ed0fb4f42a0d6d9df You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 20:44:38 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 03 Apr 2023 16:44:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23208 Message-ID: <642b3ab6856e_11425fcbce9e81935a@gitlab.mail> Sebastian Graf pushed new branch wip/T23208 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23208 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 22:04:00 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 03 Apr 2023 18:04:00 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] Make approximateWC a bit cleverer Message-ID: <642b4d5037c3e_11425fe3d6b44208814@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: d82250e8 by Simon Peyton Jones at 2023-04-03T23:05:03+01:00 Make approximateWC a bit cleverer See the long comment in !10123. Submitting for CI. I'll write a proper commit later if we like this. - - - - - 1 changed file: - compiler/GHC/Tc/Solver.hs Changes: ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -3157,30 +3157,36 @@ defaultTyVarTcS the_tv approximateWC :: Bool -> WantedConstraints -> Cts -- Second return value is the depleted wc --- Third return value is YesFDsCombined <=> multiple constraints for the same fundep floated -- Postcondition: Wanted Cts -- See Note [ApproximateWC] -- See Note [floatKindEqualities vs approximateWC] approximateWC float_past_equalities wc - = float_wc emptyVarSet wc + = float_wc False emptyVarSet wc where - float_wc :: TcTyCoVarSet -> WantedConstraints -> Cts - float_wc trapping_tvs (WC { wc_simple = simples, wc_impl = implics }) - = filterBag (is_floatable trapping_tvs) simples `unionBags` - concatMapBag (float_implic trapping_tvs) implics - float_implic :: TcTyCoVarSet -> Implication -> Cts - float_implic trapping_tvs imp - | float_past_equalities || ic_given_eqs imp /= MaybeGivenEqs - = float_wc new_trapping_tvs (ic_wanted imp) - | otherwise -- Take care with equalities - = emptyCts -- See (1) under Note [ApproximateWC] + float_wc :: Bool -- True <=> there are enclosing equalities + -> TcTyCoVarSet -- Enclosing skolem binders + -> WantedConstraints -> Cts + float_wc encl_eqs trapping_tvs (WC { wc_simple = simples, wc_impl = implics }) + = filterBag (is_floatable encl_eqs trapping_tvs) simples `unionBags` + concatMapBag (float_implic encl_eqs trapping_tvs) implics + + float_implic :: Bool -> TcTyCoVarSet -> Implication -> Cts + float_implic encl_eqs trapping_tvs imp + = float_wc new_encl_eqs new_trapping_tvs (ic_wanted imp) where new_trapping_tvs = trapping_tvs `extendVarSetList` ic_skols imp - - is_floatable skol_tvs ct - | isGivenCt ct = False - | insolubleEqCt ct = False - | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs + new_encl_eqs = encl_eqs || ic_given_eqs imp == MaybeGivenEqs + + is_floatable encl_eqs skol_tvs ct + | isGivenCt ct = False + | insolubleEqCt ct = False + | tyCoVarsOfCt ct `intersectsVarSet` skol_tvs = False + | otherwise + = case classifyPredType (ctPred ct) of + EqPred {} -> float_past_equalities || not encl_eqs + ClassPred {} -> True + IrredPred {} -> True + ForAllPred {} -> False {- Note [ApproximateWC] ~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d82250e8ab66107ed004878948a09f1f7b960472 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d82250e8ab66107ed004878948a09f1f7b960472 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 23:31:40 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 19:31:40 -0400 Subject: [Git][ghc/ghc][master] Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage Message-ID: <642b61dcde15c_11425ffa0a3e82205b9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 30 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/linear/should_fail/T18888.stderr - testsuite/tests/module/mod61.stderr - testsuite/tests/overloadedrecflds/should_fail/T13132_duplicaterecflds.stderr - testsuite/tests/parser/should_fail/readFail016.stderr - testsuite/tests/parser/should_fail/readFail023.stderr - testsuite/tests/polykinds/BadKindVar.stderr - testsuite/tests/polykinds/T14710.stderr - testsuite/tests/polykinds/T16762b.stderr - testsuite/tests/polykinds/T7151.stderr - testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr - testsuite/tests/rename/should_compile/T5331.stderr - testsuite/tests/rename/should_fail/T11663.stderr - testsuite/tests/rename/should_fail/rnfail017.stderr - testsuite/tests/rename/should_fail/rnfail019.stderr - testsuite/tests/saks/should_fail/T16722.stderr - testsuite/tests/th/T8412.stderr - testsuite/tests/th/TH_Promoted1Tuple.stderr - testsuite/tests/th/TH_unresolvedInfix2.stderr - testsuite/tests/typecheck/should_fail/T18252a.stderr - testsuite/tests/typecheck/should_fail/T8306.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearMultiAppPat.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearMultiPat.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_NonlinearSinglePat.stderr - testsuite/tests/typecheck/should_fail/TyAppPat_ScopedTyVarConflict.stderr - testsuite/tests/typecheck/should_fail/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b092910ac18a2b5dc97a29ced9fc469c663a03b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b092910ac18a2b5dc97a29ced9fc469c663a03b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 3 23:32:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 19:32:25 -0400 Subject: [Git][ghc/ghc][master] Fixes around unsafeCoerce# Message-ID: <642b6209ee4b1_11425ff84b7002242f3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 5 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Tc/Module.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/ghci/should_run/T16096.stdout - testsuite/tests/ghci/should_run/T21052.stdout Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -3845,50 +3845,6 @@ pseudoop "seq" -- This fixity is only the one picked up by Haddock. If you -- change this, do update 'ghcPrimIface' in 'GHC.Iface.Load'. -pseudoop "unsafeCoerce#" - o -> p - { The function 'unsafeCoerce#' allows you to side-step the typechecker entirely. That - is, it allows you to coerce any type into any other type. If you use this function, - you had better get it right, otherwise segmentation faults await. It is generally - used when you want to write a program that you know is well-typed, but where Haskell's - type system is not expressive enough to prove that it is well typed. - - The following uses of 'unsafeCoerce#' are supposed to work (i.e. not lead to - spurious compile-time or run-time crashes): - - * Casting any lifted type to 'Any' - - * Casting 'Any' back to the real type - - * Casting an unboxed type to another unboxed type of the same size. - (Casting between floating-point and integral types does not work. - See the "GHC.Float" module for functions to do work.) - - * Casting between two types that have the same runtime representation. One case is when - the two types differ only in "phantom" type parameters, for example - @'Ptr' 'Int'@ to @'Ptr' 'Float'@, or @['Int']@ to @['Float']@ when the list is - known to be empty. Also, a @newtype@ of a type @T@ has the same representation - at runtime as @T at . - - Other uses of 'unsafeCoerce#' are undefined. In particular, you should not use - 'unsafeCoerce#' to cast a T to an algebraic data type D, unless T is also - an algebraic data type. For example, do not cast @'Int'->'Int'@ to 'Bool', even if - you later cast that 'Bool' back to @'Int'->'Int'@ before applying it. The reasons - have to do with GHC's internal representation details (for the cognoscenti, data values - can be entered but function closures cannot). If you want a safe type to cast things - to, use 'Any', which is not an algebraic data type. - - } - with can_fail = True - --- NB. It is tempting to think that casting a value to a type that it doesn't have is safe --- as long as you don't "do anything" with the value in its cast form, such as seq on it. This --- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type, --- Bad Things Might Happen. See bug #1616: in this case we cast a function of type (a,b) -> (a,b) --- to () -> () and back again. The strictness analyser saw that the function was strict, but --- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed --- a new (), with the result that the code ended up with "case () of (a,b) -> ...". - primop TraceEventOp "traceEvent#" GenPrimOp Addr# -> State# s -> State# s { Emits an event via the RTS tracing framework. The contents ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -104,7 +104,7 @@ import GHC.Iface.Env ( externaliseName ) import GHC.Iface.Make ( coAxiomToIfaceDecl ) import GHC.Iface.Load -import GHC.Builtin.Types ( unitTy, mkListTy ) +import GHC.Builtin.Types ( mkListTy, anyTypeOfKind ) import GHC.Builtin.Names import GHC.Builtin.Utils @@ -2283,8 +2283,8 @@ We don't bother with the tcl_th_bndrs environment either. -- | The returned [Id] is the list of new Ids bound by this statement. It can -- be used to extend the InteractiveContext via extendInteractiveContext. -- --- The returned TypecheckedHsExpr is of type IO [ () ], a list of the bound --- values, coerced to (). +-- The returned TypecheckedHsExpr is of type IO [ Any ], a list of the bound +-- values, coerced to Any. tcRnStmt :: HscEnv -> GhciLStmt GhcPs -> IO (Messages TcRnMessage, Maybe ([Id], LHsExpr GhcTc, FixityEnv)) tcRnStmt hsc_env rdr_stmt @@ -2578,13 +2578,16 @@ The reason for -fno-it is explained in #14336. `it` can lead to the repl leaking memory as it is repeatedly queried. -} +any_lifted :: Type +any_lifted = anyTypeOfKind liftedTypeKind + -- | Typecheck the statements given and then return the results of the --- statement in the form 'IO [()]'. +-- statement in the form 'IO [Any]'. tcGhciStmts :: [GhciLStmt GhcRn] -> TcM PlanResult tcGhciStmts stmts = do { ioTyCon <- tcLookupTyCon ioTyConName ; ret_id <- tcLookupId returnIOName -- return @ IO - ; let ret_ty = mkListTy unitTy + ; let ret_ty = mkListTy any_lifted io_ret_ty = mkTyConApp ioTyCon [ret_ty] tc_io_stmts = tcStmtsAndThen (HsDoStmt GhciStmtCtxt) tcDoStmt stmts (mkCheckExpType io_ret_ty) @@ -2607,28 +2610,31 @@ tcGhciStmts stmts ; traceTc "GHC.Tc.Module.tcGhciStmts: done" empty -- ret_expr is the expression - -- returnIO @[()] [unsafeCoerce# () x, .., unsafeCoerce# () z] + -- returnIO @[Any] [unsafeCoerce# @Any x, .., unsafeCoerce# @Any z] -- -- Despite the inconvenience of building the type applications etc, -- this *has* to be done in type-annotated post-typecheck form -- because we are going to return a list of *polymorphic* values - -- coerced to type (). If we built a *source* stmt + -- coerced to type Any. If we built a *source* stmt -- return [coerce x, ..., coerce z] -- then the type checker would instantiate x..z, and we wouldn't -- get their *polymorphic* values. (And we'd get ambiguity errs -- if they were overloaded, since they aren't applied to anything.) + -- + -- We use Any rather than a dummy type such as () because of + -- the rules of unsafeCoerce#; see Unsafe/Coerce.hs for the details. ; AnId unsafe_coerce_id <- tcLookupGlobal unsafeCoercePrimName -- We use unsafeCoerce# here because of (U11) in -- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce ; let ret_expr = nlHsApp (nlHsTyApp ret_id [ret_ty]) $ - noLocA $ ExplicitList unitTy $ + noLocA $ ExplicitList any_lifted $ map mk_item ids mk_item id = unsafe_coerce_id `nlHsTyApp` [ getRuntimeRep (idType id) - , getRuntimeRep unitTy - , idType id, unitTy] + , getRuntimeRep any_lifted + , idType id, any_lifted] `nlHsApp` nlHsVar id stmts = tc_stmts ++ [noLocA (mkLastStmt ret_expr)] ===================================== libraries/base/Unsafe/Coerce.hs ===================================== @@ -244,11 +244,11 @@ unsafeEqualityProof = case unsafeEqualityProof @a @b of UnsafeRefl -> UnsafeRefl -- Why delay inlining to Phase 1? Because of the RULES for map/unsafeCoerce; -- see (U8) in Note [Implementing unsafeCoerce] --- | Coerce a value from one type to another, bypassing the type-checker. +-- | `unsafeCoerce` coerces a value from one type to another, bypassing the type-checker. -- -- There are several legitimate ways to use 'unsafeCoerce': -- --- 1. To coerce e.g. @Int@ to @HValue@, put it in a list of @HValue@, +-- 1. To coerce a lifted type such as @Int@ to @Any@, put it in a list of @Any@, -- and then later coerce it back to @Int@ before using it. -- -- 2. To produce e.g. @(a+b) :~: (b+a)@ from @unsafeCoerce Refl at . @@ -269,15 +269,35 @@ unsafeEqualityProof = case unsafeEqualityProof @a @b of UnsafeRefl -> UnsafeRefl -- are the same -- but the proof of that relies on the complex, trusted -- implementation of @Typeable at . -- --- 4. The "reflection trick", which takes advantage of the fact that in +-- 4. (superseded) The "reflection trick", which takes advantage of the fact that in -- @class C a where { op :: ty }@, we can safely coerce between @C a@ and @ty@ -- (which have different kinds!) because it's really just a newtype. -- Note: there is /no guarantee, at all/ that this behavior will be supported -- into perpetuity. +-- It is now preferred to use `withDict` in @GHC.Magic.Dict@, which +-- is type-safe. See Note [withDict] in GHC.Tc.Instance.Class for details. -- +-- 5. (superseded) Casting between two types which have exactly the same structure: +-- between a newtype of T and T, or between types which differ only +-- in "phantom" type parameters. +-- It is now preferred to use `coerce` from @Data.Coerce@, which +-- is type-safe. -- --- For safe zero-cost coercions you can instead use the 'Data.Coerce.coerce' function from --- "Data.Coerce". +-- Other uses of 'unsafeCoerce' are undefined. In particular, you should not use +-- 'unsafeCoerce' to cast a T to an algebraic data type D, unless T is also +-- an algebraic data type. For example, do not cast @'Int'->'Int'@ to 'Bool', even if +-- you later cast that 'Bool' back to @'Int'->'Int'@ before applying it. The reasons +-- have to do with GHC's internal representation details (for the cognoscenti, data values +-- can be entered but function closures cannot). If you want a safe type to cast things +-- to, use 'Any', which is not an algebraic data type. + +-- NB. It is tempting to think that casting a value to a type that it doesn't have is safe +-- as long as you don't "do anything" with the value in its cast form, such as seq on it. This +-- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type, +-- Bad Things Might Happen. See bug #1616: in this case we cast a function of type (a,b) -> (a,b) +-- to () -> () and back again. The strictness analyser saw that the function was strict, but +-- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed +-- a new (), with the result that the code ended up with "case () of (a,b) -> ...". unsafeCoerce :: forall (a :: Type) (b :: Type) . a -> b unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x ===================================== testsuite/tests/ghci/should_run/T16096.stdout ===================================== @@ -13,12 +13,16 @@ letrec { x = GHC.Enum.enumFrom @GHC.Types.Int $dEnum (GHC.Types.I# 1#); } in x; } in GHC.Base.returnIO - @[()] + @[GHC.Types.Any] (GHC.Types.: - @() + @GHC.Types.Any (Unsafe.Coerce.unsafeCoerce# - @GHC.Types.LiftedRep @GHC.Types.LiftedRep @[GHC.Types.Int] @() x) - (GHC.Types.[] @())) + @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @[GHC.Types.Int] + @GHC.Types.Any + x) + (GHC.Types.[] @GHC.Types.Any)) @@ -36,11 +40,15 @@ letrec { x = GHC.Enum.enumFrom @GHC.Types.Int $dEnum (GHC.Types.I# 1#); } in x; } in GHC.Base.returnIO - @[()] + @[GHC.Types.Any] (GHC.Types.: - @() + @GHC.Types.Any (Unsafe.Coerce.unsafeCoerce# - @GHC.Types.LiftedRep @GHC.Types.LiftedRep @[GHC.Types.Int] @() x) - (GHC.Types.[] @())) + @GHC.Types.LiftedRep + @GHC.Types.LiftedRep + @[GHC.Types.Int] + @GHC.Types.Any + x) + (GHC.Types.[] @GHC.Types.Any)) ===================================== testsuite/tests/ghci/should_run/T21052.stdout ===================================== @@ -1,10 +1,10 @@ ==================== CodeGenInput STG: ==================== -BCO_toplevel :: GHC.Types.IO [()] +BCO_toplevel :: GHC.Types.IO [GHC.Types.Any] [LclId] = {} \u [] let { - sat :: [()] + sat :: [GHC.Types.Any] [LclId] = :! [GHC.Tuple.Prim.() GHC.Types.[]]; } in GHC.Base.returnIO sat; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/220a7a48cabdcfd2ef7bf5dbe3fd6df99e8d3c5b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/220a7a48cabdcfd2ef7bf5dbe3fd6df99e8d3c5b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 00:37:59 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 03 Apr 2023 20:37:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fcheck-prim-bounds-9.6 Message-ID: <642b7167c778c_11425f111aa9802258cb@gitlab.mail> Matthew Craven pushed new branch wip/fcheck-prim-bounds-9.6 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fcheck-prim-bounds-9.6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 01:04:03 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 03 Apr 2023 21:04:03 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage Message-ID: <642b7783a9731_11425f117aa8f823202d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 3af52963 by Matthew Craven at 2023-04-03T21:03:55-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - ebcfaf7f by Matthew Craven at 2023-04-03T21:03:55-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - 74a98378 by sheaf at 2023-04-03T21:03:59-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Occurrence.hs - libraries/base/Data/Array/Byte.hs - libraries/base/Foreign/Marshal/Utils.hs - libraries/base/Unsafe/Coerce.hs - libraries/ghc-prim/changelog.md - rts/RtsMessages.c - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray2.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray3.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadInt64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadSmallArray.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord8ArrayAsWord32.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyAddrToByteArray.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyByteArray.hs - testsuite/tests/codeGen/should_fail/all.T - + testsuite/tests/codeGen/should_run/CheckBoundsOK.hs - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/ghci/should_run/T16096.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/841d10c29ded1fe856ca127ed0fb4f42a0d6d9df...74a983783cab24435658a1da81b19e85f41baa10 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/841d10c29ded1fe856ca127ed0fb4f42a0d6d9df...74a983783cab24435658a1da81b19e85f41baa10 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 01:57:52 2023 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Mon, 03 Apr 2023 21:57:52 -0400 Subject: [Git][ghc/ghc][wip/T23203] 13 commits: JS: Linker: use saturated JExpr Message-ID: <642b84205de2c_11425f1273a9d0237772@gitlab.mail> Ryan Scott pushed to branch wip/T23203 at Glasgow Haskell Compiler / GHC Commits: 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 55a0200b by Ryan Scott at 2023-04-03T21:57:41-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 19 changed files: - .gitlab-ci.yml - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Parser.y - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.8.1-notes.rst - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/30faa3111bdee971a3743548887a946ce828ea66...55a0200bf5df26b679c53c930e5916b1ed6492b8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/30faa3111bdee971a3743548887a946ce828ea66...55a0200bf5df26b679c53c930e5916b1ed6492b8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 02:54:24 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 22:54:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/angerman/debug-darwin Message-ID: <642b9160edddf_11425f137ec3c82435a@gitlab.mail> Moritz Angermann pushed new branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/angerman/debug-darwin You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 02:58:41 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 22:58:41 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] disable more Message-ID: <642b9261189b7_11425f13177ba02459ee@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 20d02e80 by Moritz Angermann at 2023-04-04T10:56:28+08:00 disable more - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -449,228 +449,228 @@ stack-hadrian-build: # Testing reinstallable ghc codepath #################################### -test-cabal-reinstall-x86_64-linux-deb10: - extends: nightly-x86_64-linux-deb10-validate - stage: full-build - variables: - REINSTALL_GHC: "yes" - BUILD_FLAVOUR: validate - TEST_ENV: "x86_64-linux-deb10-cabal-install" - rules: - - if: $NIGHTLY - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-reinstall.*/' +# test-cabal-reinstall-x86_64-linux-deb10: +# extends: nightly-x86_64-linux-deb10-validate +# stage: full-build +# variables: +# REINSTALL_GHC: "yes" +# BUILD_FLAVOUR: validate +# TEST_ENV: "x86_64-linux-deb10-cabal-install" +# rules: +# - if: $NIGHTLY +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-reinstall.*/' ######################################## # Testing ABI is invariant across builds ######################################## -abi-test-nightly: - stage: full-build - needs: - - job: nightly-x86_64-linux-fedora33-release-hackage - - job: nightly-x86_64-linux-fedora33-release - tags: - - x86_64-linux - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" - dependencies: null - before_script: - - mkdir -p normal - - mkdir -p hackage - - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C normal/ - - tar -xf ghc-x86_64-linux-fedora33-release-hackage_docs.tar.xz -C hackage/ - script: - - .gitlab/ci.sh compare_interfaces_of "normal/ghc-*" "hackage/ghc-*" - artifacts: - paths: - - out - rules: - - if: $NIGHTLY +# abi-test-nightly: +# stage: full-build +# needs: +# - job: nightly-x86_64-linux-fedora33-release-hackage +# - job: nightly-x86_64-linux-fedora33-release +# tags: +# - x86_64-linux +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" +# dependencies: null +# before_script: +# - mkdir -p normal +# - mkdir -p hackage +# - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C normal/ +# - tar -xf ghc-x86_64-linux-fedora33-release-hackage_docs.tar.xz -C hackage/ +# script: +# - .gitlab/ci.sh compare_interfaces_of "normal/ghc-*" "hackage/ghc-*" +# artifacts: +# paths: +# - out +# rules: +# - if: $NIGHTLY ############################################################ # Packaging ############################################################ -doc-tarball: - stage: packaging - needs: - - job: x86_64-linux-deb10-numa-slow-validate - optional: true - - job: nightly-x86_64-linux-deb10-validate - optional: true - - job: release-x86_64-linux-deb10-release - optional: true - - - job: x86_64-windows-validate - optional: true - - job: nightly-x86_64-windows-validate - optional: true - - job: release-x86_64-windows-release+no_split_sections - optional: true - - tags: - - x86_64-linux - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - dependencies: null - variables: - LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" - WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" - artifacts: - paths: - - haddock.html.tar.xz - - libraries.html.tar.xz - - users_guide.html.tar.xz - - index.html - - "*.pdf" - script: - - | - mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ - || mv "ghc-x86_64-linux-deb10-validate.tar.xz" "$LINUX_BINDIST" \ - || mv "ghc-x86_64-linux-deb10-release.tar.xz" "$LINUX_BINDIST" \ - || true - mv "ghc-x86_64-windows-validate.tar.xz" "$WINDOWS_BINDIST" \ - || mv "ghc-x86_64-windows-release+no_split_sections.tar.xz" "$WINDOWS_BINDIST" \ - || true - if [ ! -f "$LINUX_BINDIST" ]; then - echo "Error: $LINUX_BINDIST does not exist. Did the Debian 9 job fail?" - exit 1 - fi - if [ ! -f "$WINDOWS_BINDIST" ]; then - echo "Error: $WINDOWS_BINDIST does not exist. Did the 64-bit Windows job fail?" - exit 1 - fi - - rm -Rf docs - - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST - - ls -lh - - mv docs/*.tar.xz docs/index.html . - -hackage-doc-tarball: - stage: packaging - needs: - - job: nightly-x86_64-linux-fedora33-release-hackage - optional: true - - job: release-x86_64-linux-fedora33-release-hackage - optional: true - - job: source-tarball - tags: - - x86_64-linux - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - dependencies: null - variables: - # Don't clone the git repo.. - GIT_STRATEGY: none - # Don't attempt to boot a source tarball - NO_BOOT: "1" - artifacts: - paths: - - hackage_docs - before_script: - - tar -xf ghc-*[0-9]-src.tar.xz - - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C ghc*/ - script: - - cd ghc*/ - - mv .gitlab/rel_eng/upload_ghc_libs.py . - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - - ./upload_ghc_libs.py prepare --bindist ghc*linux/ - - mv .upload-libs/docs ../hackage_docs - rules: - - if: $NIGHTLY - - if: '$RELEASE_JOB == "yes"' - -source-tarball: - stage: full-build - tags: - - x86_64-linux - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - dependencies: [] - artifacts: - paths: - - ghc-*.tar.xz - script: - - sudo chown ghc:ghc -R . - - ./boot - - ./configure - - ./hadrian/build source-dist - - mv _build/source-dist/*.xz . - rules: - - if: $NIGHTLY - - if: '$RELEASE_JOB == "yes"' - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' - -generate-hadrian-bootstrap-sources: - stage: full-build - tags: - - x86_64-linux - image: "$DOCKER_IMAGE" - dependencies: [] - parallel: *bootstrap_matrix - artifacts: - paths: - - hadrian-bootstrap-sources-*.tar.gz - script: - - bash -c "[ $($GHC --numeric-version) = $GHC_VERSION ] || { echo $GHC_VERSION is not the same as the version of $GHC && exit 1; }" - - python3 ./hadrian/bootstrap/bootstrap.py -w $GHC fetch -o hadrian-bootstrap-sources-$GHC_VERSION - rules: - - if: $NIGHTLY - - if: '$RELEASE_JOB == "yes"' - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' - - -package-hadrian-bootstrap-sources: - stage: full-build - tags: - - x86_64-linux - needs: ["generate-hadrian-bootstrap-sources"] - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - artifacts: - paths: - - hadrian-bootstrap-sources-all.tar.gz - script: - - tar -czvf hadrian-bootstrap-sources-all.tar.gz hadrian-bootstrap-sources-*.tar.gz - rules: - - if: $NIGHTLY - - if: '$RELEASE_JOB == "yes"' - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' - -test-bootstrap: - stage: full-build - needs: [generate-hadrian-bootstrap-sources, source-tarball] - tags: - - x86_64-linux - image: "$DOCKER_IMAGE" - parallel: *bootstrap_matrix - dependencies: null - script: - - sudo chown ghc:ghc -R . - - mkdir test-bootstrap - - tar -xf ghc-*[0-9]-src.tar.xz -C test-bootstrap - - tar -xf ghc-*-testsuite.tar.xz -C test-bootstrap - - cp hadrian-bootstrap-sources-$GHC_VERSION.tar.gz test-bootstrap/ghc-* - - pushd test-bootstrap/ghc-* - - python3 ./hadrian/bootstrap/bootstrap.py -w $GHC --bootstrap-sources hadrian-bootstrap-sources-$GHC_VERSION.tar.gz - - export HADRIAN_PATH="$PWD/_build/bin/hadrian" - - .gitlab/ci.sh setup - # Bootstrapping should not depend on HAPPY or ALEX so set them to false - # so the build fails if they are invoked. - - export HAPPY=/bin/false; export ALEX=/bin/false - - .gitlab/ci.sh configure - - .gitlab/ci.sh build_hadrian - - .gitlab/ci.sh test_hadrian - - popd - - rm -Rf test-bootstrap - variables: - # Don't record performance benchmarks - TEST_ENV: "" - BIN_DIST_NAME: "ghc-x86_64-deb10-linux" - BUILD_FLAVOUR: "validate" - NO_BOOT: "1" - rules: - - if: $NIGHTLY - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' - - if: '$RELEASE_JOB == "yes"' - when: always - variables: - BUILD_FLAVOUR: "release" +# doc-tarball: +# stage: packaging +# needs: +# - job: x86_64-linux-deb10-numa-slow-validate +# optional: true +# - job: nightly-x86_64-linux-deb10-validate +# optional: true +# - job: release-x86_64-linux-deb10-release +# optional: true + +# - job: x86_64-windows-validate +# optional: true +# - job: nightly-x86_64-windows-validate +# optional: true +# - job: release-x86_64-windows-release+no_split_sections +# optional: true + +# tags: +# - x86_64-linux +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# dependencies: null +# variables: +# LINUX_BINDIST: "ghc-x86_64-linux-deb10.tar.xz" +# WINDOWS_BINDIST: "ghc-x86_64-windows.tar.xz" +# artifacts: +# paths: +# - haddock.html.tar.xz +# - libraries.html.tar.xz +# - users_guide.html.tar.xz +# - index.html +# - "*.pdf" +# script: +# - | +# mv "ghc-x86_64-linux-deb10-numa-slow-validate.tar.xz" "$LINUX_BINDIST" \ +# || mv "ghc-x86_64-linux-deb10-validate.tar.xz" "$LINUX_BINDIST" \ +# || mv "ghc-x86_64-linux-deb10-release.tar.xz" "$LINUX_BINDIST" \ +# || true +# mv "ghc-x86_64-windows-validate.tar.xz" "$WINDOWS_BINDIST" \ +# || mv "ghc-x86_64-windows-release+no_split_sections.tar.xz" "$WINDOWS_BINDIST" \ +# || true +# if [ ! -f "$LINUX_BINDIST" ]; then +# echo "Error: $LINUX_BINDIST does not exist. Did the Debian 9 job fail?" +# exit 1 +# fi +# if [ ! -f "$WINDOWS_BINDIST" ]; then +# echo "Error: $WINDOWS_BINDIST does not exist. Did the 64-bit Windows job fail?" +# exit 1 +# fi +# - rm -Rf docs +# - bash -ex distrib/mkDocs/mkDocs $LINUX_BINDIST $WINDOWS_BINDIST +# - ls -lh +# - mv docs/*.tar.xz docs/index.html . + +# hackage-doc-tarball: +# stage: packaging +# needs: +# - job: nightly-x86_64-linux-fedora33-release-hackage +# optional: true +# - job: release-x86_64-linux-fedora33-release-hackage +# optional: true +# - job: source-tarball +# tags: +# - x86_64-linux +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# dependencies: null +# variables: +# # Don't clone the git repo.. +# GIT_STRATEGY: none +# # Don't attempt to boot a source tarball +# NO_BOOT: "1" +# artifacts: +# paths: +# - hackage_docs +# before_script: +# - tar -xf ghc-*[0-9]-src.tar.xz +# - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C ghc*/ +# script: +# - cd ghc*/ +# - mv .gitlab/rel_eng/upload_ghc_libs.py . +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# - ./upload_ghc_libs.py prepare --bindist ghc*linux/ +# - mv .upload-libs/docs ../hackage_docs +# rules: +# - if: $NIGHTLY +# - if: '$RELEASE_JOB == "yes"' + +# source-tarball: +# stage: full-build +# tags: +# - x86_64-linux +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# dependencies: [] +# artifacts: +# paths: +# - ghc-*.tar.xz +# script: +# - sudo chown ghc:ghc -R . +# - ./boot +# - ./configure +# - ./hadrian/build source-dist +# - mv _build/source-dist/*.xz . +# rules: +# - if: $NIGHTLY +# - if: '$RELEASE_JOB == "yes"' +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' + +# generate-hadrian-bootstrap-sources: +# stage: full-build +# tags: +# - x86_64-linux +# image: "$DOCKER_IMAGE" +# dependencies: [] +# parallel: *bootstrap_matrix +# artifacts: +# paths: +# - hadrian-bootstrap-sources-*.tar.gz +# script: +# - bash -c "[ $($GHC --numeric-version) = $GHC_VERSION ] || { echo $GHC_VERSION is not the same as the version of $GHC && exit 1; }" +# - python3 ./hadrian/bootstrap/bootstrap.py -w $GHC fetch -o hadrian-bootstrap-sources-$GHC_VERSION +# rules: +# - if: $NIGHTLY +# - if: '$RELEASE_JOB == "yes"' +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' + + +# package-hadrian-bootstrap-sources: +# stage: full-build +# tags: +# - x86_64-linux +# needs: ["generate-hadrian-bootstrap-sources"] +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# artifacts: +# paths: +# - hadrian-bootstrap-sources-all.tar.gz +# script: +# - tar -czvf hadrian-bootstrap-sources-all.tar.gz hadrian-bootstrap-sources-*.tar.gz +# rules: +# - if: $NIGHTLY +# - if: '$RELEASE_JOB == "yes"' +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' + +# test-bootstrap: +# stage: full-build +# needs: [generate-hadrian-bootstrap-sources, source-tarball] +# tags: +# - x86_64-linux +# image: "$DOCKER_IMAGE" +# parallel: *bootstrap_matrix +# dependencies: null +# script: +# - sudo chown ghc:ghc -R . +# - mkdir test-bootstrap +# - tar -xf ghc-*[0-9]-src.tar.xz -C test-bootstrap +# - tar -xf ghc-*-testsuite.tar.xz -C test-bootstrap +# - cp hadrian-bootstrap-sources-$GHC_VERSION.tar.gz test-bootstrap/ghc-* +# - pushd test-bootstrap/ghc-* +# - python3 ./hadrian/bootstrap/bootstrap.py -w $GHC --bootstrap-sources hadrian-bootstrap-sources-$GHC_VERSION.tar.gz +# - export HADRIAN_PATH="$PWD/_build/bin/hadrian" +# - .gitlab/ci.sh setup +# # Bootstrapping should not depend on HAPPY or ALEX so set them to false +# # so the build fails if they are invoked. +# - export HAPPY=/bin/false; export ALEX=/bin/false +# - .gitlab/ci.sh configure +# - .gitlab/ci.sh build_hadrian +# - .gitlab/ci.sh test_hadrian +# - popd +# - rm -Rf test-bootstrap +# variables: +# # Don't record performance benchmarks +# TEST_ENV: "" +# BIN_DIST_NAME: "ghc-x86_64-deb10-linux" +# BUILD_FLAVOUR: "validate" +# NO_BOOT: "1" +# rules: +# - if: $NIGHTLY +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-bootstrap.*/' +# - if: '$RELEASE_JOB == "yes"' +# when: always +# variables: +# BUILD_FLAVOUR: "release" ############################################################ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/20d02e80af1d4ec7c56127f5ea7d3970d43352b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/20d02e80af1d4ec7c56127f5ea7d3970d43352b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:00:12 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:00:12 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] disable even more Message-ID: <642b92bca3b09_11425f137f408c24669d@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 613b12d9 by Moritz Angermann at 2023-04-04T10:59:40+08:00 disable even more - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -381,54 +381,54 @@ hadrian-ghc-in-ghci: # Hadrian Multi-Repl ############################################################ -hadrian-multi: - stage: testing - needs: - - job: x86_64-linux-fedora33-release - optional: true - - job: nightly-x86_64-linux-fedora33-release - optional: true - - job: release-x86_64-linux-fedora33-release - optional: true - dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" - before_script: - # workaround for docker permissions - - sudo chown ghc:ghc -R . - variables: - GHC_FLAGS: -Werror - CONFIGURE_ARGS: --enable-bootstrap-with-devel-snapshot - tags: - - x86_64-linux - script: - - export BOOT_HC=$GHC - - root=$(pwd)/ghc - - ls - - | - mkdir tmp - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp - pushd tmp/ghc-*/ - ./configure --prefix=$root - make install - popd - rm -Rf tmp - - export HC=$root/bin/ghc - # This GHC means, use this GHC to configure with - - export GHC=$root/bin/ghc - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - # Now GHC means, use this GHC for hadrian - - export GHC=$BOOT_HC - # Load hadrian-multi then immediately exit and check the modules loaded - - echo ":q" | hadrian/ghci-multi -j`mk/detect-cpu-count.sh`| tail -n2 | grep "Ok," - after_script: - - .gitlab/ci.sh save_cache - cache: - key: hadrian-ghci-$CACHE_REV - paths: - - cabal-cache - rules: - - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' +# hadrian-multi: +# stage: testing +# needs: +# - job: x86_64-linux-fedora33-release +# optional: true +# - job: nightly-x86_64-linux-fedora33-release +# optional: true +# - job: release-x86_64-linux-fedora33-release +# optional: true +# dependencies: null +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" +# before_script: +# # workaround for docker permissions +# - sudo chown ghc:ghc -R . +# variables: +# GHC_FLAGS: -Werror +# CONFIGURE_ARGS: --enable-bootstrap-with-devel-snapshot +# tags: +# - x86_64-linux +# script: +# - export BOOT_HC=$GHC +# - root=$(pwd)/ghc +# - ls +# - | +# mkdir tmp +# tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp +# pushd tmp/ghc-*/ +# ./configure --prefix=$root +# make install +# popd +# rm -Rf tmp +# - export HC=$root/bin/ghc +# # This GHC means, use this GHC to configure with +# - export GHC=$root/bin/ghc +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# # Now GHC means, use this GHC for hadrian +# - export GHC=$BOOT_HC +# # Load hadrian-multi then immediately exit and check the modules loaded +# - echo ":q" | hadrian/ghci-multi -j`mk/detect-cpu-count.sh`| tail -n2 | grep "Ok," +# after_script: +# - .gitlab/ci.sh save_cache +# cache: +# key: hadrian-ghci-$CACHE_REV +# paths: +# - cabal-cache +# rules: +# - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' ############################################################ # stack-hadrian-build @@ -437,13 +437,13 @@ hadrian-multi: # Verify that Hadrian builds with stack. Note that we don't actually perform a # build of GHC itself; we merely test that the Hadrian executable builds and # works (by invoking `hadrian --version`). -stack-hadrian-build: - extends: hadrian-ghc-in-ghci - stage: quick-build - script: - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - - hadrian/build-stack --version +# stack-hadrian-build: +# extends: hadrian-ghc-in-ghci +# stage: quick-build +# script: +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# - hadrian/build-stack --version #################################### # Testing reinstallable ghc codepath View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/613b12d9530ebcd6592195148cc0d76de27c8a7c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/613b12d9530ebcd6592195148cc0d76de27c8a7c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:01:50 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:01:50 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] And more Message-ID: <642b931e9e813_11425f138b7d20247117@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 5d3a588f by Moritz Angermann at 2023-04-04T11:01:27+08:00 And more - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -707,382 +707,382 @@ hadrian-ghc-in-ghci: branch: "upstream-testing" strategy: "depend" -hackage-lint: - needs: - - job: x86_64-linux-deb10-numa-slow-validate - optional: true - artifacts: false - - job: nightly-x86_64-linux-deb10-numa-slow-validate - optional: true - artifacts: false - extends: .hackage - variables: - SLOW_VALIDATE: 1 - EXTRA_HC_OPTS: "-dlint" - # No for release jobs because there isn't a slow-valdate bindist. There is an - # automatic pipeline for release bindists (see release-hackage-lint) - rules: - - if: '$RELEASE_JOB != "yes"' - when: manual +# hackage-lint: +# needs: +# - job: x86_64-linux-deb10-numa-slow-validate +# optional: true +# artifacts: false +# - job: nightly-x86_64-linux-deb10-numa-slow-validate +# optional: true +# artifacts: false +# extends: .hackage +# variables: +# SLOW_VALIDATE: 1 +# EXTRA_HC_OPTS: "-dlint" +# # No for release jobs because there isn't a slow-valdate bindist. There is an +# # automatic pipeline for release bindists (see release-hackage-lint) +# rules: +# - if: '$RELEASE_JOB != "yes"' +# when: manual -hackage-label-lint: - needs: - - job: x86_64-linux-deb10-numa-slow-validate - optional: true - artifacts: false - extends: .hackage - variables: - SLOW_VALIDATE: 1 - EXTRA_HC_OPTS: "-dlint" - rules: - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' +# hackage-label-lint: +# needs: +# - job: x86_64-linux-deb10-numa-slow-validate +# optional: true +# artifacts: false +# extends: .hackage +# variables: +# SLOW_VALIDATE: 1 +# EXTRA_HC_OPTS: "-dlint" +# rules: +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*user-facing.*/' -# The head.hackage job is split into two jobs because enabling `-dlint` -# affects the total allocation numbers for the simplifier portion significantly. -nightly-hackage-lint: - needs: - - job: nightly-x86_64-linux-deb10-numa-slow-validate - optional: true - artifacts: false - rules: - - if: $NIGHTLY - variables: - NIGHTLY: "$NIGHTLY" - extends: .hackage - variables: - SLOW_VALIDATE: 1 - EXTRA_HC_OPTS: "-dlint" +# # The head.hackage job is split into two jobs because enabling `-dlint` +# # affects the total allocation numbers for the simplifier portion significantly. +# nightly-hackage-lint: +# needs: +# - job: nightly-x86_64-linux-deb10-numa-slow-validate +# optional: true +# artifacts: false +# rules: +# - if: $NIGHTLY +# variables: +# NIGHTLY: "$NIGHTLY" +# extends: .hackage +# variables: +# SLOW_VALIDATE: 1 +# EXTRA_HC_OPTS: "-dlint" -nightly-hackage-perf: - needs: - - job: nightly-x86_64-linux-fedora33-release - optional: true - artifacts: false - rules: - - if: $NIGHTLY - variables: - NIGHTLY: "$NIGHTLY" - extends: .hackage - variables: - # Generate logs for nightly builds which include timing information. - EXTRA_HC_OPTS: "-ddump-timings" - # Ask head.hackage to generate eventlogs - EVENTLOGGING: 1 +# nightly-hackage-perf: +# needs: +# - job: nightly-x86_64-linux-fedora33-release +# optional: true +# artifacts: false +# rules: +# - if: $NIGHTLY +# variables: +# NIGHTLY: "$NIGHTLY" +# extends: .hackage +# variables: +# # Generate logs for nightly builds which include timing information. +# EXTRA_HC_OPTS: "-ddump-timings" +# # Ask head.hackage to generate eventlogs +# EVENTLOGGING: 1 -release-hackage-lint: - needs: - - job: release-x86_64-linux-fedora33-release - optional: true - artifacts: false - rules: - - if: '$RELEASE_JOB == "yes"' - extends: .hackage - variables: - # No slow-validate bindist on release pipeline - EXTRA_HC_OPTS: "-dlint" +# release-hackage-lint: +# needs: +# - job: release-x86_64-linux-fedora33-release +# optional: true +# artifacts: false +# rules: +# - if: '$RELEASE_JOB == "yes"' +# extends: .hackage +# variables: +# # No slow-validate bindist on release pipeline +# EXTRA_HC_OPTS: "-dlint" ############################################################ # Nofib testing # (Disabled: See #21859) ############################################################ -perf-nofib: - # Dependencies used by perf-nofib can't be built when some compiler changes - # aren't (yet) supported by head.hackage. - # Hence we allow this job to fail. - allow_failure: true - stage: testing - needs: - - job: x86_64-linux-fedora33-release - optional: true - - job: nightly-x86_64-linux-fedora33-release - optional: true - - job: release-x86_64-linux-fedora33-release - optional: true - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" - rules: - - when: never - - if: $CI_MERGE_REQUEST_ID - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' - - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' - tags: - - x86_64-linux - before_script: - - cd nofib - - "cabal update --index=$HACKAGE_INDEX_STATE --project-file=cabal.project.head-hackage" - script: - - root=$(pwd)/ghc - - | - mkdir tmp - tar -xf ../ghc-x86_64-linux-fedora33-release.tar.xz -C tmp - pushd tmp/ghc-*/ - ./configure --prefix=$root - make install - popd - rm -Rf tmp - - export PATH=$root/bin:$PATH - - cabal install -w "$root/bin/ghc" --lib regex-compat unboxed-ref parallel random-1.2.1 --allow-newer --package-env local.env --project-file=cabal.project.head-hackage - - export GHC_ENVIRONMENT="$(pwd)/local.env" - - "make HC=$root/bin/ghc BOOT_HC=$root/bin/ghc boot mode=fast -j$CPUS" - - "make HC=$root/bin/ghc BOOT_HC=$root/bin/ghc EXTRA_RUNTEST_OPTS='-cachegrind +RTS -V0 -RTS' NoFibRuns=1 mode=fast -j$CPUS 2>&1 | tee nofib.log" - artifacts: - expire_in: 12 week - when: always - paths: - - nofib/nofib.log +# perf-nofib: +# # Dependencies used by perf-nofib can't be built when some compiler changes +# # aren't (yet) supported by head.hackage. +# # Hence we allow this job to fail. +# allow_failure: true +# stage: testing +# needs: +# - job: x86_64-linux-fedora33-release +# optional: true +# - job: nightly-x86_64-linux-fedora33-release +# optional: true +# - job: release-x86_64-linux-fedora33-release +# optional: true +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" +# rules: +# - when: never +# - if: $CI_MERGE_REQUEST_ID +# - if: '$CI_COMMIT_BRANCH == "master"' +# - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' +# - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' +# tags: +# - x86_64-linux +# before_script: +# - cd nofib +# - "cabal update --index=$HACKAGE_INDEX_STATE --project-file=cabal.project.head-hackage" +# script: +# - root=$(pwd)/ghc +# - | +# mkdir tmp +# tar -xf ../ghc-x86_64-linux-fedora33-release.tar.xz -C tmp +# pushd tmp/ghc-*/ +# ./configure --prefix=$root +# make install +# popd +# rm -Rf tmp +# - export PATH=$root/bin:$PATH +# - cabal install -w "$root/bin/ghc" --lib regex-compat unboxed-ref parallel random-1.2.1 --allow-newer --package-env local.env --project-file=cabal.project.head-hackage +# - export GHC_ENVIRONMENT="$(pwd)/local.env" +# - "make HC=$root/bin/ghc BOOT_HC=$root/bin/ghc boot mode=fast -j$CPUS" +# - "make HC=$root/bin/ghc BOOT_HC=$root/bin/ghc EXTRA_RUNTEST_OPTS='-cachegrind +RTS -V0 -RTS' NoFibRuns=1 mode=fast -j$CPUS 2>&1 | tee nofib.log" +# artifacts: +# expire_in: 12 week +# when: always +# paths: +# - nofib/nofib.log -############################################################ -# Ad-hoc performance testing -############################################################ +# ############################################################ +# # Ad-hoc performance testing +# ############################################################ -perf: - stage: testing - needs: - - job: x86_64-linux-fedora33-release - optional: true - - job: nightly-x86_64-linux-fedora33-release - optional: true - - job: release-x86_64-linux-fedora33-release - optional: true - dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" - rules: - - if: $CI_MERGE_REQUEST_ID - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' - tags: - - x86_64-linux-perf - script: - - root=$(pwd)/ghc - - | - mkdir tmp - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp - pushd tmp/ghc-*/ - ./configure --prefix=$root - make install - popd - rm -Rf tmp - - export BOOT_HC=$(which ghc) - - export HC=$root/bin/ghc - - .gitlab/ci.sh perf_test - artifacts: - expire_in: 2 year - when: always - paths: - - out - rules: - - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' +# perf: +# stage: testing +# needs: +# - job: x86_64-linux-fedora33-release +# optional: true +# - job: nightly-x86_64-linux-fedora33-release +# optional: true +# - job: release-x86_64-linux-fedora33-release +# optional: true +# dependencies: null +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" +# rules: +# - if: $CI_MERGE_REQUEST_ID +# - if: '$CI_COMMIT_BRANCH == "master"' +# - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' +# tags: +# - x86_64-linux-perf +# script: +# - root=$(pwd)/ghc +# - | +# mkdir tmp +# tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp +# pushd tmp/ghc-*/ +# ./configure --prefix=$root +# make install +# popd +# rm -Rf tmp +# - export BOOT_HC=$(which ghc) +# - export HC=$root/bin/ghc +# - .gitlab/ci.sh perf_test +# artifacts: +# expire_in: 2 year +# when: always +# paths: +# - out +# rules: +# - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' -############################################################ -# ABI testing -############################################################ - -abi-test: - stage: testing - needs: - - job: x86_64-linux-fedora33-release - optional: true - - job: nightly-x86_64-linux-fedora33-release - optional: true - - job: release-x86_64-linux-fedora33-release - optional: true - dependencies: null - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" - rules: - - if: $CI_MERGE_REQUEST_ID - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' - tags: - - x86_64-linux - script: - - root=$(pwd)/ghc - - | - mkdir tmp - tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp - pushd tmp/ghc-*/ - ./configure --prefix=$root - make install - popd - rm -Rf tmp - - export BOOT_HC=$(which ghc) - - export HC=$root/bin/ghc - - .gitlab/ci.sh abi_test - artifacts: - paths: - - out - rules: - - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' +# ############################################################ +# # ABI testing +# ############################################################ +# abi-test: +# stage: testing +# needs: +# - job: x86_64-linux-fedora33-release +# optional: true +# - job: nightly-x86_64-linux-fedora33-release +# optional: true +# - job: release-x86_64-linux-fedora33-release +# optional: true +# dependencies: null +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" +# rules: +# - if: $CI_MERGE_REQUEST_ID +# - if: '$CI_COMMIT_BRANCH == "master"' +# - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' +# tags: +# - x86_64-linux +# script: +# - root=$(pwd)/ghc +# - | +# mkdir tmp +# tar -xf ghc-x86_64-linux-fedora33-release.tar.xz -C tmp +# pushd tmp/ghc-*/ +# ./configure --prefix=$root +# make install +# popd +# rm -Rf tmp +# - export BOOT_HC=$(which ghc) +# - export HC=$root/bin/ghc +# - .gitlab/ci.sh abi_test +# artifacts: +# paths: +# - out +# rules: +# - if: '$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/' -############################################################ -# Documentation deployment via GitLab Pages -############################################################ -pages: - stage: deploy - needs: [doc-tarball] - dependencies: null - image: ghcci/x86_64-linux-deb9:0.2 - # See #18973 - allow_failure: true - tags: - - x86_64-linux - script: - - mkdir -p public/doc - # haddock docs are not in the hadrian produce doc tarballs at the moment - # - tar -xf haddock.html.tar.xz -C public/doc - - tar -xf libraries.html.tar.xz -C public/doc - - tar -xf users_guide.html.tar.xz -C public/doc - - | - cat >public/index.html < - - - EOF - - cp -f index.html public/doc - rules: - # N.B. only run this on ghc/ghc since the deployed pages are quite large - # and we only serve GitLab Pages for ghc/ghc. - - if: '$CI_COMMIT_BRANCH == "master" && $CI_PROJECT_NAMESPACE == "ghc"' - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*publish-docs.*/' +# ############################################################ +# # Documentation deployment via GitLab Pages +# ############################################################ - artifacts: - paths: - - public +# pages: +# stage: deploy +# needs: [doc-tarball] +# dependencies: null +# image: ghcci/x86_64-linux-deb9:0.2 +# # See #18973 +# allow_failure: true +# tags: +# - x86_64-linux +# script: +# - mkdir -p public/doc +# # haddock docs are not in the hadrian produce doc tarballs at the moment +# # - tar -xf haddock.html.tar.xz -C public/doc +# - tar -xf libraries.html.tar.xz -C public/doc +# - tar -xf users_guide.html.tar.xz -C public/doc +# - | +# cat >public/index.html < +# +# +# EOF +# - cp -f index.html public/doc +# rules: +# # N.B. only run this on ghc/ghc since the deployed pages are quite large +# # and we only serve GitLab Pages for ghc/ghc. +# - if: '$CI_COMMIT_BRANCH == "master" && $CI_PROJECT_NAMESPACE == "ghc"' +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*publish-docs.*/' -############################################################# -# Generation of GHCUp metadata -############################################################# +# artifacts: +# paths: +# - public +# ############################################################# +# # Generation of GHCUp metadata +# ############################################################# -project-version: - stage: packaging - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - tags: - - x86_64-linux - variables: - BUILD_FLAVOUR: default - script: - # Calculate the project version - - sudo chown ghc:ghc -R . - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - - echo "ProjectVersion=$(cat VERSION)" > version.sh - needs: [] - dependencies: [] - artifacts: - paths: - - version.sh - rules: - - if: '$NIGHTLY' - - if: '$RELEASE_JOB == "yes"' +# project-version: +# stage: packaging +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# tags: +# - x86_64-linux +# variables: +# BUILD_FLAVOUR: default +# script: +# # Calculate the project version +# - sudo chown ghc:ghc -R . +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# - echo "ProjectVersion=$(cat VERSION)" > version.sh -.ghcup-metadata: - stage: deploy - image: nixos/nix:2.14.1 - dependencies: null - tags: - - x86_64-linux - variables: - BUILD_FLAVOUR: default - GIT_SUBMODULE_STRATEGY: "none" - before_script: - - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf - - nix-channel --update - - cat version.sh - # Calculate the project version - - . ./version.sh +# needs: [] +# dependencies: [] +# artifacts: +# paths: +# - version.sh +# rules: +# - if: '$NIGHTLY' +# - if: '$RELEASE_JOB == "yes"' - # Download existing ghcup metadata - - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#wget -c wget "https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-0.0.7.yaml" +# .ghcup-metadata: +# stage: deploy +# image: nixos/nix:2.14.1 +# dependencies: null +# tags: +# - x86_64-linux +# variables: +# BUILD_FLAVOUR: default +# GIT_SUBMODULE_STRATEGY: "none" +# before_script: +# - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf +# - nix-channel --update +# - cat version.sh +# # Calculate the project version +# - . ./version.sh - - .gitlab/generate_job_metadata +# # Download existing ghcup metadata +# - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#wget -c wget "https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-0.0.7.yaml" - artifacts: - paths: - - metadata_test.yaml - - version.sh +# - .gitlab/generate_job_metadata -ghcup-metadata-nightly: - extends: .ghcup-metadata - # Explicit needs for validate pipeline because we only need certain bindists - needs: - - job: nightly-x86_64-linux-fedora33-release - artifacts: false - - job: nightly-x86_64-linux-centos7-validate - artifacts: false - - job: nightly-x86_64-linux-ubuntu20_04-validate - artifacts: false - - job: nightly-x86_64-linux-ubuntu18_04-validate - artifacts: false - - job: nightly-x86_64-linux-rocky8-validate - artifacts: false - - job: nightly-x86_64-darwin-validate - artifacts: false - - job: nightly-aarch64-darwin-validate - artifacts: false - - job: nightly-x86_64-windows-validate - artifacts: false - - job: nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static - artifacts: false - - job: nightly-x86_64-linux-deb9-validate - artifacts: false - - job: nightly-i386-linux-deb9-validate - artifacts: false - - job: nightly-x86_64-linux-deb10-validate - artifacts: false - - job: nightly-aarch64-linux-deb10-validate - artifacts: false - - job: nightly-x86_64-linux-deb11-validate - artifacts: false - - job: source-tarball - artifacts: false - - job: project-version - script: - - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" - rules: - - if: $NIGHTLY +# artifacts: +# paths: +# - metadata_test.yaml +# - version.sh -ghcup-metadata-release: - # No explicit needs for release pipeline as we assume we need everything and everything will pass. - extends: .ghcup-metadata - script: - - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --release-mode --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" - rules: - - if: '$RELEASE_JOB == "yes"' +# ghcup-metadata-nightly: +# extends: .ghcup-metadata +# # Explicit needs for validate pipeline because we only need certain bindists +# needs: +# - job: nightly-x86_64-linux-fedora33-release +# artifacts: false +# - job: nightly-x86_64-linux-centos7-validate +# artifacts: false +# - job: nightly-x86_64-linux-ubuntu20_04-validate +# artifacts: false +# - job: nightly-x86_64-linux-ubuntu18_04-validate +# artifacts: false +# - job: nightly-x86_64-linux-rocky8-validate +# artifacts: false +# - job: nightly-x86_64-darwin-validate +# artifacts: false +# - job: nightly-aarch64-darwin-validate +# artifacts: false +# - job: nightly-x86_64-windows-validate +# artifacts: false +# - job: nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static +# artifacts: false +# - job: nightly-x86_64-linux-deb9-validate +# artifacts: false +# - job: nightly-i386-linux-deb9-validate +# artifacts: false +# - job: nightly-x86_64-linux-deb10-validate +# artifacts: false +# - job: nightly-aarch64-linux-deb10-validate +# artifacts: false +# - job: nightly-x86_64-linux-deb11-validate +# artifacts: false +# - job: source-tarball +# artifacts: false +# - job: project-version +# script: +# - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" +# rules: +# - if: $NIGHTLY -.ghcup-metadata-testing: - stage: deploy - variables: - UPSTREAM_PROJECT_PATH: "$CI_PROJECT_PATH" - UPSTREAM_PROJECT_ID: "$CI_PROJECT_ID" - UPSTREAM_PIPELINE_ID: "$CI_PIPELINE_ID" - RELEASE_JOB: "$RELEASE_JOB" - trigger: - project: "ghc/ghcup-ci" - branch: "upstream-testing" - strategy: "depend" +# ghcup-metadata-release: +# # No explicit needs for release pipeline as we assume we need everything and everything will pass. +# extends: .ghcup-metadata +# script: +# - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --release-mode --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" +# rules: +# - if: '$RELEASE_JOB == "yes"' -ghcup-metadata-testing-nightly: - needs: - - job: ghcup-metadata-nightly - artifacts: false - extends: .ghcup-metadata-testing - variables: - NIGHTLY: "$NIGHTLY" - UPSTREAM_JOB_NAME: "ghcup-metadata-nightly" - rules: - - if: '$NIGHTLY == "1"' +# .ghcup-metadata-testing: +# stage: deploy +# variables: +# UPSTREAM_PROJECT_PATH: "$CI_PROJECT_PATH" +# UPSTREAM_PROJECT_ID: "$CI_PROJECT_ID" +# UPSTREAM_PIPELINE_ID: "$CI_PIPELINE_ID" +# RELEASE_JOB: "$RELEASE_JOB" +# trigger: +# project: "ghc/ghcup-ci" +# branch: "upstream-testing" +# strategy: "depend" + +# ghcup-metadata-testing-nightly: +# needs: +# - job: ghcup-metadata-nightly +# artifacts: false +# extends: .ghcup-metadata-testing +# variables: +# NIGHTLY: "$NIGHTLY" +# UPSTREAM_JOB_NAME: "ghcup-metadata-nightly" +# rules: +# - if: '$NIGHTLY == "1"' -ghcup-metadata-testing-release: - needs: - - job: ghcup-metadata-release - artifacts: false - extends: .ghcup-metadata-testing - variables: - UPSTREAM_JOB_NAME: "ghcup-metadata-release" - rules: - - if: '$RELEASE_JOB == "yes"' - when: manual +# ghcup-metadata-testing-release: +# needs: +# - job: ghcup-metadata-release +# artifacts: false +# extends: .ghcup-metadata-testing +# variables: +# UPSTREAM_JOB_NAME: "ghcup-metadata-release" +# rules: +# - if: '$RELEASE_JOB == "yes"' +# when: manual View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d3a588f3671cd27eb21c9262a7f996aa9db8335 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d3a588f3671cd27eb21c9262a7f996aa9db8335 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:04:02 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:04:02 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] faster Message-ID: <642b93a2bd9fb_11425f13a2db002476e7@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 44211a39 by Moritz Angermann at 2023-04-04T11:03:45+08:00 faster - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -47,8 +47,8 @@ default: stages: - not-interruptible - - tool-lint # Source linting of the tools - - quick-build # A very quick smoke-test to weed out broken commits + # - tool-lint # Source linting of the tools + # - quick-build # A very quick smoke-test to weed out broken commits - full-build # Build all the things - packaging # Source distribution, etc. - testing # head.hackage correctness and compiler performance testing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44211a390922bd1a1d4baf4e145c2a8e0477ef24 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44211a390922bd1a1d4baf4e145c2a8e0477ef24 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:05:26 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:05:26 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] No we don't need that. Message-ID: <642b93f6568f3_11425f13a2dad8248316@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: a3a6575d by Moritz Angermann at 2023-04-04T11:05:07+08:00 No we don't need that. - - - - - 1 changed file: - .gitlab/jobs.yaml Changes: ===================================== .gitlab/jobs.yaml ===================================== @@ -28,10 +28,6 @@ "dependencies": [], "image": null, "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } ], "rules": [ { @@ -90,10 +86,6 @@ "dependencies": [], "image": null, "needs": [ - { - "artifacts": false, - "job": "hadrian-ghc-in-ghci" - } ], "rules": [ { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3a6575dad271e630fc4ca1a6d7a7b549afe5dad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3a6575dad271e630fc4ca1a6d7a7b549afe5dad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:06:36 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:06:36 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] wow Message-ID: <642b943cb66a1_11425f13a76f44248823@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 05089c51 by Moritz Angermann at 2023-04-04T11:06:16+08:00 wow - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -191,191 +191,191 @@ include: '.gitlab/jobs.yaml' # tool linting ############################################################ -ghc-linters: - stage: tool-lint - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - extends: .lint-params - variables: - BUILD_FLAVOUR: default - script: - - .gitlab/ci.sh configure - - timeout 10m .gitlab/ci.sh run_hadrian test --test-root-dirs="testsuite/tests/linters" - dependencies: [] - rules: - - if: $CI_MERGE_REQUEST_ID - - *drafts-can-fail-lint +# ghc-linters: +# stage: tool-lint +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# extends: .lint-params +# variables: +# BUILD_FLAVOUR: default +# script: +# - .gitlab/ci.sh configure +# - timeout 10m .gitlab/ci.sh run_hadrian test --test-root-dirs="testsuite/tests/linters" +# dependencies: [] +# rules: +# - if: $CI_MERGE_REQUEST_ID +# - *drafts-can-fail-lint -# Run mypy Python typechecker on linter scripts. -lint-linters: - image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" - extends: .lint - script: - - mypy testsuite/tests/linters/regex-linters/*.py - dependencies: [] - -# Check that .T files all parse by listing broken tests. -lint-testsuite: - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - extends: .lint - script: - - make -Ctestsuite list_broken TEST_HC=$GHC - dependencies: [] - -# Run mypy Python typechecker on testsuite driver -typecheck-testsuite: - image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" - extends: .lint - script: - - mypy testsuite/driver/runtests.py - dependencies: [] - -# We allow the submodule checker to fail when run on merge requests (to -# accommodate, e.g., haddock changes not yet upstream) but not on `master` or -# Marge jobs. -.lint-submods: - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - extends: .lint-params - variables: - BUILD_FLAVOUR: default - script: - - .gitlab/ci.sh configure - - .gitlab/ci.sh run_hadrian stage0:exe:lint-submodule-refs - - git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)" - - "echo Linting submodule changes between $base..$CI_COMMIT_SHA" - - git submodule foreach git remote update - - _build/stageBoot/bin/lint-submodule-refs . $(git rev-list $base..$CI_COMMIT_SHA) - dependencies: [] - -# We allow the submodule checker to fail when run on merge requests (to -# accommodate, e.g., haddock changes not yet upstream) but not on `master` or -# Marge jobs. -lint-author: - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - extends: .lint-params - variables: - BUILD_FLAVOUR: default - script: - - git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)" - - "echo Linting authors between $base..$CI_COMMIT_SHA" - - .gitlab/ci.sh lint_author $base $CI_COMMIT_SHA - dependencies: [] - rules: - - if: $CI_MERGE_REQUEST_ID - - *drafts-can-fail-lint +# # Run mypy Python typechecker on linter scripts. +# lint-linters: +# image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" +# extends: .lint +# script: +# - mypy testsuite/tests/linters/regex-linters/*.py +# dependencies: [] -lint-ci-config: - image: nixos/nix:2.14.1 - extends: .lint - # We don't need history/submodules in this job - variables: - GIT_DEPTH: 1 - GIT_SUBMODULE_STRATEGY: none - before_script: - - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf - - nix-channel --update - script: - - .gitlab/generate_jobs - # 1 if .gitlab/generate_jobs changed the output of the generated config - - nix shell nixpkgs#git -c git diff --exit-code - # And run this to just make sure that works - - .gitlab/generate_job_metadata - dependencies: [] - -lint-submods: - extends: .lint-submods - # Allow failure on merge requests since any necessary submodule patches may - # not be upstreamed yet. - rules: - - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' - allow_failure: false - # Don't run on nightly because the program needs a base commit to check. - - if: $NIGHTLY - when: never - - allow_failure: true +# # Check that .T files all parse by listing broken tests. +# lint-testsuite: +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" +# extends: .lint +# script: +# - make -Ctestsuite list_broken TEST_HC=$GHC +# dependencies: [] -lint-submods-branch: - extends: .lint-submods - variables: - BUILD_FLAVOUR: default - script: - - .gitlab/ci.sh configure - - .gitlab/ci.sh run_hadrian stage0:exe:lint-submodule-refs - - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" - - git submodule foreach git remote update - - _build/stageBoot/bin/lint-submodule-refs . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) - rules: - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' - - *drafts-can-fail-lint +# # Run mypy Python typechecker on testsuite driver +# typecheck-testsuite: +# image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" +# extends: .lint +# script: +# - mypy testsuite/driver/runtests.py +# dependencies: [] -############################################################ -# GHC source code linting -############################################################ +# # We allow the submodule checker to fail when run on merge requests (to +# # accommodate, e.g., haddock changes not yet upstream) but not on `master` or +# # Marge jobs. +# .lint-submods: +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# extends: .lint-params +# variables: +# BUILD_FLAVOUR: default +# script: +# - .gitlab/ci.sh configure +# - .gitlab/ci.sh run_hadrian stage0:exe:lint-submodule-refs +# - git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME +# - base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)" +# - "echo Linting submodule changes between $base..$CI_COMMIT_SHA" +# - git submodule foreach git remote update +# - _build/stageBoot/bin/lint-submodule-refs . $(git rev-list $base..$CI_COMMIT_SHA) +# dependencies: [] -.lint-params: - needs: [] - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - extends: .lint - before_script: - - export PATH="/opt/toolchain/bin:$PATH" - # workaround for docker permissions - - sudo chown ghc:ghc -R . - - .gitlab/ci.sh setup - after_script: - - .gitlab/ci.sh save_cache - - cat ci-timings - variables: - GHC_FLAGS: -Werror - cache: - key: lint-$CACHE_REV - paths: - - cabal-cache - -# Disabled due to #22830 -.hlint-ghc-and-base: - extends: .lint-params - image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" - variables: - BUILD_FLAVOUR: default - script: - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - - .gitlab/ci.sh run_hadrian lint:base - - .gitlab/ci.sh run_hadrian lint:compiler +# # We allow the submodule checker to fail when run on merge requests (to +# # accommodate, e.g., haddock changes not yet upstream) but not on `master` or +# # Marge jobs. +# lint-author: +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# extends: .lint-params +# variables: +# BUILD_FLAVOUR: default +# script: +# - git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME +# - base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)" +# - "echo Linting authors between $base..$CI_COMMIT_SHA" +# - .gitlab/ci.sh lint_author $base $CI_COMMIT_SHA +# dependencies: [] +# rules: +# - if: $CI_MERGE_REQUEST_ID +# - *drafts-can-fail-lint -############################################################ -# GHC-in-GHCi (Hadrian) -############################################################ +# lint-ci-config: +# image: nixos/nix:2.14.1 +# extends: .lint +# # We don't need history/submodules in this job +# variables: +# GIT_DEPTH: 1 +# GIT_SUBMODULE_STRATEGY: none +# before_script: +# - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf +# - nix-channel --update +# script: +# - .gitlab/generate_jobs +# # 1 if .gitlab/generate_jobs changed the output of the generated config +# - nix shell nixpkgs#git -c git diff --exit-code +# # And run this to just make sure that works +# - .gitlab/generate_job_metadata +# dependencies: [] -hadrian-ghc-in-ghci: - stage: quick-build - needs: - - job: lint-linters - - job: lint-submods - optional: true - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" - before_script: - # workaround for docker permissions - - sudo chown ghc:ghc -R . - variables: - GHC_FLAGS: -Werror - tags: - - x86_64-linux - script: - - git clean -xdf && git submodule foreach git clean -xdf - - .gitlab/ci.sh setup - - .gitlab/ci.sh configure - # Load ghc-in-ghci then immediately exit and check the modules loaded - - echo ":q" | hadrian/ghci -j`mk/detect-cpu-count.sh`| tail -n2 | grep "Ok," - after_script: - - .gitlab/ci.sh save_cache - - cat ci-timings - cache: - key: hadrian-ghci-$CACHE_REV - paths: - - cabal-cache +# lint-submods: +# extends: .lint-submods +# # Allow failure on merge requests since any necessary submodule patches may +# # not be upstreamed yet. +# rules: +# - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/' +# allow_failure: false +# # Don't run on nightly because the program needs a base commit to check. +# - if: $NIGHTLY +# when: never +# - allow_failure: true + +# lint-submods-branch: +# extends: .lint-submods +# variables: +# BUILD_FLAVOUR: default +# script: +# - .gitlab/ci.sh configure +# - .gitlab/ci.sh run_hadrian stage0:exe:lint-submodule-refs +# - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" +# - git submodule foreach git remote update +# - _build/stageBoot/bin/lint-submodule-refs . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA) +# rules: +# - if: '$CI_COMMIT_BRANCH == "master"' +# - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/' +# - *drafts-can-fail-lint + +# ############################################################ +# # GHC source code linting +# ############################################################ + +# .lint-params: +# needs: [] +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# extends: .lint +# before_script: +# - export PATH="/opt/toolchain/bin:$PATH" +# # workaround for docker permissions +# - sudo chown ghc:ghc -R . +# - .gitlab/ci.sh setup +# after_script: +# - .gitlab/ci.sh save_cache +# - cat ci-timings +# variables: +# GHC_FLAGS: -Werror +# cache: +# key: lint-$CACHE_REV +# paths: +# - cabal-cache + +# # Disabled due to #22830 +# .hlint-ghc-and-base: +# extends: .lint-params +# image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV" +# variables: +# BUILD_FLAVOUR: default +# script: +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# - .gitlab/ci.sh run_hadrian lint:base +# - .gitlab/ci.sh run_hadrian lint:compiler + +# ############################################################ +# # GHC-in-GHCi (Hadrian) +# ############################################################ + +# hadrian-ghc-in-ghci: +# stage: quick-build +# needs: +# - job: lint-linters +# - job: lint-submods +# optional: true +# image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" +# before_script: +# # workaround for docker permissions +# - sudo chown ghc:ghc -R . +# variables: +# GHC_FLAGS: -Werror +# tags: +# - x86_64-linux +# script: +# - git clean -xdf && git submodule foreach git clean -xdf +# - .gitlab/ci.sh setup +# - .gitlab/ci.sh configure +# # Load ghc-in-ghci then immediately exit and check the modules loaded +# - echo ":q" | hadrian/ghci -j`mk/detect-cpu-count.sh`| tail -n2 | grep "Ok," +# after_script: +# - .gitlab/ci.sh save_cache +# - cat ci-timings +# cache: +# key: hadrian-ghci-$CACHE_REV +# paths: +# - cabal-cache ############################################################ # Hadrian Multi-Repl View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05089c51d2450f76dc30300e402497827785d7a6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05089c51d2450f76dc30300e402497827785d7a6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:30:22 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:30:22 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] trace Message-ID: <642b99ce4d196_11425f141df1642505ce@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 135e47c2 by Moritz Angermann at 2023-04-04T11:30:05+08:00 trace - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -210,7 +210,7 @@ function set_toolchain_paths() { *) fail "unknown NIX_SYSTEM" ;; esac info "Building toolchain for $NIX_SYSTEM" - nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh + nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace cat toolchain.sh fi source toolchain.sh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/135e47c23fcbb1abfa68e4dfcd08e6592c97e3e5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/135e47c23fcbb1abfa68e4dfcd08e6592c97e3e5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:36:49 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:36:49 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] 2 commits: log nix version Message-ID: <642b9b5168c4d_11425f14375c1c2508f2@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: bd6faa18 by Moritz Angermann at 2023-04-04T11:35:32+08:00 log nix version - - - - - 3e4bd178 by Moritz Angermann at 2023-04-04T11:36:28+08:00 more verbose output - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -210,7 +210,8 @@ function set_toolchain_paths() { *) fail "unknown NIX_SYSTEM" ;; esac info "Building toolchain for $NIX_SYSTEM" - nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace + nix --version + nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace -v cat toolchain.sh fi source toolchain.sh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/135e47c23fcbb1abfa68e4dfcd08e6592c97e3e5...3e4bd178f3c33e92276e05b389792fa0a226a809 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/135e47c23fcbb1abfa68e4dfcd08e6592c97e3e5...3e4bd178f3c33e92276e05b389792fa0a226a809 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 03:55:22 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Mon, 03 Apr 2023 23:55:22 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] dump env Message-ID: <642b9faa41a9e_11425f148ea1d42553ae@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 9179743f by Moritz Angermann at 2023-04-04T11:55:03+08:00 dump env - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -211,6 +211,7 @@ function set_toolchain_paths() { esac info "Building toolchain for $NIX_SYSTEM" nix --version + env nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace -v cat toolchain.sh fi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9179743ffaba01e75f253d2edcd66767045756d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9179743ffaba01e75f253d2edcd66767045756d4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 04:06:38 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Tue, 04 Apr 2023 00:06:38 -0400 Subject: [Git][ghc/ghc][wip/angerman/debug-darwin] increase debugging Message-ID: <642ba24e1f5a2_11425f14c55f8025589f@gitlab.mail> Moritz Angermann pushed to branch wip/angerman/debug-darwin at Glasgow Haskell Compiler / GHC Commits: 491ad16d by Moritz Angermann at 2023-04-04T12:05:49+08:00 increase debugging - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -211,8 +211,9 @@ function set_toolchain_paths() { esac info "Building toolchain for $NIX_SYSTEM" nix --version - env - nix-build .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace -v + # env + # nix build -f .gitlab/darwin/toolchain.nix --argstr system "$NIX_SYSTEM" -o toolchain.sh --show-trace -v + nix build -v --debug -L -f .gitlab/darwin/toolchain.nix --argstr system aarch64-darwin -o toolchain.sh --show-trace cat toolchain.sh fi source toolchain.sh View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/491ad16d23dfe4d6189f29ff82683f8186266ca2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/491ad16d23dfe4d6189f29ff82683f8186266ca2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 05:04:39 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 01:04:39 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Add a few more memcpy-ish primops Message-ID: <642bafe79dc55_11425f15b65160266731@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - 20 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - libraries/base/Data/Array/Byte.hs - libraries/base/Foreign/Marshal/Utils.hs - libraries/ghc-prim/changelog.md - rts/RtsMessages.c - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray2.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray3.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadInt64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadSmallArray.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord8ArrayAsWord32.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyAddrToByteArray.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyByteArray.hs - testsuite/tests/codeGen/should_fail/all.T - + testsuite/tests/codeGen/should_run/CheckBoundsOK.hs - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -1890,13 +1890,14 @@ primop CompareByteArraysOp "compareByteArrays#" GenPrimOp primop CopyByteArrayOp "copyByteArray#" GenPrimOp ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - {@'copyByteArray#' src src_ofs dst dst_ofs n@ copies the range - starting at offset @src_ofs@ of length @n@ from the - 'ByteArray#' @src@ to the 'MutableByteArray#' @dst@ - starting at offset @dst_ofs at . Both arrays must fully contain - the specified ranges, but this is not checked. The two arrays must - not be the same array in different states, but this is not checked - either.} + { @'copyByteArray#' src src_ofs dst dst_ofs len@ copies the range + starting at offset @src_ofs@ of length @len@ from the + 'ByteArray#' @src@ to the 'MutableByteArray#' @dst@ + starting at offset @dst_ofs at . Both arrays must fully contain + the specified ranges, but this is not checked. The two arrays must + not be the same array in different states, but this is not checked + either. + } with has_side_effects = True code_size = { primOpCodeSizeForeignCall + 4} @@ -1904,10 +1905,30 @@ primop CopyByteArrayOp "copyByteArray#" GenPrimOp primop CopyMutableByteArrayOp "copyMutableByteArray#" GenPrimOp MutableByteArray# s -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - {Copy a range of the first MutableByteArray\# to the specified region in the second MutableByteArray\#. - Both arrays must fully contain the specified ranges, but this is not checked. The regions are - allowed to overlap, although this is only possible when the same array is provided - as both the source and the destination.} + { @'copyMutableByteArray#' src src_ofs dst dst_ofs len@ copies the + range starting at offset @src_ofs@ of length @len@ from the + 'MutableByteArray#' @src@ to the 'MutableByteArray#' @dst@ + starting at offset @dst_ofs at . Both arrays must fully contain the + specified ranges, but this is not checked. The regions are + allowed to overlap, although this is only possible when the same + array is provided as both the source and the destination. + } + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + can_fail = True + +primop CopyMutableByteArrayNonOverlappingOp "copyMutableByteArrayNonOverlapping#" GenPrimOp + MutableByteArray# s -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s + { @'copyMutableByteArrayNonOverlapping#' src src_ofs dst dst_ofs len@ + copies the range starting at offset @src_ofs@ of length @len@ from + the 'MutableByteArray#' @src@ to the 'MutableByteArray#' @dst@ + starting at offset @dst_ofs at . Both arrays must fully contain the + specified ranges, but this is not checked. The regions are /not/ + allowed to overlap, but this is also not checked. + + @since 0.11.0 + } with has_side_effects = True code_size = { primOpCodeSizeForeignCall + 4 } @@ -1922,7 +1943,7 @@ primop CopyByteArrayToAddrOp "copyByteArrayToAddr#" GenPrimOp either.} with has_side_effects = True - code_size = { primOpCodeSizeForeignCall + 4} + code_size = { primOpCodeSizeForeignCall + 4 } can_fail = True primop CopyMutableByteArrayToAddrOp "copyMutableByteArrayToAddr#" GenPrimOp @@ -1934,7 +1955,7 @@ primop CopyMutableByteArrayToAddrOp "copyMutableByteArrayToAddr#" GenPrimOp pinned), but this is not checked either.} with has_side_effects = True - code_size = { primOpCodeSizeForeignCall + 4} + code_size = { primOpCodeSizeForeignCall + 4 } can_fail = True primop CopyAddrToByteArrayOp "copyAddrToByteArray#" GenPrimOp @@ -1946,7 +1967,38 @@ primop CopyAddrToByteArrayOp "copyAddrToByteArray#" GenPrimOp but this is not checked either.} with has_side_effects = True - code_size = { primOpCodeSizeForeignCall + 4} + code_size = { primOpCodeSizeForeignCall + 4 } + can_fail = True + +primop CopyAddrToAddrOp "copyAddrToAddr#" GenPrimOp + Addr# -> Addr# -> Int# -> State# RealWorld -> State# RealWorld + { @'copyAddrToAddr#' src dest len@ copies @len@ bytes + from @src@ to @dest at . These two memory ranges are allowed to overlap. + + Analogous to the standard C function @memmove@, but with a different + argument order. + + @since 0.11.0 + } + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall } + can_fail = True + +primop CopyAddrToAddrNonOverlappingOp "copyAddrToAddrNonOverlapping#" GenPrimOp + Addr# -> Addr# -> Int# -> State# RealWorld -> State# RealWorld + { @'copyAddrToAddrNonOverlapping#' src dest len@ copies @len@ bytes + from @src@ to @dest at . As the name suggests, these two memory ranges + /must not overlap/, although this pre-condition is not checked. + + Analogous to the standard C function @memcpy@, but with a different + argument order. + + @since 0.11.0 + } + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall } can_fail = True primop SetByteArrayOp "setByteArray#" GenPrimOp @@ -1958,6 +2010,21 @@ primop SetByteArrayOp "setByteArray#" GenPrimOp code_size = { primOpCodeSizeForeignCall + 4 } can_fail = True +primop SetAddrRangeOp "setAddrRange#" GenPrimOp + Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld + { @'setAddrRange#' dest len c@ sets all of the bytes in + @[dest, dest+len)@ to the value @c at . + + Analogous to the standard C function @memset@, but with a different + argument order. + + @since 0.11.0 + } + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall } + can_fail = True + -- Atomic operations primop AtomicReadByteArrayOp_Int "atomicReadIntArray#" GenPrimOp ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -65,6 +65,7 @@ module GHC.Cmm.CLabel ( mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel, mkOutOfBoundsAccessLabel, + mkMemcpyRangeOverlapLabel, mkArrWords_infoLabel, mkSRTInfoLabel, @@ -649,7 +650,8 @@ mkDirty_MUT_VAR_Label, mkCAFBlackHoleInfoTableLabel, mkSMAP_FROZEN_CLEAN_infoLabel, mkSMAP_FROZEN_DIRTY_infoLabel, mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel, - mkOutOfBoundsAccessLabel, mkMUT_VAR_CLEAN_infoLabel :: CLabel + mkOutOfBoundsAccessLabel, mkMemcpyRangeOverlapLabel, + mkMUT_VAR_CLEAN_infoLabel :: CLabel mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData @@ -667,7 +669,8 @@ mkSMAP_FROZEN_CLEAN_infoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsL mkSMAP_FROZEN_DIRTY_infoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo mkSMAP_DIRTY_infoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo mkBadAlignmentLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_badAlignment") CmmEntry -mkOutOfBoundsAccessLabel = mkForeignLabel (fsLit "rtsOutOfBoundsAccess") Nothing ForeignLabelInExternalPackage IsFunction +mkOutOfBoundsAccessLabel = mkForeignLabel (fsLit "rtsOutOfBoundsAccess") Nothing ForeignLabelInExternalPackage IsFunction +mkMemcpyRangeOverlapLabel = mkForeignLabel (fsLit "rtsMemcpyRangeOverlap") Nothing ForeignLabelInExternalPackage IsFunction mkMUT_VAR_CLEAN_infoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_MUT_VAR_CLEAN") CmmInfo mkSRTInfoLabel :: Int -> CLabel ===================================== compiler/GHC/StgToCmm/Foreign.hs ===================================== @@ -8,7 +8,9 @@ module GHC.StgToCmm.Foreign ( cgForeignCall, - emitPrimCall, emitCCall, + emitPrimCall, + emitCCall, + emitCCallNeverReturns, emitForeignCall, emitSaveThreadState, saveThreadState, @@ -194,17 +196,31 @@ continuation, resulting in just one proc point instead of two. Yay! -} -emitCCall :: [(CmmFormal,ForeignHint)] - -> CmmExpr - -> [(CmmActual,ForeignHint)] - -> FCode () -emitCCall hinted_results fn hinted_args +emitCCall' :: CmmReturnInfo + -> [(CmmFormal,ForeignHint)] + -> CmmExpr + -> [(CmmActual,ForeignHint)] + -> FCode () +emitCCall' ret_info hinted_results fn hinted_args = void $ emitForeignCall PlayRisky results target args where (args, arg_hints) = unzip hinted_args (results, result_hints) = unzip hinted_results target = ForeignTarget fn fc - fc = ForeignConvention CCallConv arg_hints result_hints CmmMayReturn + fc = ForeignConvention CCallConv arg_hints result_hints ret_info + +emitCCall :: [(CmmFormal,ForeignHint)] + -> CmmExpr + -> [(CmmActual,ForeignHint)] + -> FCode () +emitCCall = emitCCall' CmmMayReturn + +emitCCallNeverReturns + :: [(CmmFormal,ForeignHint)] + -> CmmExpr + -> [(CmmActual,ForeignHint)] + -> FCode () +emitCCallNeverReturns = emitCCall' CmmNeverReturns emitPrimCall :: [CmmFormal] -> CallishMachOp -> [CmmActual] -> FCode () ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -311,7 +311,7 @@ emitPrimOp cfg primop = -- #define sizzeofByteArrayzh(r,a) \ -- r = ((StgArrBytes *)(a))->bytes SizeofByteArrayOp -> \[arg] -> opIntoRegs $ \[res] -> - emit $ mkAssign (CmmLocal res) (cmmLoadIndexW platform arg (fixedHdrSizeW profile) (bWord platform)) + emitAssign (CmmLocal res) (byteArraySize platform profile arg) -- #define sizzeofMutableByteArrayzh(r,a) \ -- r = ((StgArrBytes *)(a))->bytes @@ -320,7 +320,7 @@ emitPrimOp cfg primop = -- #define getSizzeofMutableByteArrayzh(r,a) \ -- r = ((StgArrBytes *)(a))->bytes GetSizeofMutableByteArrayOp -> \[arg] -> opIntoRegs $ \[res] -> - emitAssign (CmmLocal res) (cmmLoadIndexW platform arg (fixedHdrSizeW profile) (bWord platform)) + emitAssign (CmmLocal res) (byteArraySize platform profile arg) -- #define touchzh(o) /* nothing */ @@ -394,15 +394,10 @@ emitPrimOp cfg primop = -- Getting the size of pointer arrays SizeofArrayOp -> \[arg] -> opIntoRegs $ \[res] -> - emit $ mkAssign (CmmLocal res) (cmmLoadIndexW platform arg - (fixedHdrSizeW profile + bytesToWordsRoundUp platform (pc_OFFSET_StgMutArrPtrs_ptrs (platformConstants platform))) - (bWord platform)) + emitAssign (CmmLocal res) (ptrArraySize platform profile arg) SizeofMutableArrayOp -> emitPrimOp cfg SizeofArrayOp SizeofSmallArrayOp -> \[arg] -> opIntoRegs $ \[res] -> - emit $ mkAssign (CmmLocal res) - (cmmLoadIndexW platform arg - (fixedHdrSizeW profile + bytesToWordsRoundUp platform (pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform))) - (bWord platform)) + emitAssign (CmmLocal res) (smallPtrArraySize platform profile arg) SizeofSmallMutableArrayOp -> emitPrimOp cfg SizeofSmallArrayOp GetSizeofSmallMutableArrayOp -> emitPrimOp cfg SizeofSmallArrayOp @@ -715,14 +710,22 @@ emitPrimOp cfg primop = doCopyByteArrayOp src src_off dst dst_off n CopyMutableByteArrayOp -> \[src,src_off,dst,dst_off,n] -> opIntoRegs $ \[] -> doCopyMutableByteArrayOp src src_off dst dst_off n + CopyMutableByteArrayNonOverlappingOp -> \[src,src_off,dst,dst_off,n] -> opIntoRegs $ \[] -> + doCopyMutableByteArrayNonOverlappingOp src src_off dst dst_off n CopyByteArrayToAddrOp -> \[src,src_off,dst,n] -> opIntoRegs $ \[] -> doCopyByteArrayToAddrOp src src_off dst n CopyMutableByteArrayToAddrOp -> \[src,src_off,dst,n] -> opIntoRegs $ \[] -> doCopyMutableByteArrayToAddrOp src src_off dst n CopyAddrToByteArrayOp -> \[src,dst,dst_off,n] -> opIntoRegs $ \[] -> doCopyAddrToByteArrayOp src dst dst_off n + CopyAddrToAddrOp -> \[src,dst,n] -> opIntoRegs $ \[] -> + doCopyAddrToAddrOp src dst n + CopyAddrToAddrNonOverlappingOp -> \[src,dst,n] -> opIntoRegs $ \[] -> + doCopyAddrToAddrNonOverlappingOp src dst n SetByteArrayOp -> \[ba,off,len,c] -> opIntoRegs $ \[] -> doSetByteArrayOp ba off len c + SetAddrRangeOp -> \[dst,len,c] -> opIntoRegs $ \[] -> + doSetAddrRangeOp dst len c -- Comparing byte arrays CompareByteArraysOp -> \[ba1,ba1_off,ba2,ba2_off,n] -> opIntoRegs $ \[res] -> @@ -2097,8 +2100,8 @@ doWriteOffAddrOp :: Maybe MachOp -> [LocalReg] -> [CmmExpr] -> FCode () -doWriteOffAddrOp maybe_pre_write_cast idx_ty [] [addr,idx,val] - = mkBasicIndexedWrite 0 maybe_pre_write_cast addr idx_ty idx val +doWriteOffAddrOp castOp idx_ty [] [addr,idx, val] + = mkBasicIndexedWrite 0 addr idx_ty idx (maybeCast castOp val) doWriteOffAddrOp _ _ _ _ = panic "GHC.StgToCmm.Prim: doWriteOffAddrOp" @@ -2107,11 +2110,12 @@ doWriteByteArrayOp :: Maybe MachOp -> [LocalReg] -> [CmmExpr] -> FCode () -doWriteByteArrayOp maybe_pre_write_cast idx_ty [] [addr,idx,val] +doWriteByteArrayOp castOp idx_ty [] [addr,idx, rawVal] = do profile <- getProfile platform <- getPlatform + let val = maybeCast castOp rawVal doByteArrayBoundsCheck idx addr idx_ty (cmmExprType platform val) - mkBasicIndexedWrite (arrWordsHdrSize profile) maybe_pre_write_cast addr idx_ty idx val + mkBasicIndexedWrite (arrWordsHdrSize profile) addr idx_ty idx val doWriteByteArrayOp _ _ _ _ = panic "GHC.StgToCmm.Prim: doWriteByteArrayOp" @@ -2134,7 +2138,7 @@ doWritePtrArrayOp addr idx val -- referred to by val have happened before we write val into the array. -- See #12469 for details. emitPrimCall [] MO_WriteBarrier [] - mkBasicIndexedWrite hdr_size Nothing addr ty idx val + mkBasicIndexedWrite hdr_size addr ty idx val emit (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel))) -- the write barrier. We must write a byte into the mark table: @@ -2142,15 +2146,10 @@ doWritePtrArrayOp addr idx val emit $ mkStore ( cmmOffsetExpr platform (cmmOffsetExprW platform (cmmOffsetB platform addr hdr_size) - (loadArrPtrsSize profile addr)) + (ptrArraySize platform profile addr)) (CmmMachOp (mo_wordUShr platform) [idx, mkIntExpr platform (pc_MUT_ARR_PTRS_CARD_BITS (platformConstants platform))]) ) (CmmLit (CmmInt 1 W8)) -loadArrPtrsSize :: Profile -> CmmExpr -> CmmExpr -loadArrPtrsSize profile addr = cmmLoadBWord platform (cmmOffsetB platform addr off) - where off = fixedHdrSize profile + pc_OFFSET_StgMutArrPtrs_ptrs (profileConstants profile) - platform = profilePlatform profile - mkBasicIndexedRead :: AlignmentSpec -> ByteOff -- Initial offset in bytes -> Maybe MachOp -- Optional result cast @@ -2169,18 +2168,15 @@ mkBasicIndexedRead alignment off (Just cast) ty res base idx_ty idx cmmLoadIndexOffExpr platform alignment off ty base idx_ty idx]) mkBasicIndexedWrite :: ByteOff -- Initial offset in bytes - -> Maybe MachOp -- Optional value cast -> CmmExpr -- Base address -> CmmType -- Type of element by which we are indexing -> CmmExpr -- Index -> CmmExpr -- Value to write -> FCode () -mkBasicIndexedWrite off Nothing base idx_ty idx val +mkBasicIndexedWrite off base idx_ty idx val = do platform <- getPlatform let alignment = alignmentFromTypes (cmmExprType platform val) idx_ty emitStore' alignment (cmmIndexOffExpr platform off (typeWidth idx_ty) base idx) val -mkBasicIndexedWrite off (Just cast) base idx_ty idx val - = mkBasicIndexedWrite off Nothing base idx_ty idx (CmmMachOp cast [val]) -- ---------------------------------------------------------------------------- -- Misc utils @@ -2208,6 +2204,30 @@ cmmLoadIndexOffExpr platform alignment off ty base idx_ty idx setInfo :: CmmExpr -> CmmExpr -> CmmAGraph setInfo closure_ptr info_ptr = mkStore closure_ptr info_ptr +maybeCast :: Maybe MachOp -> CmmExpr -> CmmExpr +maybeCast Nothing val = val +maybeCast (Just cast) val = CmmMachOp cast [val] + +ptrArraySize :: Platform -> Profile -> CmmExpr -> CmmExpr +ptrArraySize platform profile arr = + cmmLoadBWord platform (cmmOffsetB platform arr sz_off) + where sz_off = fixedHdrSize profile + + pc_OFFSET_StgMutArrPtrs_ptrs (platformConstants platform) + +smallPtrArraySize :: Platform -> Profile -> CmmExpr -> CmmExpr +smallPtrArraySize platform profile arr = + cmmLoadBWord platform (cmmOffsetB platform arr sz_off) + where sz_off = fixedHdrSize profile + + pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform) + +byteArraySize :: Platform -> Profile -> CmmExpr -> CmmExpr +byteArraySize platform profile arr = + cmmLoadBWord platform (cmmOffsetB platform arr sz_off) + where sz_off = fixedHdrSize profile + + pc_OFFSET_StgArrBytes_bytes (platformConstants platform) + + + ------------------------------------------------------------------------------ -- Helpers for translating vector primops. @@ -2453,10 +2473,9 @@ doCompareByteArraysOp res ba1 ba1_off ba2 ba2_off n = do profile <- getProfile platform <- getPlatform - ifNonZero n $ do - let last_touched_idx off = cmmOffsetB platform (cmmAddWord platform off n) (-1) - doByteArrayBoundsCheck (last_touched_idx ba1_off) ba1 b8 b8 - doByteArrayBoundsCheck (last_touched_idx ba2_off) ba2 b8 b8 + whenCheckBounds $ ifNonZero n $ do + emitRangeBoundsCheck ba1_off n (byteArraySize platform profile ba1) + emitRangeBoundsCheck ba2_off n (byteArraySize platform profile ba2) ba1_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba1 (arrWordsHdrSize profile)) ba1_off ba2_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba2 (arrWordsHdrSize profile)) ba2_off @@ -2519,7 +2538,7 @@ doCopyByteArrayOp = emitCopyByteArray copy -- Copy data (we assume the arrays aren't overlapping since -- they're of different types) copy _src _dst dst_p src_p bytes align = - emitMemcpyCall dst_p src_p bytes align + emitCheckedMemcpyCall dst_p src_p bytes align -- | Takes a source 'MutableByteArray#', an offset in the source -- array, a destination 'MutableByteArray#', an offset into the @@ -2540,6 +2559,19 @@ doCopyMutableByteArrayOp = emitCopyByteArray copy (getCode $ emitMemcpyCall dst_p src_p bytes align) emit =<< mkCmmIfThenElse (cmmEqWord platform src dst) moveCall cpyCall +-- | Takes a source 'MutableByteArray#', an offset in the source +-- array, a destination 'MutableByteArray#', an offset into the +-- destination array, and the number of bytes to copy. Copies the +-- given number of bytes from the source array to the destination +-- array. Assumes the two ranges are disjoint +doCopyMutableByteArrayNonOverlappingOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr + -> FCode () +doCopyMutableByteArrayNonOverlappingOp = emitCopyByteArray copy + where + copy _src _dst dst_p src_p bytes align = do + emitCheckedMemcpyCall dst_p src_p bytes align + + emitCopyByteArray :: (CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode ()) -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr @@ -2548,10 +2580,9 @@ emitCopyByteArray copy src src_off dst dst_off n = do profile <- getProfile platform <- getPlatform - ifNonZero n $ do - let last_touched_idx off = cmmOffsetB platform (cmmAddWord platform off n) (-1) - doByteArrayBoundsCheck (last_touched_idx src_off) src b8 b8 - doByteArrayBoundsCheck (last_touched_idx dst_off) dst b8 b8 + whenCheckBounds $ ifNonZero n $ do + emitRangeBoundsCheck src_off n (byteArraySize platform profile src) + emitRangeBoundsCheck dst_off n (byteArraySize platform profile dst) let byteArrayAlignment = wordAlignment platform srcOffAlignment = cmmExprAlignment src_off @@ -2569,11 +2600,10 @@ doCopyByteArrayToAddrOp src src_off dst_p bytes = do -- Use memcpy (we are allowed to assume the arrays aren't overlapping) profile <- getProfile platform <- getPlatform - ifNonZero bytes $ do - let last_touched_idx off = cmmOffsetB platform (cmmAddWord platform off bytes) (-1) - doByteArrayBoundsCheck (last_touched_idx src_off) src b8 b8 + whenCheckBounds $ ifNonZero bytes $ do + emitRangeBoundsCheck src_off bytes (byteArraySize platform profile src) src_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform src (arrWordsHdrSize profile)) src_off - emitMemcpyCall dst_p src_p bytes (mkAlignment 1) + emitCheckedMemcpyCall dst_p src_p bytes (mkAlignment 1) -- | Takes a source 'MutableByteArray#', an offset in the source array, a -- destination 'Addr#', and the number of bytes to copy. Copies the given @@ -2590,33 +2620,51 @@ doCopyAddrToByteArrayOp src_p dst dst_off bytes = do -- Use memcpy (we are allowed to assume the arrays aren't overlapping) profile <- getProfile platform <- getPlatform - ifNonZero bytes $ do - let last_touched_idx off = cmmOffsetB platform (cmmAddWord platform off bytes) (-1) - doByteArrayBoundsCheck (last_touched_idx dst_off) dst b8 b8 + whenCheckBounds $ ifNonZero bytes $ do + emitRangeBoundsCheck dst_off bytes (byteArraySize platform profile dst) dst_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform dst (arrWordsHdrSize profile)) dst_off - emitMemcpyCall dst_p src_p bytes (mkAlignment 1) + emitCheckedMemcpyCall dst_p src_p bytes (mkAlignment 1) + +-- | Takes a source 'Addr#', a destination 'Addr#', and the number of +-- bytes to copy. Copies the given number of bytes from the source +-- memory region to the destination array. +doCopyAddrToAddrOp :: CmmExpr -> CmmExpr -> CmmExpr -> FCode () +doCopyAddrToAddrOp src_p dst_p bytes = do + -- Use memmove; the ranges may overlap + emitMemmoveCall dst_p src_p bytes (mkAlignment 1) + +-- | Takes a source 'Addr#', a destination 'Addr#', and the number of +-- bytes to copy. Copies the given number of bytes from the source +-- memory region to the destination region. The regions may not overlap. +doCopyAddrToAddrNonOverlappingOp :: CmmExpr -> CmmExpr -> CmmExpr -> FCode () +doCopyAddrToAddrNonOverlappingOp src_p dst_p bytes = do + -- Use memcpy; the ranges may not overlap + emitCheckedMemcpyCall dst_p src_p bytes (mkAlignment 1) ifNonZero :: CmmExpr -> FCode () -> FCode () ifNonZero e it = do platform <- getPlatform let pred = cmmNeWord platform e (zeroExpr platform) code <- getCode it - emit =<< mkCmmIfThen' pred code (Just False) + emit =<< mkCmmIfThen' pred code (Just True) + -- This function is used for range operation bounds-checks; + -- Most calls to those ops will not have range length zero. + -- ---------------------------------------------------------------------------- -- Setting byte arrays -- | Takes a 'MutableByteArray#', an offset into the array, a length, -- and a byte, and sets each of the selected bytes in the array to the --- character. +-- given byte. doSetByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode () doSetByteArrayOp ba off len c = do profile <- getProfile platform <- getPlatform - doByteArrayBoundsCheck off ba b8 b8 - doByteArrayBoundsCheck (cmmOffset platform (cmmAddWord platform off len) (-1)) ba b8 b8 + whenCheckBounds $ ifNonZero len $ + emitRangeBoundsCheck off len (byteArraySize platform profile ba) let byteArrayAlignment = wordAlignment platform -- known since BA is allocated on heap offsetAlignment = cmmExprAlignment off @@ -2625,6 +2673,14 @@ doSetByteArrayOp ba off len c = do p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba (arrWordsHdrSize profile)) off emitMemsetCall p c len align +-- | Takes an 'Addr#', a length, and a byte, and sets each of the +-- selected bytes in memory to the given byte. +doSetAddrRangeOp :: CmmExpr -> CmmExpr -> CmmExpr + -> FCode () +doSetAddrRangeOp dst len c = do + emitMemsetCall dst c len (mkAlignment 1) + + -- ---------------------------------------------------------------------------- -- Allocating arrays @@ -2687,7 +2743,7 @@ doCopyArrayOp = emitCopyArray copy -- they're of different types) copy _src _dst dst_p src_p bytes = do platform <- getPlatform - emitMemcpyCall dst_p src_p (mkIntExpr platform bytes) + emitCheckedMemcpyCall dst_p src_p (mkIntExpr platform bytes) (wordAlignment platform) @@ -2729,8 +2785,11 @@ emitCopyArray copy src0 src_off dst0 dst_off0 n = dst <- assignTempE dst0 dst_off <- assignTempE dst_off0 - doPtrArrayBoundsCheck (cmmAddWord platform src_off (mkIntExpr platform n)) src - doPtrArrayBoundsCheck (cmmAddWord platform dst_off (mkIntExpr platform n)) dst + whenCheckBounds $ do + emitRangeBoundsCheck src_off (mkIntExpr platform n) + (ptrArraySize platform profile src) + emitRangeBoundsCheck dst_off (mkIntExpr platform n) + (ptrArraySize platform profile dst) -- Nonmoving collector write barrier emitCopyUpdRemSetPush platform (arrPtrsHdrSize profile) dst dst_off n @@ -2749,7 +2808,7 @@ emitCopyArray copy src0 src_off dst0 dst_off0 n = -- The base address of the destination card table dst_cards_p <- assignTempE $ cmmOffsetExprW platform dst_elems_p - (loadArrPtrsSize profile dst) + (ptrArraySize platform profile dst) emitSetCards dst_off dst_cards_p n @@ -2761,7 +2820,7 @@ doCopySmallArrayOp = emitCopySmallArray copy -- they're of different types) copy _src _dst dst_p src_p bytes = do platform <- getPlatform - emitMemcpyCall dst_p src_p (mkIntExpr platform bytes) + emitCheckedMemcpyCall dst_p src_p (mkIntExpr platform bytes) (wordAlignment platform) @@ -2798,9 +2857,11 @@ emitCopySmallArray copy src0 src_off dst0 dst_off n = src <- assignTempE src0 dst <- assignTempE dst0 - when (n /= 0) $ do - doSmallPtrArrayBoundsCheck (cmmAddWord platform src_off (mkIntExpr platform n)) src - doSmallPtrArrayBoundsCheck (cmmAddWord platform dst_off (mkIntExpr platform n)) dst + whenCheckBounds $ do + emitRangeBoundsCheck src_off (mkIntExpr platform n) + (smallPtrArraySize platform profile src) + emitRangeBoundsCheck dst_off (mkIntExpr platform n) + (smallPtrArraySize platform profile dst) -- Nonmoving collector write barrier emitCopyUpdRemSetPush platform (smallArrPtrsHdrSize profile) dst dst_off n @@ -2895,7 +2956,7 @@ emitCloneSmallArray info_p res_r src src_off n = do emit $ mkAssign (CmmLocal res_r) (CmmReg arr) --- | Takes and offset in the destination array, the base address of +-- | Takes an offset in the destination array, the base address of -- the card table, and the number of elements affected (*not* the -- number of cards). The number of elements may not be zero. -- Marks the relevant cards as dirty. @@ -2948,7 +3009,7 @@ doWriteSmallPtrArrayOp addr idx val = do whenUpdRemSetEnabled $ emitUpdRemSetPush (CmmReg (CmmLocal tmp)) emitPrimCall [] MO_WriteBarrier [] -- #12469 - mkBasicIndexedWrite (smallArrPtrsHdrSize profile) Nothing addr ty idx val + mkBasicIndexedWrite (smallArrPtrsHdrSize profile) addr ty idx val emit (setInfo addr (CmmLit (CmmLabel mkSMAP_DIRTY_infoLabel))) ------------------------------------------------------------------------------ @@ -3074,6 +3135,26 @@ emitMemcpyCall dst src n align = (MO_Memcpy (alignmentBytes align)) [ dst, src, n ] +-- | Emit a call to @memcpy@, but check for range +-- overlap when -fcheck-prim-bounds is on. +emitCheckedMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode () +emitCheckedMemcpyCall dst src n align = do + whenCheckBounds (getPlatform >>= doCheck) + emitMemcpyCall dst src n align + where + doCheck platform = do + overlapCheckFailed <- getCode $ + emitCCallNeverReturns [] (mkLblExpr mkMemcpyRangeOverlapLabel) [] + emit =<< mkCmmIfThen' rangesOverlap overlapCheckFailed (Just False) + where + rangesOverlap = (checkDiff dst src `or` checkDiff src dst) `ne` zero + checkDiff p q = (p `minus` q) `uLT` n + or = cmmOrWord platform + minus = cmmSubWord platform + uLT = cmmULtWord platform + ne = cmmNeWord platform + zero = zeroExpr platform + -- | Emit a call to @memmove at . emitMemmoveCall :: CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode () emitMemmoveCall dst src n align = @@ -3168,50 +3249,68 @@ emitCtzCall res x width = -- Array bounds checking --------------------------------------------------------------------------- -doBoundsCheck :: CmmExpr -- ^ accessed index - -> CmmExpr -- ^ array size (in elements) - -> FCode () -doBoundsCheck idx sz = do - do_bounds_check <- stgToCmmDoBoundsCheck <$> getStgToCmmConfig - platform <- getPlatform - when do_bounds_check (doCheck platform) - where - doCheck platform = do - boundsCheckFailed <- getCode $ emitCCall [] (mkLblExpr mkOutOfBoundsAccessLabel) [] - emit =<< mkCmmIfThen' isOutOfBounds boundsCheckFailed (Just False) - where - uGE = cmmUGeWord platform - and = cmmAndWord platform - zero = zeroExpr platform - ne = cmmNeWord platform - isOutOfBounds = ((idx `uGE` sz) `and` (idx `ne` zero)) `ne` zero +whenCheckBounds :: FCode () -> FCode () +whenCheckBounds a = do + config <- getStgToCmmConfig + case stgToCmmDoBoundsCheck config of + False -> pure () + True -> a --- We want to make sure that the array size computation is pushed into the --- Opt_DoBoundsChecking check to avoid regregressing compiler performance when --- it's disabled. -{-# INLINE doBoundsCheck #-} +emitBoundsCheck :: CmmExpr -- ^ accessed index + -> CmmExpr -- ^ array size (in elements) + -> FCode () +emitBoundsCheck idx sz = do + assertM (stgToCmmDoBoundsCheck <$> getStgToCmmConfig) + platform <- getPlatform + boundsCheckFailed <- getCode $ + emitCCallNeverReturns [] (mkLblExpr mkOutOfBoundsAccessLabel) [] + let isOutOfBounds = cmmUGeWord platform idx sz + emit =<< mkCmmIfThen' isOutOfBounds boundsCheckFailed (Just False) + +emitRangeBoundsCheck :: CmmExpr -- ^ first accessed index + -> CmmExpr -- ^ number of accessed indices (non-zero) + -> CmmExpr -- ^ array size (in elements) + -> FCode () +emitRangeBoundsCheck idx len arrSizeExpr = do + assertM (stgToCmmDoBoundsCheck <$> getStgToCmmConfig) + config <- getStgToCmmConfig + platform <- getPlatform + arrSize <- assignTempE arrSizeExpr + -- arrSizeExpr is probably a load we don't want to duplicate + rangeTooLargeReg <- newTemp (bWord platform) + lastSafeIndexReg <- newTemp (bWord platform) + _ <- withSequel (AssignTo [lastSafeIndexReg, rangeTooLargeReg] False) $ + cmmPrimOpApp config WordSubCOp [arrSize, len] Nothing + boundsCheckFailed <- getCode $ + emitCCallNeverReturns [] (mkLblExpr mkOutOfBoundsAccessLabel) [] + let + rangeTooLarge = CmmReg (CmmLocal rangeTooLargeReg) + lastSafeIndex = CmmReg (CmmLocal lastSafeIndexReg) + badStartIndex = (idx `uGT` lastSafeIndex) + isOutOfBounds = (rangeTooLarge `or` badStartIndex) `neq` zero + uGT = cmmUGtWord platform + or = cmmOrWord platform + neq = cmmNeWord platform + zero = zeroExpr platform + emit =<< mkCmmIfThen' isOutOfBounds boundsCheckFailed (Just False) doPtrArrayBoundsCheck :: CmmExpr -- ^ accessed index (in bytes) -> CmmExpr -- ^ pointer to @StgMutArrPtrs@ -> FCode () -doPtrArrayBoundsCheck idx arr = do +doPtrArrayBoundsCheck idx arr = whenCheckBounds $ do profile <- getProfile platform <- getPlatform - let sz = cmmLoadBWord platform (cmmOffset platform arr sz_off) - sz_off = fixedHdrSize profile + pc_OFFSET_StgMutArrPtrs_ptrs (platformConstants platform) - doBoundsCheck idx sz + emitBoundsCheck idx (ptrArraySize platform profile arr) doSmallPtrArrayBoundsCheck :: CmmExpr -- ^ accessed index (in bytes) -> CmmExpr -- ^ pointer to @StgMutArrPtrs@ -> FCode () -doSmallPtrArrayBoundsCheck idx arr = do +doSmallPtrArrayBoundsCheck idx arr = whenCheckBounds $ do profile <- getProfile platform <- getPlatform - let sz = cmmLoadBWord platform (cmmOffset platform arr sz_off) - sz_off = fixedHdrSize profile + pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform) - doBoundsCheck idx sz + emitBoundsCheck idx (smallPtrArraySize platform profile arr) doByteArrayBoundsCheck :: CmmExpr -- ^ accessed index (in elements) @@ -3219,18 +3318,18 @@ doByteArrayBoundsCheck -> CmmType -- ^ indexing type -> CmmType -- ^ element type -> FCode () -doByteArrayBoundsCheck idx arr idx_ty elem_ty = do +doByteArrayBoundsCheck idx arr idx_ty elem_ty = whenCheckBounds $ do profile <- getProfile platform <- getPlatform - let sz = cmmLoadBWord platform (cmmOffset platform arr sz_off) - sz_off = fixedHdrSize profile + pc_OFFSET_StgArrBytes_bytes (platformConstants platform) - elem_sz = widthInBytes $ typeWidth elem_ty - idx_sz = widthInBytes $ typeWidth idx_ty - -- Ensure that the last byte of the access is within the array - idx_bytes = cmmOffsetB platform - (cmmMulWord platform idx (mkIntExpr platform idx_sz)) - (elem_sz - 1) - doBoundsCheck idx_bytes sz + let elem_w = typeWidth elem_ty + idx_w = typeWidth idx_ty + elem_sz = mkIntExpr platform $ widthInBytes elem_w + arr_sz = byteArraySize platform profile arr + effective_arr_sz = + cmmUShrWord platform arr_sz (mkIntExpr platform (widthInLog idx_w)) + if elem_w == idx_w + then emitBoundsCheck idx effective_arr_sz -- aligned => simpler check + else assert (idx_w == W8) (emitRangeBoundsCheck idx elem_sz arr_sz) --------------------------------------------------------------------------- -- Pushing to the update remembered set ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -717,15 +717,19 @@ genPrim prof bound ty op = case op of . boundsChecked bound a2 (Add o2 (Sub n 1)) $ appS "h$copyMutableByteArray" [a1,o1,a2,o2,n] CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyMutableByteArrayNonOverlappingOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs CopyByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs CopyMutableByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs CopyAddrToByteArrayOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyAddrToAddrOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyAddrToAddrNonOverlappingOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs SetByteArrayOp -> \[] [a,o,n,v] -> PrimInline . boundsChecked bound a (Add o (Sub n 1)) $ loopBlockS zero_ (.<. n) \i -> [ write_u8 a (Add o i) v , postIncrS i ] + SetAddrRangeOp -> \[] xs@[_a,_o,_n,_v] -> genPrim prof bound ty SetByteArrayOp [] xs AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i v ===================================== libraries/base/Data/Array/Byte.hs ===================================== @@ -134,7 +134,7 @@ unsafeCopyByteArray (MutableByteArray dst#) (I# doff#) (ByteArray src#) (I# soff -- | Copy a slice from one mutable byte array to another -- or to the same mutable byte array. -- --- /Note:/ this function does not do bounds checking. +-- /Note:/ this function does not do bounds or overlap checking. unsafeCopyMutableByteArray :: MutableByteArray s -- ^ destination array -> Int -- ^ offset into destination array @@ -144,7 +144,7 @@ unsafeCopyMutableByteArray -> ST s () {-# INLINE unsafeCopyMutableByteArray #-} unsafeCopyMutableByteArray (MutableByteArray dst#) (I# doff#) (MutableByteArray src#) (I# soff#) (I# sz#) = - ST (\s# -> case copyMutableByteArray# src# soff# dst# doff# sz# s# of + ST (\s# -> case copyMutableByteArrayNonOverlapping# src# soff# dst# doff# sz# s# of s'# -> (# s'#, () #)) -- | @since 4.17.0.0 ===================================== libraries/base/Foreign/Marshal/Utils.hs ===================================== @@ -1,6 +1,9 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + ----------------------------------------------------------------------------- -- | -- Module : Foreign.Marshal.Utils @@ -50,13 +53,11 @@ module Foreign.Marshal.Utils ( ) where import Data.Maybe -import Foreign.Ptr ( Ptr, nullPtr ) +import GHC.Ptr ( Ptr(..), nullPtr ) import Foreign.Storable ( Storable(poke) ) -import Foreign.C.Types ( CSize(..), CInt(..) ) import Foreign.Marshal.Alloc ( malloc, alloca ) -import Data.Word ( Word8 ) +import GHC.Word ( Word8(..) ) -import GHC.Real ( fromIntegral ) import GHC.Num import GHC.Base @@ -158,9 +159,8 @@ copyBytes -> Ptr a -- ^ Source -> Int -- ^ Size in bytes -> IO () -copyBytes dest src size = do - _ <- memcpy dest src (fromIntegral size) - return () +copyBytes = coerce $ \(Ptr dest#) (Ptr src#) (I# size#) s + -> (# copyAddrToAddrNonOverlapping# src# dest# size# s, () #) -- |Copies the given number of bytes from the second area (source) into the -- first (destination); the copied areas /may/ overlap @@ -170,9 +170,8 @@ moveBytes -> Ptr a -- ^ Source -> Int -- ^ Size in bytes -> IO () -moveBytes dest src size = do - _ <- memmove dest src (fromIntegral size) - return () +moveBytes = coerce $ \(Ptr dest#) (Ptr src#) (I# size#) s + -> (# copyAddrToAddr# src# dest# size# s, () #) -- Filling up memory area with required values -- ------------------------------------------- @@ -180,16 +179,6 @@ moveBytes dest src size = do -- |Fill a given number of bytes in memory area with a byte value. -- -- @since 4.8.0.0 -fillBytes :: Ptr a -> Word8 -> Int -> IO () -fillBytes dest char size = do - _ <- memset dest (fromIntegral char) (fromIntegral size) - return () - --- auxiliary routines --- ------------------- - --- |Basic C routines needed for memory copying --- -foreign import ccall unsafe "string.h" memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr a) -foreign import ccall unsafe "string.h" memmove :: Ptr a -> Ptr a -> CSize -> IO (Ptr a) -foreign import ccall unsafe "string.h" memset :: Ptr a -> CInt -> CSize -> IO (Ptr a) +fillBytes :: Ptr a -> Word8 -> Int -> IO () +fillBytes = coerce $ \(Ptr dest#) (W8# byte#) (I# size#) s + -> (# setAddrRange# dest# size# (word2Int# (word8ToWord# byte#)) s, () #) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -14,6 +14,13 @@ - `sameMutVar#`, `sameTVar#`, `sameMVar#` - `sameIOPort#`, `eqStableName#`. +- Several new primops were added: + + - `copyMutableByteArrayNonOverlapping#` + - `copyAddrToAddr#` + - `copyAddrToAddrNonOverlapping#` + - `setAddrRange#` + ## 0.10.0 - Shipped with GHC 9.6.1 ===================================== rts/RtsMessages.c ===================================== @@ -338,3 +338,12 @@ rtsOutOfBoundsAccess() { barf("Encountered out of bounds array access."); } + +// Used by code generator +void rtsMemcpyRangeOverlap(void) STG_NORETURN; + +void +rtsMemcpyRangeOverlap() +{ + barf("Encountered overlapping source/destination ranges in a memcpy-using op."); +} ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray2.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE NondecreasingIndentation #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 4# s0 of + (# s1, a_marr #) -> case newByteArray# 4# s1 of + (# s2, b_marr #) -> case unsafeFreezeByteArray# a_marr s2 of + (# s3, a_arr #) -> case unsafeFreezeByteArray# b_marr s2 of + (# s4, b_arr #) -> case compareByteArrays# a_arr (-1#) b_arr 0# 4# of + 0# -> (# s4, () #) + ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray3.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE NondecreasingIndentation #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 4# s0 of + (# s1, a_marr #) -> case newByteArray# 4# s1 of + (# s2, b_marr #) -> case unsafeFreezeByteArray# a_marr s2 of + (# s3, a_arr #) -> case unsafeFreezeByteArray# b_marr s2 of + (# s4, b_arr #) -> case compareByteArrays# a_arr 2# b_arr 3# (-1#) of + 0# -> (# s4, () #) + ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsReadInt64Array.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 23# s0 of + (# s1, marr #) -> + case readInt64Array# marr 2# s1 of + (# s2, _n #) -> (# s2, () #) + ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsReadSmallArray.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newSmallArray# 5# () s0 of + (# s1, marr #) -> readSmallArray# marr (-1#) s1 + ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsReadWord64Array.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 23# s0 of + (# s1, marr #) -> + case readWord64Array# marr (-1#) s1 of + (# s2, _n #) -> (# s2, () #) + ===================================== testsuite/tests/codeGen/should_fail/CheckBoundsReadWord8ArrayAsWord32.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 7# s0 of + (# s1, marr #) -> + case readWord8ArrayAsWord32# marr (-3#) s1 of + -- only the last byte of the desired word32 is in bounds + (# s2, _n #) -> (# s2, () #) + ===================================== testsuite/tests/codeGen/should_fail/CheckOverlapCopyAddrToByteArray.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newPinnedByteArray# 7# s0 of + (# s1, marr #) -> case mutableByteArrayContents# marr of + ptr -> (# copyAddrToByteArray# ptr marr 3# 4# s1, () #) ===================================== testsuite/tests/codeGen/should_fail/CheckOverlapCopyByteArray.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import GHC.IO + +main :: IO () +main = do + IO $ \s0 -> + case newByteArray# 7# s0 of + (# s1, marr #) -> case unsafeFreezeByteArray# marr s1 of + (# s2, arr #) -> (# copyByteArray# arr 3# marr 0# 4# s2, () #) + ===================================== testsuite/tests/codeGen/should_fail/all.T ===================================== @@ -10,10 +10,18 @@ def check_bounds_test(name): [ignore_stderr, exit_code(127 if opsys('mingw32') else 134)], compile_and_run, ['-fcheck-prim-bounds']) -check_bounds_test('CheckBoundsWriteArray') -check_bounds_test('CheckBoundsIndexArray') +check_bounds_test('CheckBoundsWriteArray') # Check past end +check_bounds_test('CheckBoundsIndexArray') # Check past end +check_bounds_test('CheckBoundsReadSmallArray') # Check before start check_bounds_test('CheckBoundsReadInt8Array') -check_bounds_test('CheckBoundsReadWord8ArrayAsInt32') +check_bounds_test('CheckBoundsReadInt64Array') # read past end +check_bounds_test('CheckBoundsReadWord64Array') # read before start +check_bounds_test('CheckBoundsReadWord8ArrayAsInt32') # Check last byte +check_bounds_test('CheckBoundsReadWord8ArrayAsWord32') # Check first byte check_bounds_test('CheckBoundsCopyByteArray') -check_bounds_test('CheckBoundsCompareByteArray') +check_bounds_test('CheckBoundsCompareByteArray') # Check last byte, 2nd array +check_bounds_test('CheckBoundsCompareByteArray2') # Check first byte, 1st array +check_bounds_test('CheckBoundsCompareByteArray3') # Check negative length +check_bounds_test('CheckOverlapCopyByteArray') +check_bounds_test('CheckOverlapCopyAddrToByteArray') ===================================== testsuite/tests/codeGen/should_run/CheckBoundsOK.hs ===================================== @@ -0,0 +1,244 @@ +-- This test verifies that correct (not out-of-bounds) uses +-- of primops that we can bounds-check with -fcheck-prim-bounds +-- do not cause spurious bounds-checking failures. + +-- Currently this tests most ByteArray#, Array#, and SmallArray# operations. +-- (Theoretically it could also test Addr# operations, +-- since those /can/ be bounds-checked with the JS back-end.) + +{-# LANGUAGE CPP #-} + +{-# LANGUAGE GHC2021 #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +module Main where + +import Data.Array.Byte +import Data.Bits +import Control.Monad +import GHC.Exts +import GHC.IO +import GHC.Word +import GHC.Int +import GHC.Float +import GHC.Stable +import System.IO + +#define TEST_READ_WRITE(CONDITION, READ_OP, INDEX_OP, WRITE_OP) \ + when (CONDITION) $ IO $ \s0 -> \ + case (READ_OP) arrU# i# s0 of \ + (# s1, v# #) -> case (WRITE_OP) arrP# i# v# s1 of \ + s2 -> (# (WRITE_OP) arrU# i# ((INDEX_OP) arrF# i#) s2, () #) + +#define ALIGNED_RW(WIDTH, READ_OP, INDEX_OP, WRITE_OP) \ + TEST_READ_WRITE(i < size `div` (WIDTH), READ_OP, INDEX_OP, WRITE_OP) + +#define UNALIGNED_RW(WIDTH, READ_OP, INDEX_OP, WRITE_OP) \ + TEST_READ_WRITE(i + (WIDTH) <= size, READ_OP, INDEX_OP, WRITE_OP) + +#define TEST_CAS(WIDTH, CON, CAS_OP) \ + when (i < size `div` (WIDTH)) $ IO $ \s0 -> \ + case (0, 7) of \ + (CON v0, CON v7) -> case (CAS_OP) arrU# i# v0 v7 s0 of \ + (# s1, v' #) -> (# s1, () #) + + +wrapEffect :: (State# RealWorld -> State# RealWorld) -> IO () +wrapEffect eff = IO (\s0 -> (# eff s0, () #)) + + +testByteArraysOfSize :: Int -> IO () +testByteArraysOfSize (size@(I# size#)) = do + let mkArr op = IO $ \s0 -> case op size# s0 of + (# s1, newArr #) + -> (# setByteArray# newArr 0# size# 123# s1, + MutableByteArray newArr #) + MutableByteArray arrU# <- mkArr newByteArray# + MutableByteArray arrP# <- mkArr newPinnedByteArray# + ByteArray arrF# <- do + MutableByteArray arrToFreeze <- mkArr newByteArray# + IO $ \s0 -> case unsafeFreezeByteArray# arrToFreeze s0 of + (# s1, frozenArr #) -> (# s1, ByteArray frozenArr #) + let !nws = finiteBitSize (0 :: Int) `div` 8 + !bufP = mutableByteArrayContents# arrP# + + + forM_ [0..size] $ \i@(I# i#) -> do + -- test valid aligned read/write ops + -- (expressed via CPP macro because of non-uniform representations) + ALIGNED_RW(1, readWord8Array#, indexWord8Array#, writeWord8Array#) + ALIGNED_RW(2, readWord16Array#, indexWord16Array#, writeWord16Array#) + ALIGNED_RW(4, readWord32Array#, indexWord32Array#, writeWord32Array#) + ALIGNED_RW(8, readWord64Array#, indexWord64Array#, writeWord64Array#) + ALIGNED_RW(nws, readWordArray#, indexWordArray#, writeWordArray#) + + ALIGNED_RW(1, readInt8Array#, indexInt8Array#, writeInt8Array#) + ALIGNED_RW(2, readInt16Array#, indexInt16Array#, writeInt16Array#) + ALIGNED_RW(4, readInt32Array#, indexInt32Array#, writeInt32Array#) + ALIGNED_RW(8, readInt64Array#, indexInt64Array#, writeInt64Array#) + ALIGNED_RW(nws, readIntArray#, indexIntArray#, writeIntArray#) + + ALIGNED_RW(4, readFloatArray#, indexFloatArray#, writeFloatArray#) + ALIGNED_RW(8, readDoubleArray#, indexDoubleArray#, writeDoubleArray#) + + ALIGNED_RW(1, readCharArray#, indexCharArray#, writeCharArray#) + ALIGNED_RW(4, readWideCharArray#, indexWideCharArray#, writeWideCharArray#) + + -- TODO: What is the right condition is for Addr# with the JS backend? + ALIGNED_RW(nws, readAddrArray#, indexAddrArray#, writeAddrArray#) + ALIGNED_RW(nws, readStablePtrArray#, indexStablePtrArray#, writeStablePtrArray#) + + + -- test valid unaligned read/write ops + -- (expressed via CPP macro because of non-uniform representations) + -- no primops for unaligned word8 access + UNALIGNED_RW(2, readWord8ArrayAsWord16#, indexWord8ArrayAsWord16#, writeWord8ArrayAsWord16#) + UNALIGNED_RW(4, readWord8ArrayAsWord32#, indexWord8ArrayAsWord32#, writeWord8ArrayAsWord32#) + UNALIGNED_RW(8, readWord8ArrayAsWord64#, indexWord8ArrayAsWord64#, writeWord8ArrayAsWord64#) + UNALIGNED_RW(nws, readWord8ArrayAsWord#, indexWord8ArrayAsWord#, writeWord8ArrayAsWord#) + + -- no primops for unaligned int8 access + UNALIGNED_RW(2, readWord8ArrayAsInt16#, indexWord8ArrayAsInt16#, writeWord8ArrayAsInt16#) + UNALIGNED_RW(4, readWord8ArrayAsInt32#, indexWord8ArrayAsInt32#, writeWord8ArrayAsInt32#) + UNALIGNED_RW(8, readWord8ArrayAsInt64#, indexWord8ArrayAsInt64#, writeWord8ArrayAsInt64#) + UNALIGNED_RW(nws, readWord8ArrayAsInt#, indexWord8ArrayAsInt#, writeWord8ArrayAsInt#) + + UNALIGNED_RW(4, readWord8ArrayAsFloat#, indexWord8ArrayAsFloat#, writeWord8ArrayAsFloat#) + UNALIGNED_RW(8, readWord8ArrayAsDouble#, indexWord8ArrayAsDouble#, writeWord8ArrayAsDouble#) + + UNALIGNED_RW(1, readWord8ArrayAsChar#, indexWord8ArrayAsChar#, writeWord8ArrayAsChar#) + UNALIGNED_RW(4, readWord8ArrayAsWideChar#, indexWord8ArrayAsWideChar#, writeWord8ArrayAsWideChar#) + + -- TODO: What is the right condition is for Addr# with the JS backend? + UNALIGNED_RW(nws, readWord8ArrayAsAddr#, indexWord8ArrayAsAddr#, writeWord8ArrayAsAddr#) + UNALIGNED_RW(nws, readWord8ArrayAsStablePtr#, indexWord8ArrayAsStablePtr#, writeWord8ArrayAsStablePtr#) + + + when (i < size `div` nws) $ do + let testFetchModify :: (MutableByteArray# RealWorld -> Int# -> Int# + -> State# RealWorld -> (# State# RealWorld, Int# #)) + -> IO () + testFetchModify op + = IO (\s -> case op arrU# i# 137# s of (# s', _ #) -> (# s', () #) ) + testFetchModify fetchXorIntArray# + testFetchModify fetchOrIntArray# + testFetchModify fetchNandIntArray# + testFetchModify fetchAndIntArray# + testFetchModify fetchSubIntArray# + testFetchModify fetchAddIntArray# + + IO $ \s0 -> case atomicReadIntArray# arrU# i# s0 of + (# s1, v #) -> (# atomicWriteIntArray# arrP# i# v s1, () #) + + + TEST_CAS(8, I64#, casInt64Array#) + TEST_CAS(4, I32#, casInt32Array#) + TEST_CAS(2, I16#, casInt16Array#) + TEST_CAS(1, I8# , casInt8Array#) + TEST_CAS(nws, I#, casIntArray#) + + + -- test valid range ops + forM_ [0..size] $ \rangeLen@(I# rangeLen#) -> do + let ixs | rangeLen == 0 = [-4 .. size + 4] -- empty ranges are not out-of-bounds + | otherwise = [0 .. size - rangeLen] + forM_ ixs $ \i@(I# i#) -> do + wrapEffect (setByteArray# arrU# i# rangeLen# 234#) + forM_ ixs $ \j@(I# j#) -> do + wrapEffect (copyMutableByteArrayNonOverlapping# arrP# i# arrU# j# rangeLen#) + wrapEffect (copyByteArray# arrF# i# arrU# j# rangeLen#) + wrapEffect (copyMutableByteArray# arrU# i# arrP# j# rangeLen#) + wrapEffect (copyMutableByteArray# arrU# i# arrU# j# rangeLen#) + case compareByteArrays# arrF# i# arrF# j# rangeLen# of + v -> wrapEffect (setByteArray# arrP# j# rangeLen# (v `andI#` 255#)) + let !rangeP = bufP `plusAddr#` j# + wrapEffect (copyAddrToByteArray# rangeP arrU# i# rangeLen#) + wrapEffect (copyMutableByteArrayToAddr# arrU# i# rangeP rangeLen#) + wrapEffect (copyByteArrayToAddr# arrF# i# rangeP rangeLen#) + when (abs (i - j) >= rangeLen) $ + wrapEffect (copyMutableByteArrayNonOverlapping# arrU# i# arrU# j# rangeLen#) + + + +data Array a = Array (Array# a) +data MutableArray s a = MutableArray (MutableArray# s a) +data SmallArray a = SmallArray (SmallArray# a) +data SmallMutableArray s a = SmallMutableArray (SmallMutableArray# s a) + + +testArraysOfSize :: Int -> IO () +testArraysOfSize (size@(I# size#)) = do + let mkArr v = IO $ \s0 -> case newArray# size# v s0 of + (# s1, newArr #) -> (# s1, MutableArray newArr #) + MutableArray arrM# <- mkArr 0 + Array arrF# <- do + MutableArray arrToFreeze <- mkArr 0 + forM_ [0 .. size - 1] $ \(i@(I# i#)) -> do + wrapEffect (writeArray# arrM# i# i) + wrapEffect (writeArray# arrToFreeze i# i) + + IO $ \s0 -> case unsafeFreezeArray# arrToFreeze s0 of + (# s1, frozenArr #) -> (# s1, Array frozenArr #) + + forM_ [0 .. size - 1] $ \(i@(I# i#)) -> do + + -- test read/index/write + IO $ \s0 -> case readArray# arrM# i# s0 of + (# s1, vm #) -> case indexArray# arrF# i# of + (# vf #) -> (# writeArray# arrM# i# (vm + vf) s1, () #) + + -- test casArray + IO $ \s0 -> case casArray# arrM# i# 0 7 s0 of + (# s1, _, _ #) -> (# s1, () #) + + -- test valid range ops + forM_ [0..size] $ \rangeLen@(I# rangeLen#) -> do + let ixs | rangeLen == 0 = [-4 .. size + 4] -- empty ranges are not out-of-bounds + | otherwise = [0 .. size - rangeLen] + forM_ ixs $ \(i@(I# i#)) -> do + forM_ ixs $ \(j@(I# j#)) -> do + wrapEffect (copyArray# arrF# i# arrM# j# rangeLen#) + wrapEffect (copyMutableArray# arrM# i# arrM# j# rangeLen#) + + +testSmallArraysOfSize :: Int -> IO () +testSmallArraysOfSize (size@(I# size#)) = do + let mkArr v = IO $ \s0 -> case newSmallArray# size# v s0 of + (# s1, newArr #) -> (# s1, SmallMutableArray newArr #) + SmallMutableArray arrM# <- mkArr 0 + SmallArray arrF# <- do + SmallMutableArray arrToFreeze <- mkArr 0 + forM_ [0 .. size - 1] $ \(i@(I# i#)) -> do + wrapEffect (writeSmallArray# arrM# i# i) + wrapEffect (writeSmallArray# arrToFreeze i# i) + + IO $ \s0 -> case unsafeFreezeSmallArray# arrToFreeze s0 of + (# s1, frozenArr #) -> (# s1, SmallArray frozenArr #) + + forM_ [0 .. size - 1] $ \(i@(I# i#)) -> do + + -- test read/index/write + IO $ \s0 -> case readSmallArray# arrM# i# s0 of + (# s1, vm #) -> case indexSmallArray# arrF# i# of + (# vf #) -> (# writeSmallArray# arrM# i# (vm + vf) s1, () #) + + -- test casSmallArray + IO $ \s0 -> case casSmallArray# arrM# i# 0 7 s0 of + (# s1, _, _ #) -> (# s1, () #) + + -- test valid range ops + forM_ [0..size] $ \rangeLen@(I# rangeLen#) -> do + let ixs | rangeLen == 0 = [-4 .. size + 4] -- empty ranges are not out-of-bounds + | otherwise = [0 .. size - rangeLen] + forM_ ixs $ \(i@(I# i#)) -> do + forM_ ixs $ \(j@(I# j#)) -> do + wrapEffect (copySmallArray# arrF# i# arrM# j# rangeLen#) + wrapEffect (copySmallMutableArray# arrM# i# arrM# j# rangeLen#) + + +main :: IO () +main = forM_ ([0..4] ++ [24..32]) $ \size -> do + testByteArraysOfSize size + testArraysOfSize size + testSmallArraysOfSize size ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -229,3 +229,4 @@ test('T20640b', normal, compile_and_run, ['']) test('T22296',[only_ways(llvm_ways) ,unless(arch('x86_64'), skip)],compile_and_run,['']) test('T22798', normal, compile_and_run, ['-fregs-graph']) +test('CheckBoundsOK', js_broken(23123), compile_and_run, ['-fcheck-prim-bounds']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/220a7a48cabdcfd2ef7bf5dbe3fd6df99e8d3c5b...f7da530c80c0117d5684bb52481e4a40d7e724cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/220a7a48cabdcfd2ef7bf5dbe3fd6df99e8d3c5b...f7da530c80c0117d5684bb52481e4a40d7e724cc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 05:05:09 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 01:05:09 -0400 Subject: [Git][ghc/ghc][master] Relax assertion in varToRecFieldOcc Message-ID: <642bb005a6e5_11425f15b7bc30272068@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - 5 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Types/Name/Occurrence.hs - + testsuite/tests/overloadedrecflds/should_compile/T23220.hs - + testsuite/tests/overloadedrecflds/should_compile/T23220_aux.hs - testsuite/tests/overloadedrecflds/should_compile/all.T Changes: ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1011,7 +1011,7 @@ newRecordFieldLabel dup_fields_ok has_sel (dc:_) (L loc (FieldOcc _ (L _ fld))) , flSelector = selName } } where fld_occ = rdrNameOcc fld - dc_fs = (occNameFS $ nameOccName dc) + dc_fs = occNameFS $ nameOccName dc field -- Use an Exact RdrName as-is, to preserve the bindings -- of an already renamer-resolved field and its use ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -465,9 +465,12 @@ varToRecFieldOcc dc (OccName ns s) = assert makes_sense $ mkRecFieldOccFS dc s where makes_sense = case ns of - VarName -> True - FldName con -> con == dc - _ -> False + VarName -> True + FldName {} -> True + -- NB: it's OK to change the parent data constructor, + -- see e.g. test T23220 in which we construct with TH + -- a datatype using the fields of a different datatype. + _ -> False recFieldToVarOcc :: HasDebugCallStack => OccName -> OccName recFieldToVarOcc (OccName _ns s) = mkVarOccFS s ===================================== testsuite/tests/overloadedrecflds/should_compile/T23220.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE TemplateHaskell #-} + +module T23220 where + +import Language.Haskell.TH + +import T23220_aux ( makeExtendingDatatype ) + +type Uri = String + +data TextDocumentIdentifier = + TextDocumentIdentifier + { _uri :: Uri + } + +type TextDocumentVersion = Maybe Int + +makeExtendingDatatype "VersionedTextDocumentIdentifier" [''TextDocumentIdentifier] + [ ("_version", [t| TextDocumentVersion |])] ===================================== testsuite/tests/overloadedrecflds/should_compile/T23220_aux.hs ===================================== @@ -0,0 +1,24 @@ +module T23220_aux ( makeExtendingDatatype ) where + +import Control.Monad ( forM ) +import Language.Haskell.TH + +-- | @makeExtendingDatatype name extends fields@ generates a record datatype +-- that contains all the fields of @extends@, plus the additional fields in +-- @fields at . +-- e.g. +-- data Foo = { a :: Int } +-- makeExtendingDatatype "bar" [''Foo] [("b", [t| String |])] +-- Will generate +-- data Bar = { a :: Int, b :: String } +makeExtendingDatatype :: String -> [Name] -> [(String, TypeQ)] -> DecsQ +makeExtendingDatatype datatypeNameStr extends fields = do + extendFields <- fmap concat $ forM extends $ \e -> do + TyConI (DataD _ _ _ _ [RecC _ eFields] _) <- reify e + return eFields + let datatypeName = mkName datatypeNameStr + constructor = recC datatypeName combinedFields + userFields = flip map fields $ \(s, typ) -> do + varBangType (mkName s) (bangType (bang noSourceUnpackedness noSourceStrictness) typ) + combinedFields = (map pure extendFields) <> userFields + (\a -> [a]) <$> dataD (cxt []) datatypeName [] Nothing [constructor] [] ===================================== testsuite/tests/overloadedrecflds/should_compile/all.T ===================================== @@ -47,3 +47,6 @@ test('BootFldReexport' # Should either pass or give an ambiguity error when compiling # the final module (BootFldReexport), but not fail earlier. , ['BootFldReexport', '-v0']) +test('T23220' + , [req_th, extra_files(['T23220_aux.hs'])] + , multimod_compile, ['T23220_aux.hs T23220.hs', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd00e321d5d7aaee3999b283a2a2f0d77f7b3e8e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd00e321d5d7aaee3999b283a2a2f0d77f7b3e8e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 08:09:46 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 04 Apr 2023 04:09:46 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 50 commits: ghc-the-library: Retain cafs in both static in dynamic builds. Message-ID: <642bdb4ac106d_11425f18f83a00287832@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 0f46d481 by Andreas Klebinger at 2023-04-04T13:39:24+05:30 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- (cherry picked from commit 08ba87200ff068aa37cac082e61ee7e2d534daf5) (cherry picked from commit 96ab827a0d1ffd81bd906262b42409f2df808375) - - - - - e7d033c1 by sheaf at 2023-04-04T13:39:24+05:30 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 (cherry picked from commit cf564dd71548771394249e9bf959512a21bbcec0) (cherry picked from commit c17668466a404de8a7fc5ef5b2931790da9440b6) - - - - - f9b39b7b by Simon Peyton Jones at 2023-04-04T13:39:24+05:30 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 (cherry picked from commit 3d55d8ab51ece43c51055c43c9e7aba77cce46c0) - - - - - 3732f703 by Simon Peyton Jones at 2023-04-04T13:39:24+05:30 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. (cherry picked from commit e193e53790dd5886feea3cf4c9c17625d188291b) - - - - - 2c95c996 by Simon Peyton Jones at 2023-04-04T13:39:25+05:30 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 (cherry picked from commit 317f45c154f6fe25d50ef2f3febcc5883ff1b1ca) - - - - - 31ea50f1 by Andreas Klebinger at 2023-04-04T13:39:25+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 69853dad by Matthew Pickering at 2023-04-04T13:39:25+05:30 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s (cherry picked from commit a960ca817d6ad0109ea6edda50da3902cc538e86) - - - - - 55a4b92a by Matthew Pickering at 2023-04-04T13:39:25+05:30 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. (cherry picked from commit 734847108420cf826a807c30ad54651659cf3a08) - - - - - dd30d299 by Matthew Pickering at 2023-04-04T13:39:25+05:30 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes (cherry picked from commit 8c0ea25fb4a27d4729aabf73f4c00b912bb0c58d) - - - - - d13736f4 by Sebastian Graf at 2023-04-04T13:39:25+05:30 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite (cherry picked from commit e3fff7512bbf989386faaa1dccafdad1deabde84) - - - - - b74c99fd by Oleg Grenrus at 2023-04-04T13:39:25+05:30 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general (cherry picked from commit 1b812b6973a25cb1962e2fc543d2c4ed3cf31f3c) - - - - - 55ddff3c by Viktor Dukhovni at 2023-04-04T13:39:25+05:30 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 (cherry picked from commit fc02f3bbb5f47f880465e22999ba9794f658d8f6) - - - - - 1a4cd8a7 by Ryan Scott at 2023-04-04T13:39:25+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - 1868ee43 by Cheng Shao at 2023-04-04T13:39:25+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - 71831a1d by Ben Gamari at 2023-04-04T13:39:25+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - addb2166 by Ben Gamari at 2023-04-04T13:39:25+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - c6a0e980 by Ben Gamari at 2023-04-04T13:39:25+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - 8e864571 by Ben Gamari at 2023-04-04T13:39:25+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - 71c2010c by Zubin Duggal at 2023-04-04T13:39:25+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 0a4a9ac0 by Ben Gamari at 2023-04-04T13:39:25+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - f1cc92f6 by Zubin Duggal at 2023-04-04T13:39:25+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - eaee6f2b by Ben Gamari at 2023-04-04T13:39:25+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - 54958a9b by sheaf at 2023-04-04T13:39:25+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - bd6cf496 by Ben Gamari at 2023-04-04T13:39:25+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - daec09a3 by Ben Gamari at 2023-04-04T13:39:26+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - adc2211f by Ben Gamari at 2023-04-04T13:39:26+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - c13ca8e5 by Ben Gamari at 2023-04-04T13:39:26+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 5ff4f609 by Ben Gamari at 2023-04-04T13:39:26+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - 876ddef6 by Ben Gamari at 2023-04-04T13:39:26+05:30 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. (cherry picked from commit 79ffa170a6b0b152da0e02744869311773733286) - - - - - a15ad2c3 by Andreas Klebinger at 2023-04-04T13:39:26+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - 29abe542 by Matthew Pickering at 2023-04-04T13:39:26+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - eba5c232 by Sylvain Henry at 2023-04-04T13:39:26+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - 13e81e88 by Ben Gamari at 2023-04-04T13:39:26+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - b0ed6eeb by Matthew Pickering at 2023-04-04T13:39:26+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - 96d24e37 by Matthew Pickering at 2023-04-04T13:39:26+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - cef9fb46 by Matthew Pickering at 2023-04-04T13:39:26+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - f7d031ec by Matthew Pickering at 2023-04-04T13:39:26+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - 7b77e584 by Matthew Pickering at 2023-04-04T13:39:26+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 6c63fa60 by Matthew Pickering at 2023-04-04T13:39:26+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - bd0fed4d by Matthew Pickering at 2023-04-04T13:39:26+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - e17871f3 by Matthew Pickering at 2023-04-04T13:39:26+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - bef8783a by Matthew Pickering at 2023-04-04T13:39:26+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - a4411525 by Matthew Pickering at 2023-04-04T13:39:26+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 6395a242 by Matthew Pickering at 2023-04-04T13:39:27+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 31de03d4 by Matthew Pickering at 2023-04-04T13:39:27+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 10f2997d by Matthew Pickering at 2023-04-04T13:39:27+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 87401100 by Matthew Pickering at 2023-04-04T13:39:27+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - c9597ccc by Matthew Pickering at 2023-04-04T13:39:27+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 74d77900 by Matthew Pickering at 2023-04-04T13:39:27+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 5eea437e by Simon Peyton Jones at 2023-04-04T13:39:27+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Solver/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/ThToHs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4b4a34a758349e569e1dc1775967e7ef32e7fff9...5eea437e1b20e294a6e7a8267a1c968ac59053aa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4b4a34a758349e569e1dc1775967e7ef32e7fff9...5eea437e1b20e294a6e7a8267a1c968ac59053aa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 09:18:09 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 04 Apr 2023 05:18:09 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] 100 commits: Fix BCO creation setting caps when -j > -N Message-ID: <642beb51bc57d_11425f1a605170298175@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - 75ea4767 by Josh Meredith at 2023-04-04T09:17:47+00:00 JS: fix bounds checking - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/SimpleOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe03d242c8d35f59e4d9bb29000a065fbb0b96fd...75ea47677062c7d6cec1919555cce18c10ce3245 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe03d242c8d35f59e4d9bb29000a065fbb0b96fd...75ea47677062c7d6cec1919555cce18c10ce3245 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 09:45:32 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 04 Apr 2023 05:45:32 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 8 commits: Hardwire a better unit-id for ghc Message-ID: <642bf1bc290c6_11425f1adc4f143043bc@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: b8123b2c by romes at 2023-04-03T10:20:02+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - f939dfc1 by romes at 2023-04-03T10:20:02+01:00 Validate compatibility of ghcs when loading plugins - - - - - c9b48a23 by romes at 2023-04-03T10:20:02+01:00 Add hashes to unit-ids created by hadrian Co-author: @mpickering - - - - - 6e7abf19 by GHC GitLab CI at 2023-04-03T10:20:02+01:00 Fix sed command in install makefile - - - - - 13824cd5 by Matthew Pickering at 2023-04-03T17:14:10+01:00 fixes - - - - - 104c2b4c by Matthew Pickering at 2023-04-03T17:31:17+01:00 add flag - - - - - 5d179c5d by Matthew Pickering at 2023-04-03T17:33:33+01:00 Use hash-unit-ids in release jobs - - - - - 8efe61f3 by Matthew Pickering at 2023-04-04T10:38:52+01:00 Fix passing opts to toolargs - - - - - 30 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Driver/Session.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Unit/Types.hs - compiler/Setup.hs - compiler/ghc.cabal.in - hadrian/bindist/Makefile - hadrian/hadrian.cabal - hadrian/src/CommandLine.hs - hadrian/src/Context.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/BuildPath.hs - hadrian/src/Hadrian/Builder/Git.hs - hadrian/src/Hadrian/Haskell/Cabal.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - + hadrian/src/Hadrian/Haskell/Hash.hs - + hadrian/src/Hadrian/Haskell/Hash.hs-boot - hadrian/src/Hadrian/Package.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Library.hs - hadrian/src/Rules/Register.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Ghc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ab30288e9fc996c8ef4add845e77aaa14fbe4ed...8efe61f3714e20bc32cefdd5f69a74c28220a441 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ab30288e9fc996c8ef4add845e77aaa14fbe4ed...8efe61f3714e20bc32cefdd5f69a74c28220a441 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 10:03:59 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 04 Apr 2023 06:03:59 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 5 commits: hadrian: Flavour: Change args -> extraArgs Message-ID: <642bf60f7e601_11425f1b61b71c312691@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: d079f75a by Matthew Pickering at 2023-04-04T10:56:15+01:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 3debbf79 by romes at 2023-04-04T10:56:15+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 07513a25 by romes at 2023-04-04T10:56:15+01:00 Validate compatibility of ghcs when loading plugins - - - - - eb5fb7f9 by romes at 2023-04-04T11:03:35+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 157c46d6 by Matthew Pickering at 2023-04-04T11:03:35+01:00 Use hash-unit-ids in release jobs - - - - - 30 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Driver/Session.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Unit/Types.hs - compiler/Setup.hs - compiler/ghc.cabal.in - hadrian/bindist/Makefile - hadrian/hadrian.cabal - hadrian/src/CommandLine.hs - hadrian/src/Context.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/BuildPath.hs - hadrian/src/Hadrian/Builder/Git.hs - hadrian/src/Hadrian/Haskell/Cabal.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - + hadrian/src/Hadrian/Haskell/Hash.hs - + hadrian/src/Hadrian/Haskell/Hash.hs-boot - hadrian/src/Hadrian/Package.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Library.hs - hadrian/src/Rules/Register.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Ghc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8efe61f3714e20bc32cefdd5f69a74c28220a441...157c46d6f551b33d8c3b511fe078d76aab7e8830 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8efe61f3714e20bc32cefdd5f69a74c28220a441...157c46d6f551b33d8c3b511fe078d76aab7e8830 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 10:47:12 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 04 Apr 2023 06:47:12 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 15 commits: Rework documentation for data Char Message-ID: <642c0030ca45b_11425f1be9d2a031585a@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - 3d182660 by Simon Peyton Jones at 2023-04-04T11:48:49+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 0418bd89 by Simon Peyton Jones at 2023-04-04T11:48:49+01:00 Add some documentation about redundant constraints - - - - - abcbfe52 by Simon Peyton Jones at 2023-04-04T11:48:49+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever #23223: misleading error with partial type signatuers See the long notes: * Note [ApproximateWC] in GHC.Tc.Solver * Note [Partial type signatures and the MR] in GHC.Tc.Gen.Bind All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. The test #19106 becomes an error again, but with a better error message; it's a very subtle case, conjured out of Richard's brain. - - - - - 25 changed files: - .gitlab-ci.yml - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d82250e8ab66107ed004878948a09f1f7b960472...abcbfe522b68f0fe17092818472162794bf22605 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d82250e8ab66107ed004878948a09f1f7b960472...abcbfe522b68f0fe17092818472162794bf22605 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 12:39:13 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 08:39:13 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add a few more memcpy-ish primops Message-ID: <642c1a7194b62_11425f1e2d305c357941@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - bd04461e by Sylvain Henry at 2023-04-04T08:39:04-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 6a36e70a by Ryan Scott at 2023-04-04T08:39:05-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Name/Occurrence.hs - libraries/base/Data/Array/Byte.hs - libraries/base/Foreign/Marshal/Utils.hs - libraries/ghc-prim/changelog.md - libraries/ghci/GHCi/RemoteTypes.hs - rts/RtsMessages.c - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray2.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsCompareByteArray3.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadInt64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadSmallArray.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord64Array.hs - + testsuite/tests/codeGen/should_fail/CheckBoundsReadWord8ArrayAsWord32.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyAddrToByteArray.hs - + testsuite/tests/codeGen/should_fail/CheckOverlapCopyByteArray.hs - testsuite/tests/codeGen/should_fail/all.T - + testsuite/tests/codeGen/should_run/CheckBoundsOK.hs - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/overloadedrecflds/should_compile/T23220.hs - + testsuite/tests/overloadedrecflds/should_compile/T23220_aux.hs - testsuite/tests/overloadedrecflds/should_compile/all.T - + testsuite/tests/th/T23203.hs - + testsuite/tests/th/T23203.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/74a983783cab24435658a1da81b19e85f41baa10...6a36e70a9b05e9e884351b327a3d9fae79744d57 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/74a983783cab24435658a1da81b19e85f41baa10...6a36e70a9b05e9e884351b327a3d9fae79744d57 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 15:09:29 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 11:09:29 -0400 Subject: [Git][ghc/ghc][master] GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) Message-ID: <642c3da9bd2a2_3b005521029241401fc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 2 changed files: - compiler/GHC/Runtime/Interpreter.hs - libraries/ghci/GHCi/RemoteTypes.hs Changes: ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -690,17 +690,15 @@ principle it would probably be ok, but it seems less hairy this way. -- 'RemoteRef' when it is no longer referenced. mkFinalizedHValue :: Interp -> RemoteRef a -> IO (ForeignRef a) mkFinalizedHValue interp rref = do - let hvref = toHValueRef rref - free <- case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> return (freeRemoteRef hvref) + InternalInterp -> return (freeRemoteRef rref) #endif ExternalInterp _ (IServ i) -> return $ modifyMVar_ i $ \state -> case state of IServPending {} -> pure state -- already shut down IServRunning inst -> do - let !inst' = inst {iservPendingFrees = hvref:iservPendingFrees inst} + let !inst' = inst {iservPendingFrees = castRemoteRef rref : iservPendingFrees inst} pure (IServRunning inst') mkForeignRef rref free ===================================== libraries/ghci/GHCi/RemoteTypes.hs ===================================== @@ -8,14 +8,29 @@ -- compiler/GHC/Runtime/Interpreter.hs. -- module GHCi.RemoteTypes - ( RemotePtr(..), toRemotePtr, fromRemotePtr, castRemotePtr + ( -- * Remote pointer + RemotePtr(..) + , toRemotePtr + , fromRemotePtr + , castRemotePtr + -- * RemoteRef: reference to some heap object (potentially remote) + , RemoteRef (..) + , mkRemoteRef + , localRef + , freeRemoteRef + , castRemoteRef + -- * ForeignRef: RemoteRef with a finalizer + , ForeignRef + , mkForeignRef + , withForeignRef + , finalizeForeignRef + , castForeignRef + , unsafeForeignRefToRemoteRef + -- * HValue , HValue(..) - , RemoteRef, mkRemoteRef, localRef, freeRemoteRef - , HValueRef, toHValueRef - , ForeignRef, mkForeignRef, withForeignRef + , HValueRef , ForeignHValue - , unsafeForeignRefToRemoteRef, finalizeForeignRef - ) where +) where import Prelude -- See note [Why do we import Prelude here?] import Control.DeepSeq @@ -23,7 +38,6 @@ import Data.Word import Foreign hiding (newForeignPtr) import Foreign.Concurrent import Data.Binary -import Unsafe.Coerce import GHC.Exts import GHC.ForeignPtr @@ -52,23 +66,28 @@ deriving instance Binary (RemotePtr a) deriving instance NFData (RemotePtr a) -- ----------------------------------------------------------------------------- --- HValueRef +-- HValue: alias for Any newtype HValue = HValue Any instance Show HValue where show _ = "" --- | A reference to a remote value. These are allocated and freed explicitly. +-- For convenience +type HValueRef = RemoteRef HValue +type ForeignHValue = ForeignRef HValue + +-- ----------------------------------------------------------------------------- +-- RemoteRef: pointer to a Heap object + +-- | A reference to a heap object. Potentially in a remote heap! +-- These are allocated and freed explicitly. newtype RemoteRef a = RemoteRef (RemotePtr ()) deriving (Show, Binary) -- We can discard type information if we want -toHValueRef :: RemoteRef a -> RemoteRef HValue -toHValueRef = unsafeCoerce - --- For convenience -type HValueRef = RemoteRef HValue +castRemoteRef :: RemoteRef a -> RemoteRef b +castRemoteRef = coerce -- | Make a reference to a local value that we can send remotely. -- This reference will keep the value that it refers to alive until @@ -78,34 +97,33 @@ mkRemoteRef a = do sp <- newStablePtr a return $! RemoteRef (toRemotePtr (castStablePtrToPtr sp)) --- | Convert an HValueRef to an HValue. Should only be used if the HValue --- originated in this process. +-- | Convert a RemoteRef to its carried type. Should only be used if the +-- RemoteRef originated in this process. localRef :: RemoteRef a -> IO a localRef (RemoteRef w) = deRefStablePtr (castPtrToStablePtr (fromRemotePtr w)) --- | Release an HValueRef that originated in this process +-- | Release a RemoteRef that originated in this process freeRemoteRef :: RemoteRef a -> IO () freeRemoteRef (RemoteRef w) = freeStablePtr (castPtrToStablePtr (fromRemotePtr w)) --- | An HValueRef with a finalizer +-- | An RemoteRef with a finalizer newtype ForeignRef a = ForeignRef (ForeignPtr ()) instance NFData (ForeignRef a) where rnf x = x `seq` () -type ForeignHValue = ForeignRef HValue -- | Create a 'ForeignRef' from a 'RemoteRef'. The finalizer --- should arrange to call 'freeHValueRef' on the 'HValueRef'. (since +-- should arrange to call 'freeRemoteRef' on the 'RemoteRef'. (since -- this function needs to be called in the process that created the --- 'HValueRef', it cannot be called directly from the finalizer). +-- 'RemoteRef', it cannot be called directly from the finalizer). mkForeignRef :: RemoteRef a -> IO () -> IO (ForeignRef a) mkForeignRef (RemoteRef hvref) finalizer = ForeignRef <$> newForeignPtr (fromRemotePtr hvref) finalizer --- | Use a 'ForeignHValue' +-- | Use a 'ForeignRef' withForeignRef :: ForeignRef a -> (RemoteRef a -> IO b) -> IO b withForeignRef (ForeignRef fp) f = withForeignPtr fp (f . RemoteRef . toRemotePtr) @@ -116,3 +134,6 @@ unsafeForeignRefToRemoteRef (ForeignRef fp) = finalizeForeignRef :: ForeignRef a -> IO () finalizeForeignRef (ForeignRef fp) = finalizeForeignPtr fp + +castForeignRef :: ForeignRef a -> ForeignRef b +castForeignRef = coerce View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eed0d9307b3f48b6a2e45dbb246610cf4ab73896 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eed0d9307b3f48b6a2e45dbb246610cf4ab73896 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 15:10:11 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 11:10:11 -0400 Subject: [Git][ghc/ghc][master] Make INLINE pragmas for pattern synonyms work with TH Message-ID: <642c3dd312788_3b00551f05054145213@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 4 changed files: - compiler/GHC/ThToHs.hs - + testsuite/tests/th/T23203.hs - + testsuite/tests/th/T23203.stderr - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -851,7 +851,10 @@ cvt_conv TH.JavaScript = JavaScriptCallConv cvtPragmaD :: Pragma -> CvtM (Maybe (LHsDecl GhcPs)) cvtPragmaD (InlineP nm inline rm phases) - = do { nm' <- vNameN nm + = do { -- NB: Use vcNameN here, which works for both the variable namespace + -- (e.g., `INLINE`d functions) and the constructor namespace + -- (e.g., `INLINE`d pattern synonyms, cf. #23203) + nm' <- vcNameN nm ; let dflt = dfltActivation inline ; let src TH.NoInline = "{-# NOINLINE" src TH.Inline = "{-# INLINE" ===================================== testsuite/tests/th/T23203.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TemplateHaskell #-} +module T23203 where + +import Language.Haskell.TH + +data D = MkD Int + +$(do let -- The original example from #23203 + genPat1 :: Q [Dec] + genPat1 = sequence [ + patSynD name (prefixPatSyn []) unidir wildP + , pure $ PragmaD $ InlineP name Inline FunLike AllPhases + ] + where name = mkName "A" + + -- A slightly more complicated example that also puts an INLINE pragma + -- on a field name in a record pattern synonym + genPat2 :: Q [Dec] + genPat2 = sequence [ + patSynD con_name (recordPatSyn [fld_name]) implBidir (conP 'MkD [varP fld_name]) + , pure $ PragmaD $ InlineP con_name Inline FunLike AllPhases + , pure $ PragmaD $ InlineP fld_name Inline FunLike AllPhases + ] + where con_name = mkName "P" + fld_name = mkName "fld" + + decs1 <- genPat1 + decs2 <- genPat2 + pure (decs1 ++ decs2)) ===================================== testsuite/tests/th/T23203.stderr ===================================== @@ -0,0 +1,28 @@ +T23203.hs:(9,2)-(30,27): Splicing declarations + do let genPat1 :: Q [Dec] + genPat1 + = sequence + [patSynD name (prefixPatSyn []) unidir wildP, + pure $ PragmaD $ InlineP name Inline FunLike AllPhases] + where + name = mkName "A" + genPat2 :: Q [Dec] + genPat2 + = sequence + [patSynD + con_name (recordPatSyn [fld_name]) implBidir + (conP 'MkD [varP fld_name]), + pure $ PragmaD $ InlineP con_name Inline FunLike AllPhases, + pure $ PragmaD $ InlineP fld_name Inline FunLike AllPhases] + where + con_name = mkName "P" + fld_name = mkName "fld" + decs1 <- genPat1 + decs2 <- genPat2 + pure (decs1 ++ decs2) + ======> + pattern A <- _ + {-# INLINE A #-} + pattern P{fld} = MkD fld + {-# INLINE P #-} + {-# INLINE fld #-} ===================================== testsuite/tests/th/all.T ===================================== @@ -558,3 +558,4 @@ test('T22818', normal, compile, ['-v0']) test('T22819', normal, compile, ['-v0']) test('TH_fun_par', normal, compile, ['']) test('T23036', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('T23203', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/071139c30ab95e6a292bec8ae0dcb6bf2be6308d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/071139c30ab95e6a292bec8ae0dcb6bf2be6308d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 15:47:31 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 04 Apr 2023 11:47:31 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 5 commits: hadrian: Flavour: Change args -> extraArgs Message-ID: <642c4693b3f62_3b0055302e7b8176615@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 1ebb754e by Matthew Pickering at 2023-04-04T16:45:14+01:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - a4423c78 by romes at 2023-04-04T16:45:14+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 3bed72a4 by romes at 2023-04-04T16:45:14+01:00 Validate compatibility of ghcs when loading plugins - - - - - 72d55ded by romes at 2023-04-04T16:45:14+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 53181517 by Matthew Pickering at 2023-04-04T16:45:14+01:00 Use hash-unit-ids in release jobs - - - - - 30 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Driver/Session.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Unit/Types.hs - compiler/Setup.hs - compiler/ghc.cabal.in - hadrian/bindist/Makefile - hadrian/hadrian.cabal - hadrian/src/CommandLine.hs - hadrian/src/Context.hs - hadrian/src/Flavour.hs - hadrian/src/Flavour/Type.hs - hadrian/src/Hadrian/BuildPath.hs - hadrian/src/Hadrian/Builder/Git.hs - hadrian/src/Hadrian/Haskell/Cabal.hs - hadrian/src/Hadrian/Haskell/Cabal/Parse.hs - + hadrian/src/Hadrian/Haskell/Hash.hs - + hadrian/src/Hadrian/Haskell/Hash.hs-boot - hadrian/src/Hadrian/Package.hs - hadrian/src/Rules.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Rules/Library.hs - hadrian/src/Rules/Register.hs - hadrian/src/Settings.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Builders/Ghc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/157c46d6f551b33d8c3b511fe078d76aab7e8830...5318151708e61a8bcaa26ff8f01ee54bb734a40b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/157c46d6f551b33d8c3b511fe078d76aab7e8830...5318151708e61a8bcaa26ff8f01ee54bb734a40b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 16:27:59 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 04 Apr 2023 12:27:59 -0400 Subject: [Git][ghc/ghc][wip/T23170] 72 commits: Optimized Foldable methods for Data.Functor.Compose Message-ID: <642c500feac40_3b00553aefe9018665c@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23170 at Glasgow Haskell Compiler / GHC Commits: 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 9d7596d0 by Ben Gamari at 2023-04-04T18:26:48+02:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/TyCon/Env.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/FastString/Env.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Flags.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3c8bb7a904660ab97f3d09c38077d89be472301...9d7596d0413a12748232a6ef69d5cbad2260746b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3c8bb7a904660ab97f3d09c38077d89be472301...9d7596d0413a12748232a6ef69d5cbad2260746b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 18:43:04 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 14:43:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) Message-ID: <642c6fb829c8e_3b005563557182055f7@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - f3f1223b by Krzysztof Gogolewski at 2023-04-04T14:42:50-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - 56c9caee by sheaf at 2023-04-04T14:42:55-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - 12 changed files: - compiler/GHC/Core/Unify.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/ThToHs.hs - libraries/ghci/GHCi/RemoteTypes.hs - + testsuite/tests/simplCore/should_run/T23134.hs - + testsuite/tests/simplCore/should_run/T23134.stdout - testsuite/tests/simplCore/should_run/all.T - + testsuite/tests/th/T23203.hs - + testsuite/tests/th/T23203.stderr - testsuite/tests/th/all.T - + testsuite/tests/typecheck/should_compile/T23192.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -1,6 +1,6 @@ -- (c) The University of Glasgow 2006 -{-# LANGUAGE ScopedTypeVariables, PatternSynonyms #-} +{-# LANGUAGE ScopedTypeVariables, PatternSynonyms, MultiWayIf #-} {-# LANGUAGE DeriveFunctor #-} @@ -47,6 +47,7 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set import GHC.Exts( oneShot ) +import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Data.FastString @@ -994,6 +995,59 @@ These two TyConApps have the same TyCon at the front but they (legitimately) have different numbers of arguments. They are surelyApart, so we can report that without looking any further (see #15704). + +Note [Unifying type applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Unifying type applications is quite subtle, as we found +in #23134 and #22647, when type families are involved. + +Suppose + type family F a :: Type -> Type + type family G k :: k = r | r -> k + +and consider these examples: + +* F Int ~ F Char, where F is injective + Since F is injective, we can reduce this to Int ~ Char, + therefore SurelyApart. + +* F Int ~ F Char, where F is not injective + Without injectivity, return MaybeApart. + +* G Type ~ G (Type -> Type) Int + Even though G is injective and the arguments to G are different, + we cannot deduce apartness because the RHS is oversaturated. + For example, G might be defined as + G Type = Maybe Int + G (Type -> Type) = Maybe + So we return MaybeApart. + +* F Int Bool ~ F Int Char -- SurelyApart (since Bool is apart from Char) + F Int Bool ~ Maybe a -- MaybeApart + F Int Bool ~ a b -- MaybeApart + F Int Bool ~ Char -> Bool -- MaybeApart + An oversaturated type family can match an application, + whether it's a TyConApp, AppTy or FunTy. Decompose. + +* F Int ~ a b + We cannot decompose a saturated, or under-saturated + type family application. We return MaybeApart. + +To handle all those conditions, unify_ty goes through +the following checks in sequence, where Fn is a type family +of arity n: + +* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n + A saturated application. + Here we can unify arguments in which Fn is injective. +* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n + A saturated type family can match anything - we return MaybeApart. +* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n + An oversaturated type family can be decomposed. +* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n + If we couldn't decompose in the previous step, we return SurelyApart. + +Afterwards, the rest of the code doesn't have to worry about type families. -} -------------- unify_ty: the main workhorse ----------- @@ -1035,31 +1089,63 @@ unify_ty env ty1 (TyVarTy tv2) kco = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco) unify_ty env ty1 ty2 _kco + + -- Handle non-oversaturated type families first + -- See Note [Unifying type applications] + -- + -- (C1) If we have T x1 ... xn ~ T y1 ... yn, use injectivity information of T + -- Note that both sides must not be oversaturated + | Just (tc1, tys1) <- isSatTyFamApp mb_tc_app1 + , Just (tc2, tys2) <- isSatTyFamApp mb_tc_app2 + , tc1 == tc2 + = do { let inj = case tyConInjectivityInfo tc1 of + NotInjective -> repeat False + Injective bs -> bs + + (inj_tys1, noninj_tys1) = partitionByList inj tys1 + (inj_tys2, noninj_tys2) = partitionByList inj tys2 + + ; unify_tys env inj_tys1 inj_tys2 + ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] + don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } + + | Just _ <- isSatTyFamApp mb_tc_app1 -- (C2) A (not-over-saturated) type-family application + = maybeApart MARTypeFamily -- behaves like a type variable; might match + + | Just _ <- isSatTyFamApp mb_tc_app2 -- (C2) A (not-over-saturated) type-family application + -- behaves like a type variable; might unify + -- but doesn't match (as in the TyVarTy case) + = if um_unif env then maybeApart MARTypeFamily else surelyApart + + -- Handle oversaturated type families. + -- + -- They can match an application (TyConApp/FunTy/AppTy), this is handled + -- the same way as in the AppTy case below. + -- + -- If there is no application, an oversaturated type family can only + -- match a type variable or a saturated type family, + -- both of which we handled earlier. So we can say surelyApart. + | Just (tc1, _) <- mb_tc_app1 + , isTypeFamilyTyCon tc1 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + | Just (tc2, _) <- mb_tc_app2 + , isTypeFamilyTyCon tc2 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + -- At this point, neither tc1 nor tc2 can be a type family. | Just (tc1, tys1) <- mb_tc_app1 , Just (tc2, tys2) <- mb_tc_app2 , tc1 == tc2 - = if isInjectiveTyCon tc1 Nominal - then unify_tys env tys1 tys2 - else do { let inj | isTypeFamilyTyCon tc1 - = case tyConInjectivityInfo tc1 of - NotInjective -> repeat False - Injective bs -> bs - | otherwise - = repeat False - - (inj_tys1, noninj_tys1) = partitionByList inj tys1 - (inj_tys2, noninj_tys2) = partitionByList inj tys2 - - ; unify_tys env inj_tys1 inj_tys2 - ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] - don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } - - | isTyFamApp mb_tc_app1 -- A (not-over-saturated) type-family application - = maybeApart MARTypeFamily -- behaves like a type variable; might match - - | isTyFamApp mb_tc_app2 -- A (not-over-saturated) type-family application - , um_unif env -- behaves like a type variable; might unify - = maybeApart MARTypeFamily + = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1) + ; unify_tys env tys1 tys2 + } -- TYPE and CONSTRAINT are not Apart -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim @@ -1160,16 +1246,16 @@ unify_tys env orig_xs orig_ys -- Possibly different saturations of a polykinded tycon -- See Note [Polykinded tycon applications] -isTyFamApp :: Maybe (TyCon, [Type]) -> Bool --- True if we have a saturated or under-saturated type family application +isSatTyFamApp :: Maybe (TyCon, [Type]) -> Maybe (TyCon, [Type]) +-- Return the argument if we have a saturated type family application -- If it is /over/ saturated then we return False. E.g. -- unify_ty (F a b) (c d) where F has arity 1 -- we definitely want to decompose that type application! (#22647) -isTyFamApp (Just (tc, tys)) - = not (isGenerativeTyCon tc Nominal) -- Type family-ish +isSatTyFamApp tapp@(Just (tc, tys)) + | isTypeFamilyTyCon tc && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated -isTyFamApp Nothing - = False + = tapp +isSatTyFamApp _ = Nothing --------------------------------- uVar :: UMEnv ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -690,17 +690,15 @@ principle it would probably be ok, but it seems less hairy this way. -- 'RemoteRef' when it is no longer referenced. mkFinalizedHValue :: Interp -> RemoteRef a -> IO (ForeignRef a) mkFinalizedHValue interp rref = do - let hvref = toHValueRef rref - free <- case interpInstance interp of #if defined(HAVE_INTERNAL_INTERPRETER) - InternalInterp -> return (freeRemoteRef hvref) + InternalInterp -> return (freeRemoteRef rref) #endif ExternalInterp _ (IServ i) -> return $ modifyMVar_ i $ \state -> case state of IServPending {} -> pure state -- already shut down IServRunning inst -> do - let !inst' = inst {iservPendingFrees = hvref:iservPendingFrees inst} + let !inst' = inst {iservPendingFrees = castRemoteRef rref : iservPendingFrees inst} pure (IServRunning inst') mkForeignRef rref free ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -851,7 +851,10 @@ cvt_conv TH.JavaScript = JavaScriptCallConv cvtPragmaD :: Pragma -> CvtM (Maybe (LHsDecl GhcPs)) cvtPragmaD (InlineP nm inline rm phases) - = do { nm' <- vNameN nm + = do { -- NB: Use vcNameN here, which works for both the variable namespace + -- (e.g., `INLINE`d functions) and the constructor namespace + -- (e.g., `INLINE`d pattern synonyms, cf. #23203) + nm' <- vcNameN nm ; let dflt = dfltActivation inline ; let src TH.NoInline = "{-# NOINLINE" src TH.Inline = "{-# INLINE" ===================================== libraries/ghci/GHCi/RemoteTypes.hs ===================================== @@ -8,14 +8,29 @@ -- compiler/GHC/Runtime/Interpreter.hs. -- module GHCi.RemoteTypes - ( RemotePtr(..), toRemotePtr, fromRemotePtr, castRemotePtr + ( -- * Remote pointer + RemotePtr(..) + , toRemotePtr + , fromRemotePtr + , castRemotePtr + -- * RemoteRef: reference to some heap object (potentially remote) + , RemoteRef (..) + , mkRemoteRef + , localRef + , freeRemoteRef + , castRemoteRef + -- * ForeignRef: RemoteRef with a finalizer + , ForeignRef + , mkForeignRef + , withForeignRef + , finalizeForeignRef + , castForeignRef + , unsafeForeignRefToRemoteRef + -- * HValue , HValue(..) - , RemoteRef, mkRemoteRef, localRef, freeRemoteRef - , HValueRef, toHValueRef - , ForeignRef, mkForeignRef, withForeignRef + , HValueRef , ForeignHValue - , unsafeForeignRefToRemoteRef, finalizeForeignRef - ) where +) where import Prelude -- See note [Why do we import Prelude here?] import Control.DeepSeq @@ -23,7 +38,6 @@ import Data.Word import Foreign hiding (newForeignPtr) import Foreign.Concurrent import Data.Binary -import Unsafe.Coerce import GHC.Exts import GHC.ForeignPtr @@ -52,23 +66,28 @@ deriving instance Binary (RemotePtr a) deriving instance NFData (RemotePtr a) -- ----------------------------------------------------------------------------- --- HValueRef +-- HValue: alias for Any newtype HValue = HValue Any instance Show HValue where show _ = "" --- | A reference to a remote value. These are allocated and freed explicitly. +-- For convenience +type HValueRef = RemoteRef HValue +type ForeignHValue = ForeignRef HValue + +-- ----------------------------------------------------------------------------- +-- RemoteRef: pointer to a Heap object + +-- | A reference to a heap object. Potentially in a remote heap! +-- These are allocated and freed explicitly. newtype RemoteRef a = RemoteRef (RemotePtr ()) deriving (Show, Binary) -- We can discard type information if we want -toHValueRef :: RemoteRef a -> RemoteRef HValue -toHValueRef = unsafeCoerce - --- For convenience -type HValueRef = RemoteRef HValue +castRemoteRef :: RemoteRef a -> RemoteRef b +castRemoteRef = coerce -- | Make a reference to a local value that we can send remotely. -- This reference will keep the value that it refers to alive until @@ -78,34 +97,33 @@ mkRemoteRef a = do sp <- newStablePtr a return $! RemoteRef (toRemotePtr (castStablePtrToPtr sp)) --- | Convert an HValueRef to an HValue. Should only be used if the HValue --- originated in this process. +-- | Convert a RemoteRef to its carried type. Should only be used if the +-- RemoteRef originated in this process. localRef :: RemoteRef a -> IO a localRef (RemoteRef w) = deRefStablePtr (castPtrToStablePtr (fromRemotePtr w)) --- | Release an HValueRef that originated in this process +-- | Release a RemoteRef that originated in this process freeRemoteRef :: RemoteRef a -> IO () freeRemoteRef (RemoteRef w) = freeStablePtr (castPtrToStablePtr (fromRemotePtr w)) --- | An HValueRef with a finalizer +-- | An RemoteRef with a finalizer newtype ForeignRef a = ForeignRef (ForeignPtr ()) instance NFData (ForeignRef a) where rnf x = x `seq` () -type ForeignHValue = ForeignRef HValue -- | Create a 'ForeignRef' from a 'RemoteRef'. The finalizer --- should arrange to call 'freeHValueRef' on the 'HValueRef'. (since +-- should arrange to call 'freeRemoteRef' on the 'RemoteRef'. (since -- this function needs to be called in the process that created the --- 'HValueRef', it cannot be called directly from the finalizer). +-- 'RemoteRef', it cannot be called directly from the finalizer). mkForeignRef :: RemoteRef a -> IO () -> IO (ForeignRef a) mkForeignRef (RemoteRef hvref) finalizer = ForeignRef <$> newForeignPtr (fromRemotePtr hvref) finalizer --- | Use a 'ForeignHValue' +-- | Use a 'ForeignRef' withForeignRef :: ForeignRef a -> (RemoteRef a -> IO b) -> IO b withForeignRef (ForeignRef fp) f = withForeignPtr fp (f . RemoteRef . toRemotePtr) @@ -116,3 +134,6 @@ unsafeForeignRefToRemoteRef (ForeignRef fp) = finalizeForeignRef :: ForeignRef a -> IO () finalizeForeignRef (ForeignRef fp) = finalizeForeignPtr fp + +castForeignRef :: ForeignRef a -> ForeignRef b +castForeignRef = coerce ===================================== testsuite/tests/simplCore/should_run/T23134.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE GHC2021, DataKinds, TypeFamilies #-} +module Main where + +import Data.Maybe +import Data.Kind + +main :: IO () +main = putStrLn str + +str :: String +str = case runInstrImpl @(TOption TUnit) mm MAP of + C VOption -> "good" + C Unused -> "bad" + +runInstrImpl :: forall inp out. Value (MapOpRes inp TUnit) -> Instr inp out -> Rec out +runInstrImpl m MAP = C m + +type MapOpRes :: T -> T -> T +type family MapOpRes c :: T -> T +type instance MapOpRes ('TOption x) = 'TOption + +mm :: Value (TOption TUnit) +mm = VOption +{-# NOINLINE mm #-} + +type Value :: T -> Type +data Value t where + VOption :: Value ('TOption t) + Unused :: Value t + +data T = TOption T | TUnit + +data Instr (inp :: T) (out :: T) where + MAP :: Instr c (TOption (MapOpRes c TUnit)) + +data Rec :: T -> Type where + C :: Value r -> Rec (TOption r) ===================================== testsuite/tests/simplCore/should_run/T23134.stdout ===================================== @@ -0,0 +1 @@ +good ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -110,4 +110,4 @@ test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #208 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) - +test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) ===================================== testsuite/tests/th/T23203.hs ===================================== @@ -0,0 +1,30 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TemplateHaskell #-} +module T23203 where + +import Language.Haskell.TH + +data D = MkD Int + +$(do let -- The original example from #23203 + genPat1 :: Q [Dec] + genPat1 = sequence [ + patSynD name (prefixPatSyn []) unidir wildP + , pure $ PragmaD $ InlineP name Inline FunLike AllPhases + ] + where name = mkName "A" + + -- A slightly more complicated example that also puts an INLINE pragma + -- on a field name in a record pattern synonym + genPat2 :: Q [Dec] + genPat2 = sequence [ + patSynD con_name (recordPatSyn [fld_name]) implBidir (conP 'MkD [varP fld_name]) + , pure $ PragmaD $ InlineP con_name Inline FunLike AllPhases + , pure $ PragmaD $ InlineP fld_name Inline FunLike AllPhases + ] + where con_name = mkName "P" + fld_name = mkName "fld" + + decs1 <- genPat1 + decs2 <- genPat2 + pure (decs1 ++ decs2)) ===================================== testsuite/tests/th/T23203.stderr ===================================== @@ -0,0 +1,28 @@ +T23203.hs:(9,2)-(30,27): Splicing declarations + do let genPat1 :: Q [Dec] + genPat1 + = sequence + [patSynD name (prefixPatSyn []) unidir wildP, + pure $ PragmaD $ InlineP name Inline FunLike AllPhases] + where + name = mkName "A" + genPat2 :: Q [Dec] + genPat2 + = sequence + [patSynD + con_name (recordPatSyn [fld_name]) implBidir + (conP 'MkD [varP fld_name]), + pure $ PragmaD $ InlineP con_name Inline FunLike AllPhases, + pure $ PragmaD $ InlineP fld_name Inline FunLike AllPhases] + where + con_name = mkName "P" + fld_name = mkName "fld" + decs1 <- genPat1 + decs2 <- genPat2 + pure (decs1 ++ decs2) + ======> + pattern A <- _ + {-# INLINE A #-} + pattern P{fld} = MkD fld + {-# INLINE P #-} + {-# INLINE fld #-} ===================================== testsuite/tests/th/all.T ===================================== @@ -558,3 +558,4 @@ test('T22818', normal, compile, ['-v0']) test('T22819', normal, compile, ['-v0']) test('TH_fun_par', normal, compile, ['']) test('T23036', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('T23203', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/T23192.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Werror=redundant-constraints #-} + +module EventThing where + +class Monad m => Event m where + thingsForEvent :: m [Int] + +class Monad m => Thingy m where + thingies :: m [Int] + +-- Check that we don't get a redundant constraint warning for "Monad m". +-- See #19690. +instance (Monad m, Event m) => Thingy m where + thingies = thingsForEvent ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -870,3 +870,4 @@ test('T21443', normal, compile, ['']) test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) +test('T23192', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a36e70a9b05e9e884351b327a3d9fae79744d57...56c9caee6e9355115f7c2c50e94f42d9f441ab8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a36e70a9b05e9e884351b327a3d9fae79744d57...56c9caee6e9355115f7c2c50e94f42d9f441ab8f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 20:50:27 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 04 Apr 2023 16:50:27 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] Debug submodule Message-ID: <642c8d93771b2_3b005582354d022352e@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 6083339c by Matthew Pickering at 2023-04-04T21:50:16+01:00 Debug submodule - - - - - 1 changed file: - utils/haddock Changes: ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 03ba53ca764f56a13d12607c110f923f129e809a +Subproject commit 3c2206d3809530445e2cf74874f9f0e590b8f3ac View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6083339ca479c4d733c2a812d164534402242422 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6083339ca479c4d733c2a812d164534402242422 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 21:13:17 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 17:13:17 -0400 Subject: [Git][ghc/ghc][master] Fix unification with oversaturated type families Message-ID: <642c92edf2236_3b005589c31e822731b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - 4 changed files: - compiler/GHC/Core/Unify.hs - + testsuite/tests/simplCore/should_run/T23134.hs - + testsuite/tests/simplCore/should_run/T23134.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -1,6 +1,6 @@ -- (c) The University of Glasgow 2006 -{-# LANGUAGE ScopedTypeVariables, PatternSynonyms #-} +{-# LANGUAGE ScopedTypeVariables, PatternSynonyms, MultiWayIf #-} {-# LANGUAGE DeriveFunctor #-} @@ -47,6 +47,7 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set import GHC.Exts( oneShot ) +import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Data.FastString @@ -994,6 +995,59 @@ These two TyConApps have the same TyCon at the front but they (legitimately) have different numbers of arguments. They are surelyApart, so we can report that without looking any further (see #15704). + +Note [Unifying type applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Unifying type applications is quite subtle, as we found +in #23134 and #22647, when type families are involved. + +Suppose + type family F a :: Type -> Type + type family G k :: k = r | r -> k + +and consider these examples: + +* F Int ~ F Char, where F is injective + Since F is injective, we can reduce this to Int ~ Char, + therefore SurelyApart. + +* F Int ~ F Char, where F is not injective + Without injectivity, return MaybeApart. + +* G Type ~ G (Type -> Type) Int + Even though G is injective and the arguments to G are different, + we cannot deduce apartness because the RHS is oversaturated. + For example, G might be defined as + G Type = Maybe Int + G (Type -> Type) = Maybe + So we return MaybeApart. + +* F Int Bool ~ F Int Char -- SurelyApart (since Bool is apart from Char) + F Int Bool ~ Maybe a -- MaybeApart + F Int Bool ~ a b -- MaybeApart + F Int Bool ~ Char -> Bool -- MaybeApart + An oversaturated type family can match an application, + whether it's a TyConApp, AppTy or FunTy. Decompose. + +* F Int ~ a b + We cannot decompose a saturated, or under-saturated + type family application. We return MaybeApart. + +To handle all those conditions, unify_ty goes through +the following checks in sequence, where Fn is a type family +of arity n: + +* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n + A saturated application. + Here we can unify arguments in which Fn is injective. +* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n + A saturated type family can match anything - we return MaybeApart. +* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n + An oversaturated type family can be decomposed. +* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n + If we couldn't decompose in the previous step, we return SurelyApart. + +Afterwards, the rest of the code doesn't have to worry about type families. -} -------------- unify_ty: the main workhorse ----------- @@ -1035,31 +1089,63 @@ unify_ty env ty1 (TyVarTy tv2) kco = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco) unify_ty env ty1 ty2 _kco + + -- Handle non-oversaturated type families first + -- See Note [Unifying type applications] + -- + -- (C1) If we have T x1 ... xn ~ T y1 ... yn, use injectivity information of T + -- Note that both sides must not be oversaturated + | Just (tc1, tys1) <- isSatTyFamApp mb_tc_app1 + , Just (tc2, tys2) <- isSatTyFamApp mb_tc_app2 + , tc1 == tc2 + = do { let inj = case tyConInjectivityInfo tc1 of + NotInjective -> repeat False + Injective bs -> bs + + (inj_tys1, noninj_tys1) = partitionByList inj tys1 + (inj_tys2, noninj_tys2) = partitionByList inj tys2 + + ; unify_tys env inj_tys1 inj_tys2 + ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] + don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } + + | Just _ <- isSatTyFamApp mb_tc_app1 -- (C2) A (not-over-saturated) type-family application + = maybeApart MARTypeFamily -- behaves like a type variable; might match + + | Just _ <- isSatTyFamApp mb_tc_app2 -- (C2) A (not-over-saturated) type-family application + -- behaves like a type variable; might unify + -- but doesn't match (as in the TyVarTy case) + = if um_unif env then maybeApart MARTypeFamily else surelyApart + + -- Handle oversaturated type families. + -- + -- They can match an application (TyConApp/FunTy/AppTy), this is handled + -- the same way as in the AppTy case below. + -- + -- If there is no application, an oversaturated type family can only + -- match a type variable or a saturated type family, + -- both of which we handled earlier. So we can say surelyApart. + | Just (tc1, _) <- mb_tc_app1 + , isTypeFamilyTyCon tc1 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + | Just (tc2, _) <- mb_tc_app2 + , isTypeFamilyTyCon tc2 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + -- At this point, neither tc1 nor tc2 can be a type family. | Just (tc1, tys1) <- mb_tc_app1 , Just (tc2, tys2) <- mb_tc_app2 , tc1 == tc2 - = if isInjectiveTyCon tc1 Nominal - then unify_tys env tys1 tys2 - else do { let inj | isTypeFamilyTyCon tc1 - = case tyConInjectivityInfo tc1 of - NotInjective -> repeat False - Injective bs -> bs - | otherwise - = repeat False - - (inj_tys1, noninj_tys1) = partitionByList inj tys1 - (inj_tys2, noninj_tys2) = partitionByList inj tys2 - - ; unify_tys env inj_tys1 inj_tys2 - ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] - don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } - - | isTyFamApp mb_tc_app1 -- A (not-over-saturated) type-family application - = maybeApart MARTypeFamily -- behaves like a type variable; might match - - | isTyFamApp mb_tc_app2 -- A (not-over-saturated) type-family application - , um_unif env -- behaves like a type variable; might unify - = maybeApart MARTypeFamily + = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1) + ; unify_tys env tys1 tys2 + } -- TYPE and CONSTRAINT are not Apart -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim @@ -1160,16 +1246,16 @@ unify_tys env orig_xs orig_ys -- Possibly different saturations of a polykinded tycon -- See Note [Polykinded tycon applications] -isTyFamApp :: Maybe (TyCon, [Type]) -> Bool --- True if we have a saturated or under-saturated type family application +isSatTyFamApp :: Maybe (TyCon, [Type]) -> Maybe (TyCon, [Type]) +-- Return the argument if we have a saturated type family application -- If it is /over/ saturated then we return False. E.g. -- unify_ty (F a b) (c d) where F has arity 1 -- we definitely want to decompose that type application! (#22647) -isTyFamApp (Just (tc, tys)) - = not (isGenerativeTyCon tc Nominal) -- Type family-ish +isSatTyFamApp tapp@(Just (tc, tys)) + | isTypeFamilyTyCon tc && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated -isTyFamApp Nothing - = False + = tapp +isSatTyFamApp _ = Nothing --------------------------------- uVar :: UMEnv ===================================== testsuite/tests/simplCore/should_run/T23134.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE GHC2021, DataKinds, TypeFamilies #-} +module Main where + +import Data.Maybe +import Data.Kind + +main :: IO () +main = putStrLn str + +str :: String +str = case runInstrImpl @(TOption TUnit) mm MAP of + C VOption -> "good" + C Unused -> "bad" + +runInstrImpl :: forall inp out. Value (MapOpRes inp TUnit) -> Instr inp out -> Rec out +runInstrImpl m MAP = C m + +type MapOpRes :: T -> T -> T +type family MapOpRes c :: T -> T +type instance MapOpRes ('TOption x) = 'TOption + +mm :: Value (TOption TUnit) +mm = VOption +{-# NOINLINE mm #-} + +type Value :: T -> Type +data Value t where + VOption :: Value ('TOption t) + Unused :: Value t + +data T = TOption T | TUnit + +data Instr (inp :: T) (out :: T) where + MAP :: Instr c (TOption (MapOpRes c TUnit)) + +data Rec :: T -> Type where + C :: Value r -> Rec (TOption r) ===================================== testsuite/tests/simplCore/should_run/T23134.stdout ===================================== @@ -0,0 +1 @@ +good ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -110,4 +110,4 @@ test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #208 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) - +test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 4 21:13:59 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 04 Apr 2023 17:13:59 -0400 Subject: [Git][ghc/ghc][master] Add testcase for #23192 Message-ID: <642c931758591_3b0055892e32c23247a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/T23192.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/T23192.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Werror=redundant-constraints #-} + +module EventThing where + +class Monad m => Event m where + thingsForEvent :: m [Int] + +class Monad m => Thingy m where + thingies :: m [Int] + +-- Check that we don't get a redundant constraint warning for "Monad m". +-- See #19690. +instance (Monad m, Event m) => Thingy m where + thingies = thingsForEvent ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -870,3 +870,4 @@ test('T21443', normal, compile, ['']) test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) +test('T23192', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c165f079a13232a44689c55a61c70e2c9aea5464 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c165f079a13232a44689c55a61c70e2c9aea5464 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 08:59:54 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 05 Apr 2023 04:59:54 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] Attempt fixing bindist regex Message-ID: <642d388a730f_3b0055147df7f82752e4@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: f8f93599 by Matthew Pickering at 2023-04-05T09:59:39+01:00 Attempt fixing bindist regex - - - - - 1 changed file: - hadrian/bindist/Makefile Changes: ===================================== hadrian/bindist/Makefile ===================================== @@ -226,7 +226,7 @@ update_package_db: install_bin install_lib $(INSTALL_DATA) mk/system-cxx-std-lib-1.0.conf "$(DESTDIR)$(ActualLibsDir)/package.conf.d" @echo "Updating the package DB" $(foreach p, $(PKG_CONFS),\ - $(call patchpackageconf,$(shell echo $(notdir $p) | sed 's/-\([0-9]*[0-9]\.\)*\([0-9]\+\)\(-[0-9a-zA-Z]\+\)*\.conf//g'),$(shell echo "$p" | sed 's:\0xxx\0: :g'),$(docdir),$(shell mk/relpath.sh "$(ActualLibsDir)" "$(docdir)"),$(shell echo $(notdir $p) | sed 's/.conf//g'))) + $(call patchpackageconf,$(shell echo $(notdir $p) | sed 's/-[0-9.]*-[0-9a-zA-Z]*\.conf//g'),$(shell echo "$p" | sed 's:\0xxx\0: :g'),$(docdir),$(shell mk/relpath.sh "$(ActualLibsDir)" "$(docdir)"),$(shell echo $(notdir $p) | sed 's/.conf//g'))) '$(DESTDIR)$(ActualBinsDir)/$(CrossCompilePrefix)ghc-pkg' --global-package-db "$(DESTDIR)$(ActualLibsDir)/package.conf.d" recache install_mingw: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8f935994e0e358d413f57df397d8eeaf45c0bea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8f935994e0e358d413f57df397d8eeaf45c0bea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 11:44:47 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Wed, 05 Apr 2023 07:44:47 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 22 commits: base: Correct @since annotation for FP<->Integral bit cast operations. Message-ID: <642d5f2f1828e_3b005517289da0293422@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: b6e950c3 by Andreas Klebinger at 2023-04-05T17:14:28+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - b3bcf25d by Matthew Pickering at 2023-04-05T17:14:28+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - ebe79f6b by Sylvain Henry at 2023-04-05T17:14:28+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - f0c95618 by Ben Gamari at 2023-04-05T17:14:28+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - f30d0e51 by Matthew Pickering at 2023-04-05T17:14:28+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - 8da303ba by Matthew Pickering at 2023-04-05T17:14:28+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - 951bd209 by Matthew Pickering at 2023-04-05T17:14:28+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - abe44949 by Matthew Pickering at 2023-04-05T17:14:28+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - 5ce45815 by Matthew Pickering at 2023-04-05T17:14:28+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 747e20ed by Matthew Pickering at 2023-04-05T17:14:28+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - 91782221 by Matthew Pickering at 2023-04-05T17:14:28+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - ef11a3db by Matthew Pickering at 2023-04-05T17:14:28+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 584b79f7 by Matthew Pickering at 2023-04-05T17:14:28+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - 16cbd2ab by Matthew Pickering at 2023-04-05T17:14:28+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - c448f36d by Matthew Pickering at 2023-04-05T17:14:29+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - ba0a7c97 by Matthew Pickering at 2023-04-05T17:14:29+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 1caf6a39 by Matthew Pickering at 2023-04-05T17:14:29+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - e0a70743 by Matthew Pickering at 2023-04-05T17:14:29+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 7572982d by Matthew Pickering at 2023-04-05T17:14:29+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - a59fbf91 by Matthew Pickering at 2023-04-05T17:14:29+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 41cd318a by Simon Peyton Jones at 2023-04-05T17:14:29+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - eef166c2 by Matthew Pickering at 2023-04-05T17:14:29+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Match.hs-boot - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/Deps.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/Language/Haskell/Syntax/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5eea437e1b20e294a6e7a8267a1c968ac59053aa...eef166c2e544207a98d361e7977aa1d82d9c0c7c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5eea437e1b20e294a6e7a8267a1c968ac59053aa...eef166c2e544207a98d361e7977aa1d82d9c0c7c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 14:31:55 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 05 Apr 2023 10:31:55 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] JS: fix bounds checking (Issue 23123) Message-ID: <642d865bd5ceb_3b005519ddb4403082d9@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: db5327f0 by Josh Meredith at 2023-04-05T14:27:31+00:00 JS: fix bounds checking (Issue 23123) For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. Additionally, range-based operations must also check both the start and end of the range for bounds, if the range is greater than zero (all indicies are valid for ranges of size zero, since they are essentially no-ops). - - - - - 2 changed files: - compiler/GHC/StgToJS/Prim.hs - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -605,12 +605,12 @@ genPrim prof bound ty op = case op of SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_u32 a i IndexByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a i $ jVar \t -> mconcat + PrimInline . boundsCheckedLen bound a i $ jVar \t -> mconcat [ t |= a .^ "arr" , ifBlockS (t .&&. t .! (i .<<. two_)) [ r1 |= t .! (i .<<. two_) .! zero_ @@ -621,31 +621,31 @@ genPrim prof bound ty op = case op of ] ] - IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_f32 a i - IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_f64 a i + IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_f32 a i + IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ r |= read_f64 a i IndexByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a (Add i 3) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 3) $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i - IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_i16 a i - IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ mconcat + IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i + IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_i16 a i + IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_u16 a i - IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i - IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ mconcat + IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_u16 a i + IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_u32 a i + IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_u32 a i ReadByteArrayOp_Addr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -655,66 +655,66 @@ genPrim prof bound ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_f32 a i - ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_f64 a i + ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_f32 a i + ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ r |= read_f64 a i ReadByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a (Add i 3) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 3) $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i - ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_i16 a i - ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i + ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i + ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_i16 a i + ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_u16 a i - ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_u16 a i + ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_u32 a i ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e - WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e - WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e - WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_u32 a i e + WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e + WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_i32 a i e + WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_i32 a i e + WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_u32 a i e WriteByteArrayOp_Addr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_f32 a i e - WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 7) $ write_f64 a i e - WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e2 + WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_f32 a i e + WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ write_f64 a i e + WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_i32 a i e2 - WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i8 a i e - WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_i16 a i e - WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e + WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_i8 a i e + WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ write_i16 a i e + WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_i32 a i e WriteByteArrayOp_Int64 -> \[] [a,i,e1,e2] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ write_i32 a (Add (i .<<. one_) one_) e1 , write_u32 a (i .<<. one_) e2 ] - WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e - WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_u16 a i e - WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_u32 a i e + WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e + WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ write_u16 a i e + WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_u32 a i e WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ write_u32 a (Add (i .<<. one_) one_) h , write_u32 a (i .<<. one_) l ] CompareByteArraysOp -> \[r] [a1,o1,a2,o2,n] -> - PrimInline . boundsChecked bound a1 (Add o1 (Sub n 1)) - . boundsChecked bound a2 (Add o2 (Sub n 1)) + PrimInline . boundsCheckedRangeLen bound a1 o1 n + . boundsCheckedRangeLen bound a2 o2 n $ r |= app "h$compareByteArrays" [a1,o1,a2,o2,n] CopyByteArrayOp -> \[] [a1,o1,a2,o2,n] -> - PrimInline . boundsChecked bound a1 (Add o1 (Sub n 1)) - . boundsChecked bound a2 (Add o2 (Sub n 1)) + PrimInline . boundsCheckedRangeLen bound a1 o1 n + . boundsCheckedRangeLen bound a2 o2 n $ appS "h$copyMutableByteArray" [a1,o1,a2,o2,n] CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs CopyMutableByteArrayNonOverlappingOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs @@ -725,20 +725,20 @@ genPrim prof bound ty op = case op of CopyAddrToAddrNonOverlappingOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs SetByteArrayOp -> \[] [a,o,n,v] -> - PrimInline . boundsChecked bound a (Add o (Sub n 1)) $ loopBlockS zero_ (.<. n) \i -> + PrimInline . boundsCheckedRangeLen bound a o n $ loopBlockS zero_ (.<. n) \i -> [ write_u8 a (Add o i) v , postIncrS i ] SetAddrRangeOp -> \[] xs@[_a,_o,_n,_v] -> genPrim prof bound ty SetByteArrayOp [] xs - AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i v - FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray Add r a i v - FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray Sub r a i v - FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BAnd r a i v - FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BOr r a i v - FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v - FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BXor r a i v + AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_i32 a i + AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_i32 a i v + FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray Add r a i v + FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray Sub r a i v + FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray BAnd r a i v + FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray BOr r a i v + FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v + FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ fetchOpByteArray BXor r a i v ------------------------------- Addr# ------------------------------------------ @@ -1031,115 +1031,115 @@ genPrim prof bound ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , boundsChecked bound (a .^ "arr") x $ + , boundsCheckedLen bound (a .^ "arr") x $ ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_boff_f64 a i + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , boundsChecked bound (a .^ "arr") x $ + , boundsCheckedLen bound (a .^ "arr") x $ ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_boff_f64 a i + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_boff_i8 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , boundsChecked bound (a .^ "arr") (i .<<. two_) $ + , boundsCheckedLen bound (a .^ "arr") (i .<<. two_) $ a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 7) $ write_boff_f64 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_boff_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 7) $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e2 + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i -- then write the higher 4 bytes to i+4 - PrimInline . boundsChecked bound a i + PrimInline . boundsCheckedLen bound a i $ mconcat [ write_boff_i32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_boff_u16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline . boundsChecked bound a (Add i 7) + PrimInline . boundsCheckedLen bound a (Add i 7) $ mconcat [ write_boff_u32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e - CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i8 write_i8 r a i old new - CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 1) $ casOp read_i16 write_i16 r a i old new - CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a i $ casOp read_i8 write_i8 r a i old new + CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (Add i 1) $ casOp read_i16 write_i16 r a i old new + CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsChecked bound a (Add (i .<<. one_) one_) $ + CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsCheckedLen bound a (Add (i .<<. one_) one_) $ jVar \t_h t_l -> mconcat [ t_h |= read_i32 a (Add (i .<<. one_) one_) , t_l |= read_u32 a (i .<<. one_) , r_h |= t_h @@ -1473,9 +1473,32 @@ boundsChecked :: Bool -- ^ Should we do bounds checking? -> JStat boundsChecked False _ _ r = r boundsChecked True xs i r = - ifS ((i .<. xs .^ "length") .&&. (i .>=. zero_)) - r - (returnS $ app "h$exitProcess" [Int 134]) + ifS ((i .>=. zero_) .&&. (i .<. xs .^ "length")) r $ + returnS (app "h$exitProcess" [Int 134]) + +boundsCheckedRangeLen :: Bool + -> JExpr + -> JExpr + -> JExpr + -> JStat + -> JStat +boundsCheckedRangeLen False _ _ _ r = r +boundsCheckedRangeLen True xs i n r = + ifS (n .===. zero_) -- We can always fill zero elements, even if it seems out-of-bounds + r + (boundsCheckedLen True xs (Add i (Sub n 1)) (boundsCheckedLen True xs i r)) + + +boundsCheckedLen :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsCheckedLen False _ _ r = r +boundsCheckedLen True xs i r = + -- Byte arrays use `len` + ifS ((i .>=. zero_) .&&. (i .<. xs .^ "len")) r $ + returnS (app "h$exitProcess" [Int 134]) -- e|0 (32 bit signed integer truncation) required because of JS numbers. e|0 -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -229,4 +229,4 @@ test('T20640b', normal, compile_and_run, ['']) test('T22296',[only_ways(llvm_ways) ,unless(arch('x86_64'), skip)],compile_and_run,['']) test('T22798', normal, compile_and_run, ['-fregs-graph']) -test('CheckBoundsOK', js_broken(23123), compile_and_run, ['-fcheck-prim-bounds']) +test('CheckBoundsOK', js_broken(21142), compile_and_run, ['-fcheck-prim-bounds']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db5327f085b84f3a296d7347b63af6394dae026a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db5327f085b84f3a296d7347b63af6394dae026a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 14:35:31 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 05 Apr 2023 10:35:31 -0400 Subject: [Git][ghc/ghc][wip/T23083] CorePrep: Eta expand arguments (#23083) Message-ID: <642d8733ed7e4_3b005519fb697c310559@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 4f0eb801 by Sebastian Graf at 2023-04-05T16:34:17+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 8 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1445,12 +1445,31 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arg3 | Just ao <- cp_arityOpts (cpe_config env) + , not (is_join_head arg2) + , Just at <- exprEtaExpandArity ao arg2 + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = cpeEtaExpand (arityTypeArity at) arg2 + | otherwise + = arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1568,6 +1587,36 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We eta expand arguments in here, in CorePrep, rather than in the Simplifier, and +do so based on 'exprEtaExpandArity' rather than the cheaper 'exprArity' analysis +we do on let RHSs and lambdas. The reason for the latter is that the Simplifier +has already run the more costly analysis on lambdas and let RHSs and eta +expanded accordingly, while it does not try to eta expand arguments at all. + +So why eta expand arguments in CorePrep rather than in the Simplifier? +There are two reasons why eta expansion of arguments is useful + + 1. In expressions like @f (h `seq` (g $))@ (from T23083) eta expanding the + argument to @f (\x -> h `seq` (g $ x))@ allows us to save allocation of a + closure and have a faster call sequence; a code-gen matter. + + 2. The eta expansion to @f (\x -> h `seq` (g $ x))@ gives rise to another + opportunity: We could inline ($), saving call overhead and perhaps turning + an unknown call into a known call. In general, there could be further + simplification based on the structure of the concrete argument `x`. + Whether we should inline in the PAP `(g $)` (thus solving this problem + independently of (1)) is discussed in #22886. + +To profit from (1), it is enough to eta expand in CorePrep, while (2) shows +that in some rare cases as above, eta expansion of arguments may enable +further simplification. CorePrep would not allow to exploit (2), while eta +expansion in the Simplifier would. + +Alas, trying to eta expand arguments in every round of the Simplifier is costly +(!10088 measured a geom. mean of +2.0% regression in ghc/alloc perf, regressing +as much as 27.2%), so we only exploit (1) for now. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1931,6 +1980,10 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1941,6 +1994,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -259,6 +259,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoArgEtaExpansion -- Eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3398,6 +3398,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-arg-eta-expansion" Opt_DoArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -3990,6 +3991,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([2], Opt_DoArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,16 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-arg-eta-expansion + :shortdesc: Enable argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T23083 where + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,42 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 27, types: 24, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 12, types: 13, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> GHC.Base.$ @GHC.Types.LiftedRep @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4f0eb801500744770cc6bfef401229113c28a8c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4f0eb801500744770cc6bfef401229113c28a8c4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 15:08:45 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 05 Apr 2023 11:08:45 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 19 commits: ghc-heap: remove wrong Addr# coercion (#23181) Message-ID: <642d8efde5ec1_3b00551a8dcdd03129a5@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - 2d3670c2 by Matthew Pickering at 2023-04-05T10:50:26+01:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 40184df4 by romes at 2023-04-05T10:50:27+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 04b25319 by romes at 2023-04-05T10:50:27+01:00 Validate compatibility of ghcs when loading plugins - - - - - f00b8f1e by romes at 2023-04-05T16:08:22+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - a7503789 by Matthew Pickering at 2023-04-05T16:08:22+01:00 Use hash-unit-ids in release jobs - - - - - 27 changed files: - .gitlab-ci.yml - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Unit/Types.hs - compiler/Setup.hs - compiler/ghc.cabal.in - hadrian/bindist/Makefile - hadrian/bootstrap/generate_bootstrap_plans - hadrian/bootstrap/plan-9_2_1.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8f935994e0e358d413f57df397d8eeaf45c0bea...a75037892c809b196d0538de306883e215c4ddfc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8f935994e0e358d413f57df397d8eeaf45c0bea...a75037892c809b196d0538de306883e215c4ddfc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 20:21:38 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 05 Apr 2023 16:21:38 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 8 commits: GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) Message-ID: <642dd852ab84c_3b00551fb18f543651d@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - f0395a5b by Simon Peyton Jones at 2023-04-05T21:23:17+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - b39504b9 by Simon Peyton Jones at 2023-04-05T21:23:17+01:00 Add some documentation about redundant constraints - - - - - ca5971bd by Simon Peyton Jones at 2023-04-05T21:23:17+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever #23223: misleading error with partial type signatuers See the long notes: * Note [ApproximateWC] in GHC.Tc.Solver * Note [Partial type signatures and the MR] in GHC.Tc.Gen.Bind All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. The test #19106 becomes an error again, but with a better error message; it's a very subtle case, conjured out of Richard's brain. - - - - - 96d5d693 by Simon Peyton Jones at 2023-04-05T21:23:17+01:00 Wibble partial type sigs Needs better documentation - - - - - 19 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/abcbfe522b68f0fe17092818472162794bf22605...96d5d6931b6bedcff7817bed43b003a0482ceb11 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/abcbfe522b68f0fe17092818472162794bf22605...96d5d6931b6bedcff7817bed43b003a0482ceb11 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 5 20:49:19 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 05 Apr 2023 16:49:19 -0400 Subject: [Git][ghc/ghc][wip/T13660] Fix it Message-ID: <642ddecfc227e_3b005520354bdc368123@gitlab.mail> Ben Gamari pushed to branch wip/T13660 at Glasgow Haskell Compiler / GHC Commits: b9947703 by Ben Gamari at 2023-04-05T20:49:18+00:00 Fix it - - - - - 1 changed file: - libraries/base/System/Posix/Internals.hs Changes: ===================================== libraries/base/System/Posix/Internals.hs ===================================== @@ -43,7 +43,9 @@ import System.IO.Error import GHC.Base import GHC.Num +#if defined(mingw32_HOST_OS) import GHC.OldList (elem) +#endif import GHC.Ptr import GHC.Real import GHC.IO View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b99477030a04d52962c816f188a5b4c82045c6a5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b99477030a04d52962c816f188a5b4c82045c6a5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 00:17:55 2023 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 05 Apr 2023 20:17:55 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/unsupported-llvm-version-docs Message-ID: <642e0fb3d1d39_3b005523928c403793ea@gitlab.mail> Brandon Chinn pushed new branch wip/unsupported-llvm-version-docs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/unsupported-llvm-version-docs You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 02:41:01 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Wed, 05 Apr 2023 22:41:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22937 Message-ID: <642e313d73645_3b005525ce3ab8389651@gitlab.mail> Matthew Craven pushed new branch wip/T22937 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22937 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 05:00:47 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Apr 2023 01:00:47 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fix unification with oversaturated type families Message-ID: <642e51ff7d3a1_3b0055282b541c39516e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - 24097692 by Ben Gamari at 2023-04-06T01:00:40-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 2b79e386 by Brandon Chinn at 2023-04-06T01:00:40-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 8 changed files: - compiler/GHC/Core/Unify.hs - docs/users_guide/using-warnings.rst - rts/include/rts/storage/ClosureMacros.h - + testsuite/tests/simplCore/should_run/T23134.hs - + testsuite/tests/simplCore/should_run/T23134.stdout - testsuite/tests/simplCore/should_run/all.T - + testsuite/tests/typecheck/should_compile/T23192.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -1,6 +1,6 @@ -- (c) The University of Glasgow 2006 -{-# LANGUAGE ScopedTypeVariables, PatternSynonyms #-} +{-# LANGUAGE ScopedTypeVariables, PatternSynonyms, MultiWayIf #-} {-# LANGUAGE DeriveFunctor #-} @@ -47,6 +47,7 @@ import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set import GHC.Exts( oneShot ) +import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Data.FastString @@ -994,6 +995,59 @@ These two TyConApps have the same TyCon at the front but they (legitimately) have different numbers of arguments. They are surelyApart, so we can report that without looking any further (see #15704). + +Note [Unifying type applications] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Unifying type applications is quite subtle, as we found +in #23134 and #22647, when type families are involved. + +Suppose + type family F a :: Type -> Type + type family G k :: k = r | r -> k + +and consider these examples: + +* F Int ~ F Char, where F is injective + Since F is injective, we can reduce this to Int ~ Char, + therefore SurelyApart. + +* F Int ~ F Char, where F is not injective + Without injectivity, return MaybeApart. + +* G Type ~ G (Type -> Type) Int + Even though G is injective and the arguments to G are different, + we cannot deduce apartness because the RHS is oversaturated. + For example, G might be defined as + G Type = Maybe Int + G (Type -> Type) = Maybe + So we return MaybeApart. + +* F Int Bool ~ F Int Char -- SurelyApart (since Bool is apart from Char) + F Int Bool ~ Maybe a -- MaybeApart + F Int Bool ~ a b -- MaybeApart + F Int Bool ~ Char -> Bool -- MaybeApart + An oversaturated type family can match an application, + whether it's a TyConApp, AppTy or FunTy. Decompose. + +* F Int ~ a b + We cannot decompose a saturated, or under-saturated + type family application. We return MaybeApart. + +To handle all those conditions, unify_ty goes through +the following checks in sequence, where Fn is a type family +of arity n: + +* (C1) Fn x_1 ... x_n ~ Fn y_1 .. y_n + A saturated application. + Here we can unify arguments in which Fn is injective. +* (C2) Fn x_1 ... x_n ~ anything, anything ~ Fn x_1 ... x_n + A saturated type family can match anything - we return MaybeApart. +* (C3) Fn x_1 ... x_m ~ a b, a b ~ Fn x_1 ... x_m where m > n + An oversaturated type family can be decomposed. +* (C4) Fn x_1 ... x_m ~ anything, anything ~ Fn x_1 ... x_m, where m > n + If we couldn't decompose in the previous step, we return SurelyApart. + +Afterwards, the rest of the code doesn't have to worry about type families. -} -------------- unify_ty: the main workhorse ----------- @@ -1035,31 +1089,63 @@ unify_ty env ty1 (TyVarTy tv2) kco = uVar (umSwapRn env) tv2 ty1 (mkSymCo kco) unify_ty env ty1 ty2 _kco + + -- Handle non-oversaturated type families first + -- See Note [Unifying type applications] + -- + -- (C1) If we have T x1 ... xn ~ T y1 ... yn, use injectivity information of T + -- Note that both sides must not be oversaturated + | Just (tc1, tys1) <- isSatTyFamApp mb_tc_app1 + , Just (tc2, tys2) <- isSatTyFamApp mb_tc_app2 + , tc1 == tc2 + = do { let inj = case tyConInjectivityInfo tc1 of + NotInjective -> repeat False + Injective bs -> bs + + (inj_tys1, noninj_tys1) = partitionByList inj tys1 + (inj_tys2, noninj_tys2) = partitionByList inj tys2 + + ; unify_tys env inj_tys1 inj_tys2 + ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] + don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } + + | Just _ <- isSatTyFamApp mb_tc_app1 -- (C2) A (not-over-saturated) type-family application + = maybeApart MARTypeFamily -- behaves like a type variable; might match + + | Just _ <- isSatTyFamApp mb_tc_app2 -- (C2) A (not-over-saturated) type-family application + -- behaves like a type variable; might unify + -- but doesn't match (as in the TyVarTy case) + = if um_unif env then maybeApart MARTypeFamily else surelyApart + + -- Handle oversaturated type families. + -- + -- They can match an application (TyConApp/FunTy/AppTy), this is handled + -- the same way as in the AppTy case below. + -- + -- If there is no application, an oversaturated type family can only + -- match a type variable or a saturated type family, + -- both of which we handled earlier. So we can say surelyApart. + | Just (tc1, _) <- mb_tc_app1 + , isTypeFamilyTyCon tc1 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + | Just (tc2, _) <- mb_tc_app2 + , isTypeFamilyTyCon tc2 + = if | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1 + , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2 + -> unify_ty_app env ty1a [ty1b] ty2a [ty2b] -- (C3) + | otherwise -> surelyApart -- (C4) + + -- At this point, neither tc1 nor tc2 can be a type family. | Just (tc1, tys1) <- mb_tc_app1 , Just (tc2, tys2) <- mb_tc_app2 , tc1 == tc2 - = if isInjectiveTyCon tc1 Nominal - then unify_tys env tys1 tys2 - else do { let inj | isTypeFamilyTyCon tc1 - = case tyConInjectivityInfo tc1 of - NotInjective -> repeat False - Injective bs -> bs - | otherwise - = repeat False - - (inj_tys1, noninj_tys1) = partitionByList inj tys1 - (inj_tys2, noninj_tys2) = partitionByList inj tys2 - - ; unify_tys env inj_tys1 inj_tys2 - ; unless (um_inj_tf env) $ -- See (end of) Note [Specification of unification] - don'tBeSoSure MARTypeFamily $ unify_tys env noninj_tys1 noninj_tys2 } - - | isTyFamApp mb_tc_app1 -- A (not-over-saturated) type-family application - = maybeApart MARTypeFamily -- behaves like a type variable; might match - - | isTyFamApp mb_tc_app2 -- A (not-over-saturated) type-family application - , um_unif env -- behaves like a type variable; might unify - = maybeApart MARTypeFamily + = do { massertPpr (isInjectiveTyCon tc1 Nominal) (ppr tc1) + ; unify_tys env tys1 tys2 + } -- TYPE and CONSTRAINT are not Apart -- See Note [Type and Constraint are not apart] in GHC.Builtin.Types.Prim @@ -1160,16 +1246,16 @@ unify_tys env orig_xs orig_ys -- Possibly different saturations of a polykinded tycon -- See Note [Polykinded tycon applications] -isTyFamApp :: Maybe (TyCon, [Type]) -> Bool --- True if we have a saturated or under-saturated type family application +isSatTyFamApp :: Maybe (TyCon, [Type]) -> Maybe (TyCon, [Type]) +-- Return the argument if we have a saturated type family application -- If it is /over/ saturated then we return False. E.g. -- unify_ty (F a b) (c d) where F has arity 1 -- we definitely want to decompose that type application! (#22647) -isTyFamApp (Just (tc, tys)) - = not (isGenerativeTyCon tc Nominal) -- Type family-ish +isSatTyFamApp tapp@(Just (tc, tys)) + | isTypeFamilyTyCon tc && not (tys `lengthExceeds` tyConArity tc) -- Not over-saturated -isTyFamApp Nothing - = False + = tapp +isSatTyFamApp _ = Nothing --------------------------------- uVar :: UMEnv ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -1615,7 +1615,7 @@ of ``-W(no-)*``. :shortdesc: Warn when using :ghc-flag:`-fllvm` with an unsupported version of LLVM. :type: dynamic - :reverse: -Wno-monomorphism-restriction + :reverse: -Wno-unsupported-llvm-version :category: :since: 7.8 ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -479,11 +479,13 @@ EXTERN_INLINE StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) memory we're about to zero. Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero - immutable closure's slop. + immutable closure's slop. Similarly, the concurrent GC's mark thread + may race when a mutator during slop-zeroing. Consequently, we also disable + zeroing when the non-moving GC is in use. Hence, an immutable closure's slop is zeroed when either: - - PROFILING && era > 0 (LDV is on) or + - PROFILING && era > 0 (LDV is on) && !nonmoving-gc-enabled or - !THREADED && DEBUG Additionally: @@ -535,8 +537,10 @@ zeroSlop (StgClosure *p, #endif ; - // Only if we're running single threaded. - const bool can_zero_immutable_slop = getNumCapabilities() == 1; + const bool can_zero_immutable_slop = + // Only if we're running single threaded. + getNumCapabilities() == 1 + && !RTS_DEREF(RtsFlags).GcFlags.useNonmoving; // see #23170 const bool zero_slop_immutable = want_to_zero_immutable_slop && can_zero_immutable_slop; ===================================== testsuite/tests/simplCore/should_run/T23134.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE GHC2021, DataKinds, TypeFamilies #-} +module Main where + +import Data.Maybe +import Data.Kind + +main :: IO () +main = putStrLn str + +str :: String +str = case runInstrImpl @(TOption TUnit) mm MAP of + C VOption -> "good" + C Unused -> "bad" + +runInstrImpl :: forall inp out. Value (MapOpRes inp TUnit) -> Instr inp out -> Rec out +runInstrImpl m MAP = C m + +type MapOpRes :: T -> T -> T +type family MapOpRes c :: T -> T +type instance MapOpRes ('TOption x) = 'TOption + +mm :: Value (TOption TUnit) +mm = VOption +{-# NOINLINE mm #-} + +type Value :: T -> Type +data Value t where + VOption :: Value ('TOption t) + Unused :: Value t + +data T = TOption T | TUnit + +data Instr (inp :: T) (out :: T) where + MAP :: Instr c (TOption (MapOpRes c TUnit)) + +data Rec :: T -> Type where + C :: Value r -> Rec (TOption r) ===================================== testsuite/tests/simplCore/should_run/T23134.stdout ===================================== @@ -0,0 +1 @@ +good ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -110,4 +110,4 @@ test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #208 test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) - +test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) ===================================== testsuite/tests/typecheck/should_compile/T23192.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -Werror=redundant-constraints #-} + +module EventThing where + +class Monad m => Event m where + thingsForEvent :: m [Int] + +class Monad m => Thingy m where + thingies :: m [Int] + +-- Check that we don't get a redundant constraint warning for "Monad m". +-- See #19690. +instance (Monad m, Event m) => Thingy m where + thingies = thingsForEvent ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -870,3 +870,4 @@ test('T21443', normal, compile, ['']) test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) +test('T23192', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56c9caee6e9355115f7c2c50e94f42d9f441ab8f...2b79e3865d19ec02b3dba02052c2627c8ea0edb2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56c9caee6e9355115f7c2c50e94f42d9f441ab8f...2b79e3865d19ec02b3dba02052c2627c8ea0edb2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 07:41:02 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Apr 2023 03:41:02 -0400 Subject: [Git][ghc/ghc][master] nonmoving: Disable slop-zeroing Message-ID: <642e778e9f88c_3b00552aa9c674418440@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 1 changed file: - rts/include/rts/storage/ClosureMacros.h Changes: ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -479,11 +479,13 @@ EXTERN_INLINE StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) memory we're about to zero. Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero - immutable closure's slop. + immutable closure's slop. Similarly, the concurrent GC's mark thread + may race when a mutator during slop-zeroing. Consequently, we also disable + zeroing when the non-moving GC is in use. Hence, an immutable closure's slop is zeroed when either: - - PROFILING && era > 0 (LDV is on) or + - PROFILING && era > 0 (LDV is on) && !nonmoving-gc-enabled or - !THREADED && DEBUG Additionally: @@ -535,8 +537,10 @@ zeroSlop (StgClosure *p, #endif ; - // Only if we're running single threaded. - const bool can_zero_immutable_slop = getNumCapabilities() == 1; + const bool can_zero_immutable_slop = + // Only if we're running single threaded. + getNumCapabilities() == 1 + && !RTS_DEREF(RtsFlags).GcFlags.useNonmoving; // see #23170 const bool zero_slop_immutable = want_to_zero_immutable_slop && can_zero_immutable_slop; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 07:41:37 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 06 Apr 2023 03:41:37 -0400 Subject: [Git][ghc/ghc][master] Fix reverse flag for -Wunsupported-llvm-version Message-ID: <642e77b1b89b6_3b00552aa11e98421955@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 1 changed file: - docs/users_guide/using-warnings.rst Changes: ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -1615,7 +1615,7 @@ of ``-W(no-)*``. :shortdesc: Warn when using :ghc-flag:`-fllvm` with an unsupported version of LLVM. :type: dynamic - :reverse: -Wno-monomorphism-restriction + :reverse: -Wno-unsupported-llvm-version :category: :since: 7.8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04b80850c535fa8c11f435711577296a99499105 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04b80850c535fa8c11f435711577296a99499105 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 09:04:01 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 06 Apr 2023 05:04:01 -0400 Subject: [Git][ghc/ghc][wip/T23145] Pmc: Treat `x ~ y @ty` the same as `x ~ y` (#23145) Message-ID: <642e8b0133233_3b00552c5d643043125d@gitlab.mail> Sebastian Graf pushed to branch wip/T23145 at Glasgow Haskell Compiler / GHC Commits: 0b65d387 by Sebastian Graf at 2023-04-06T11:03:54+02:00 Pmc: Treat `x ~ y @ty` the same as `x ~ y` (#23145) In #23145 we had a desugaring that matched on expressions `ds @Any` and `ds @blah` (where `blah /= Any`). In both cases, we match on the same value, but Long-distance information was unable to figure this out. The fix is rather simple: Upon reasoning about the Core constraint `x ~ ds @Any`, drop any type arguments to see `x ~ ds`, then we will equate that to the same as `ds @blah`. This plays a bit fast-and-loose with types; on the other hand, the situations in which can give the same value different types should be exceedingly rare. Fixes #23145. - - - - - 3 changed files: - compiler/GHC/HsToCore/Pmc/Solver.hs - + testsuite/tests/pmcheck/should_compile/T23145.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Pmc/Solver.hs ===================================== @@ -868,15 +868,23 @@ addCoreCt nabla x e = do -- Otherwise we alternate endlessly between [] and "" [] -> data_con_app x emptyInScopeSet nilDataCon [] s' -> core_expr x (mkListExpr charTy (map mkCharExpr s')) + | Just lit <- coreExprAsPmLit e = pm_lit x lit + | Just (in_scope, _empty_floats@[], dc, _arg_tys, args) <- exprIsConApp_maybe in_scope_env e = data_con_app x in_scope dc args - -- See Note [Detecting pattern synonym applications in expressions] - | Var y <- e, Nothing <- isDataConId_maybe x - -- We don't consider DataCons flexible variables + -- See Note [Detecting pattern synonym applications in expressions] + + | (Var y, args) <- collectArgs e + -- This catches the case of a variable constraints `x ~ y` + , all isTypeArg args + -- See Note [Identify VarInfo modulo type arguments] + , Nothing <- isDataConId_maybe x + -- We don't consider DataCons flexible variables = modifyT (\nabla -> addVarCt nabla x y) + | otherwise -- Any other expression. Try to find other uses of a semantically -- equivalent expression and represent them by the same variable! @@ -1059,10 +1067,41 @@ In the end, replacing dictionaries with an error value in the pattern-match checker was the most self-contained, although we might want to revisit once we implement a more robust approach to computing equality in the pattern-match checker (see #19272). --} -{- Note [The Pos/Neg invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Identify VarInfo modulo type arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider (#23145) + + f :: (forall a. Maybe a) -> Maybe b + f (Just x) = Just x + f Nothing = Nothing + +this desugars to + + f = \ @b (ds :: forall a. Maybe a) -> + case ds @b of { + Just x -> Just @b x; + Nothing -> + case ds @Any of { + Just ipv -> patError ... + Nothing -> Nothing @b + } + } + +Note we match on `ds` twice with different type arguments applied, but since the +type arguments are erased both matches must yield the same value. Hence we should +not warn about `f` having an incomplete match. +A good way to achieve that is discard the type arguments in the constraint `pm +~ ds @b` (where `pm` is the match variable of the outermost Case) so that we +get `pm ~ ds`, with the outcome of giving both match variables the same VarInfo +as `ds`. Long distance information will sort out the rest and we the checker +detects `f` as exhaustive. + +Note that the potential type confusion is harmless as the TyCon of `ds` and `pm` +must be the same (if it exists). + +Note [The Pos/Neg invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Invariant applying to each VarInfo: Whenever we have @C @tvs args@ in 'vi_pos', any entry in 'vi_neg' must be incomparable to C (return Nothing) according to 'eqPmAltCons'. Those entries that are comparable either lead to a refutation ===================================== testsuite/tests/pmcheck/should_compile/T23145.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns #-} +module T23145 where + +data T a + = MkT1 a + | MkT2 + +f :: (forall a. T a) -> T b +f (MkT1 x) = MkT1 x +f MkT2 = MkT2 ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -159,3 +159,4 @@ test('EmptyCase010', [], compile, [overlapping_incomplete]) test('T19271', [], compile, [overlapping_incomplete]) test('T21761', [], compile, [overlapping_incomplete]) test('T22964', [], compile, [overlapping_incomplete]) +test('T23145', [], compile, [overlapping_incomplete]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b65d3873b30f87bfe3b9452f8d7432a04baf1ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0b65d3873b30f87bfe3b9452f8d7432a04baf1ce You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 09:46:00 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 06 Apr 2023 05:46:00 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 6 commits: nonmoving: Disable slop-zeroing Message-ID: <642e94d8621bb_3b00552cfa45984336ec@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 90eb4d85 by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - a96b14fd by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Add some documentation about redundant constraints - - - - - 6f392c6e by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever #23223: misleading error with partial type signatuers See the long notes: * Note [ApproximateWC] in GHC.Tc.Solver * Note [Partial type signatures and the MR] in GHC.Tc.Gen.Bind All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. The test #19106 becomes an error again, but with a better error message; it's a very subtle case, conjured out of Richard's brain. - - - - - 58df60df by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Wibble partial type sigs Needs better documentation - - - - - 18 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96d5d6931b6bedcff7817bed43b003a0482ceb11...58df60df7efe9e7920d962da3525a35826608b2d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96d5d6931b6bedcff7817bed43b003a0482ceb11...58df60df7efe9e7920d962da3525a35826608b2d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 14:50:00 2023 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Thu, 06 Apr 2023 10:50:00 -0400 Subject: [Git][ghc/ghc][wip/int-index/visibility-check] 101 commits: Rename () into Unit, (,,...,,) into Tuple (#21294) Message-ID: <642edc18e08d7_3b00553241f910504924@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/visibility-check at Glasgow Haskell Compiler / GHC Commits: a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - e52ccbd3 by Vladislav Zavialov at 2023-04-06T15:35:04+02:00 Ignore forall visibility in eqType (#22762) Prior to this change, the equality relation on types took ForAllTyFlag into account, making a distinction between: 1. forall a. blah 2. forall a -> blah Not anymore. This distinction is important in surface Haskell, but it has no meaning in Core where type abstraction and type application are always explicit. At the same time, if we are not careful to track this flag, Core Lint will fail, as reported in #22762: *** Core Lint errors : in result of TcGblEnv axioms *** From-kind of Cast differs from kind of enclosed type From-kind: forall (b :: Bool) -> * Kind of enclosed type: forall {b :: Bool}. * The solution is to compare types for equality modulo visibility (ForAllTyFlag). Updated functions: nonDetCmpType (worker for eqType) eqDeBruijnType tc_eq_type (worker for tcEqType) can_eq_nc In order to retain the distinction between visible and invisible forall in user-written code, we introduce new ad-hoc checks: checkEqForallVis (in checking mode) cteForallKindVisDiff (in inference mode) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/SimpleOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/90a9540fd1bffbe905ed356adbc60ffdc6249785...e52ccbd3cc5879350548e455f5e910ffda2332ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/90a9540fd1bffbe905ed356adbc60ffdc6249785...e52ccbd3cc5879350548e455f5e910ffda2332ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 18:21:02 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Thu, 06 Apr 2023 14:21:02 -0400 Subject: [Git][ghc/ghc][wip/T22937] CorePrep: Handle over-saturated primitives Message-ID: <642f0d8e2418b_3b005535eede705382c6@gitlab.mail> Matthew Craven pushed to branch wip/T22937 at Glasgow Haskell Compiler / GHC Commits: 1bd865bf by Matthew Craven at 2023-04-06T14:15:58-04:00 CorePrep: Handle over-saturated primitives Fixes #22937. See the new wrinkle (W2) in Note [Calling primitives with the right arity]. - - - - - 6 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/core-to-stg/T22937.hs - + testsuite/tests/core-to-stg/T22937.stdout - testsuite/tests/core-to-stg/all.T Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -700,7 +700,7 @@ convention for curried applications that can accommodate representation polymorphism. To ensure saturation, CorePrep eta expands all primop applications as -described in Note [Eta expansion of hasNoBinding things in CorePrep] in +described in Note [Calling primitives with the right arity] in GHC.Core.Prep. Historical Note: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -6,7 +6,7 @@ (c) The University of Glasgow, 1994-2006 -Core pass to saturate constructors and PrimOps +Core pass to ANF-ise and saturate PrimOps and cbv-functions -} module GHC.CoreToStg.Prep @@ -80,7 +80,7 @@ Note [CorePrep Overview] The goal of this pass is to prepare for code generation. -1. Saturate constructor and primop applications. +1. Saturate applications of primops and cbv functions. 2. Convert to A-normal form; that is, function arguments are always variables. @@ -1101,12 +1101,14 @@ cpeApp top_env expr = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 hd = getIdFromTrivialExpr_maybe e2 - -- Determine number of required arguments. See Note [Ticks and mandatory eta expansion] - min_arity = case hd of + -- Determine the number of required arguments. + -- See Note [Calling primitives with the right arity] + -- and Note [Ticks and mandatory eta expansion] + exact_arity = case hd of Just v_hd -> if hasNoBinding v_hd then Just $! (idArity v_hd) else Nothing Nothing -> Nothing -- ; pprTraceM "cpe_app:stricts:" (ppr v <+> ppr args $$ ppr stricts $$ ppr (idCbvMarks_maybe v)) - ; (app, floats, unsat_ticks) <- rebuild_app env args e2 emptyFloats stricts min_arity + ; (app, floats, unsat_ticks) <- rebuild_app env args e2 emptyFloats stricts exact_arity ; mb_saturate hd app floats unsat_ticks depth } where depth = val_args args @@ -1134,9 +1136,12 @@ cpeApp top_env expr -- If evalDmd says that it's sure to be evaluated, -- we'll end up case-binding it ; (app, floats,unsat_ticks) <- rebuild_app env args fun' fun_floats [] Nothing - ; mb_saturate Nothing app floats unsat_ticks (val_args args) } + ; massert (null unsat_ticks) + ; return (floats, app) } - -- Count the number of value arguments *and* coercions (since we don't eliminate the later in STG) + + -- Count the number of value arguments *including* coercions + -- (since we don't eliminate the latter in STG) val_args :: [ArgInfo] -> Int val_args args = go args 0 where @@ -1174,13 +1179,13 @@ cpeApp top_env expr -> CpeApp -- The function -> Floats -> [Demand] - -> Maybe Arity + -> Maybe Arity -- (Just arity) when headed by a hasNoBinding Id -> UniqSM (CpeApp ,Floats ,[CoreTickish] -- Underscoped ticks. See Note [Ticks and mandatory eta expansion] ) - rebuild_app env args app floats ss req_depth = - rebuild_app' env args app floats ss [] (fromMaybe 0 req_depth) + rebuild_app env args app floats ss req_depth = + rebuild_app' env args app floats ss [] (fromMaybe (0-1) req_depth) rebuild_app' :: CorePrepEnv @@ -1189,33 +1194,37 @@ cpeApp top_env expr -> Floats -> [Demand] -> [CoreTickish] - -> Int -- Number of arguments required to satisfy minimal tick scopes. + -> Int -- Negative for normal functions; + -- number of remaining value arguments for hasNoBinding Ids; + -- see Note [Calling primitives with the right arity] + -- and Note [Ticks and mandatory eta expansion] -> UniqSM (CpeApp, Floats, [CoreTickish]) rebuild_app' _ [] app floats ss rt_ticks !_req_depth = assertPpr (null ss) (ppr ss)-- make sure we used all the strictness info return (app, floats, rt_ticks) rebuild_app' env (a : as) fun' floats ss rt_ticks req_depth = case a of - -- See Note [Ticks and mandatory eta expansion] - _ - | not (null rt_ticks) - , req_depth <= 0 - -> - let tick_fun = foldr mkTick fun' rt_ticks - in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth - CpeApp (Type arg_ty) -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth where arg_ty' = cpSubstTy env arg_ty - CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth - where - co' = cpSubstCo env co - - CpeApp arg -> do - let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make + CpeApp arg + | req_depth == 0 -> do + -- See Note [Calling primitives with the right arity], wrinkle W2: + -- The primitive already has the right number of value arguments + -- we must case-bind before we can apply it to another argument. + -- We also apply any collected profiling ticks now; see + -- Note [Ticks and mandatory eta expansion] + v <- newVar (exprType fun') + let tick_fun = foldr mkTick fun' rt_ticks + float = mkFloat env evalDmd False v tick_fun + rebuild_app' env (a : as) (Var v) (addFloat floats float) ss [] (0-1) + | Coercion co <- arg + , let co' = cpSubstCo env co + -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks (req_depth-1) + | otherwise -> do + let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make, wrinkle W3 = case (ss, isLazyExpr arg) of (_ : ss_rest, True) -> (topDmd, ss_rest) (ss1 : ss_rest, False) -> (ss1, ss_rest) @@ -1227,10 +1236,11 @@ cpeApp top_env expr -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth where co' = cpSubstCo env co + -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime - , req_depth > 0 + , req_depth >= 0 -> assert (isProfTick tickish) $ rebuild_app' env as fun' floats ss (tickish:rt_ticks) req_depth | otherwise @@ -1238,7 +1248,7 @@ cpeApp top_env expr -> rebuild_app' env as fun' (addFloat floats (FloatTick tickish)) ss rt_ticks req_depth isLazyExpr :: CoreExpr -> Bool --- See Note [lazyId magic] in GHC.Types.Id.Make +-- See Note [lazyId magic] in GHC.Types.Id.Make, wrinkle W3 isLazyExpr (Cast e _) = isLazyExpr e isLazyExpr (Tick _ e) = isLazyExpr e isLazyExpr (Var f `App` _ `App` _) = f `hasKey` lazyIdKey @@ -1445,6 +1455,11 @@ the continuation may not be a manifest lambda. Note [ANF-ising literal string arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*** Is this Note still necessary? Yes, the example transformation to + foo = u\ [] case "turtle"# of s { __DEFAULT__ -> Foo s } + seems pretty bad. But these days, we'd expect the simplifier to + have floated "turtle"# to top-level anyway. Right? + Consider a program like, data Foo = Foo Addr# @@ -1516,18 +1531,42 @@ because that has different strictness. Hence the use of 'allLazy'. -- Building the saturated syntax -- --------------------------------------------------------------------------- -Note [Eta expansion of hasNoBinding things in CorePrep] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -maybeSaturate deals with eta expanding to saturate things that can't deal with -unsaturated applications (identified by 'hasNoBinding', currently -foreign calls, unboxed tuple/sum constructors, and representation-polymorphic -primitives such as 'coerce' and 'unsafeCoerce#'). +Note [Calling primitives with the right arity] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For several low-level things, the code generator can only handle +saturated applications, i.e. applications with exactly the right +number of arguments. (These things are identified by 'hasNoBinding'. +Currently, they are: foreign calls, unboxed tuple/sum constructors, +and representation-polymorphic primitives such as 'coerce' and +'unsafeCoerce#'.) + +W1: If an application has too few arguments, we must eta-expand. For + example, we transform `(+#) x` into `\y -> (+#) x y`. This happens + in maybeSaturate. + +W2: Perhaps surprisingly, an application of a primitive can have too + many arguments! This can make sense if the primitive returns a + function. Here's an example, from #22937: + + let arg3 = \s' f -> unIO f s' + arg4 = putStrLn "test" + in keepAlive# () s arg3 arg4 + + keepAlive# is a primop with arity 3, so we must apply it to its + first 3 arguments, and then apply the resulting function to the + remaining argument, as follows: + + let arg3 = \s' f -> unIO f s' + arg4 = putStrLn "test" + in case keepAlive# () s arg3 of fun { + __DEFAULT -> fun arg4 + }; + + We perform this transformation in rebuild_app. + Historical Note: Note that eta expansion in CorePrep used to be very fragile due to the "prediction" of CAFfyness that we used to make during tidying. -We previously saturated primop -applications here as well but due to this fragility (see #16846) we now deal -with this another way, as described in Note [Primop wrappers] in GHC.Builtin.PrimOps. -} maybeSaturate :: Id -> CpeApp -> Int -> [CoreTickish] -> UniqSM CpeRhs @@ -1769,19 +1808,6 @@ mkFloat env dmd is_unlifted bndr rhs -- Otherwise we get case (\x -> e) of ...! | is_unlifted = FloatCase rhs bndr DEFAULT [] True - -- we used to assertPpr ok_for_spec (ppr rhs) here, but it is now disabled - -- because exprOkForSpeculation isn't stable under ANF-ing. See for - -- example #19489 where the following unlifted expression: - -- - -- GHC.Prim.(#|_#) @LiftedRep @LiftedRep @[a_ax0] @[a_ax0] - -- (GHC.Types.: @a_ax0 a2_agq a3_agl) - -- - -- is ok-for-spec but is ANF-ised into: - -- - -- let sat = GHC.Types.: @a_ax0 a2_agq a3_agl - -- in GHC.Prim.(#|_#) @LiftedRep @LiftedRep @[a_ax0] @[a_ax0] sat - -- - -- which isn't ok-for-spec because of the let-expression. | is_hnf = FloatLet (NonRec bndr rhs) | otherwise = FloatLet (NonRec (setIdDemandInfo bndr dmd) rhs) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -1904,43 +1904,43 @@ Note [lazyId magic] lazy :: forall a. a -> a 'lazy' is used to make sure that a sub-expression, and its free variables, -are truly used call-by-need, with no code motion. Key examples: +are truly used call-by-need, with no code motion. Key example: * pseq: pseq a b = a `seq` lazy b We want to make sure that the free vars of 'b' are not evaluated before 'a', even though the expression is plainly strict in 'b'. - -* catch: catch a b = catch# (lazy a) b - Again, it's clear that 'a' will be evaluated strictly (and indeed - applied to a state token) but we want to make sure that any exceptions - arising from the evaluation of 'a' are caught by the catch (see - #11555). + *** This isn't especially robust. See #23233. Implementing 'lazy' is a bit tricky: -* It must not have a strictness signature: by being a built-in Id, - all the info about lazyId comes from here, not from GHC.Magic.hi. - This is important, because the strictness analyser will spot it as - strict! - -* It must not have an unfolding: it gets "inlined" by a HACK in - CorePrep. It's very important to do this inlining *after* unfoldings - are exposed in the interface file. Otherwise, the unfolding for - (say) pseq in the interface file will not mention 'lazy', so if we - inline 'pseq' we'll totally miss the very thing that 'lazy' was - there for in the first place. See #3259 for a real world - example. - -* Suppose CorePrep sees (catch# (lazy e) b). At all costs we must - avoid using call by value here: - case e of r -> catch# r b - Avoiding that is the whole point of 'lazy'. So in CorePrep (which - generate the 'case' expression for a call-by-value call) we must - spot the 'lazy' on the arg (in CorePrep.cpeApp), and build a 'let' - instead. - -* lazyId is defined in GHC.Base, so we don't *have* to inline it. If it - appears un-applied, we'll end up just calling it. +W1: It must not have a strictness signature: by being a built-in Id, + all the info about lazyId comes from here, not from GHC.Magic.hi. + This is important, because the strictness analyser will spot it as + strict! + +W2: It must not have an unfolding: it gets "inlined" by a HACK in + CorePrep. It's very important to do this inlining *after* unfoldings + are exposed in the interface file. Otherwise, the unfolding for + (say) pseq in the interface file will not mention 'lazy', so if we + inline 'pseq' we'll totally miss the very thing that 'lazy' was + there for in the first place. See #3259 for a real world + example. + +W3: Suppose CorePrep sees (catch# (lazy e) b). At all costs we must + avoid using call by value here: + case e of r -> catch# r b + Avoiding that is the whole point of 'lazy'. So in CorePrep (which + generate the 'case' expression for a call-by-value call) we must + spot the 'lazy' on the arg (in CorePrep.cpeApp), and build a 'let' + instead. + *** We wouldn't use call-by-value in this example anyway, since + catch# is no longer considered strict. (See primops.txt.pp + Note [Strictness for mask/unmask/catch]) This property of + lazy is news to me (clyring, Apr 2023). Is it documented + anywhere else? Is there any reason to keep it? + +W4: lazyId is defined in GHC.Magic, so we don't *have* to inline it. If it + appears un-applied, we'll end up just calling it. Note [noinlineId magic] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1982,7 +1982,7 @@ Wrinkles (W1) Sometimes case (2) above needs to apply `noinline` to a type of kind Constraint; e.g. noinline @(Eq Int) $dfEqInt - We don't have type-or-kind polymorphism, so we simply have two `inline` + We don't have type-or-kind polymorphism, so we simply have two `noinline` Ids, namely `noinlineId` and `noinlineConstraintId`. (W2) Note that noinline as currently implemented can hide some simplifications ===================================== testsuite/tests/core-to-stg/T22937.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE MagicHash #-} + +import GHC.Exts +import GHC.IO +import System.IO + +main :: IO () +main = do + IO $ \s -> keepAlive# () s (\s' f -> unIO f s') + (putStrLn "This should get printed.") + hFlush stdout ===================================== testsuite/tests/core-to-stg/T22937.stdout ===================================== @@ -0,0 +1 @@ +This should get printed. ===================================== testsuite/tests/core-to-stg/all.T ===================================== @@ -1,3 +1,4 @@ # Tests for CorePrep and CoreToStg test('T19700', normal, compile, ['-O']) +test('T22937', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1bd865bf1687628a087a6cf98d3137974be062aa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1bd865bf1687628a087a6cf98d3137974be062aa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 6 23:13:45 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 06 Apr 2023 19:13:45 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Maybe working now Message-ID: <642f5229dc879_3b00553a7d95085672c3@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 3017ff40 by Simon Peyton Jones at 2023-04-07T00:13:38+01:00 Maybe working now - - - - - 8 changed files: - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -387,9 +387,9 @@ extendTvSubstWithClone :: Subst -> TyVar -> TyVar -> Subst -- those variables should be in scope already extendTvSubstWithClone (Subst in_scope idenv tenv cenv) tv tv' = Subst (extendInScopeSet in_scope tv') - idenv - (extendVarEnv tenv tv (mkTyVarTy tv')) - cenv + idenv + (extendVarEnv tenv tv (mkTyVarTy tv')) + cenv -- | Add a substitution from a 'CoVar' to a 'Coercion' to the 'Subst': -- you must ensure that the in-scope set satisfies ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -5,7 +5,6 @@ module GHC.Tc.Solver.Canonical( canonicalize, - unifyWanted, makeSuperClasses, StopOrContinue(..), stopWith, continueWith, andWhenContinue, solveCallStack -- For GHC.Tc.Solver @@ -211,15 +210,13 @@ canClass ev cls tys pend_sc = -- all classes do *nominal* matching assertPpr (ctEvRole ev == Nominal) (ppr ev $$ ppr cls $$ ppr tys) $ do { (redns@(Reductions _ xis), rewriters) <- rewriteArgsNom ev cls_tc tys - ; let redn@(Reduction _ xi) = mkClassPredRedn cls redns - mk_ct new_ev = CDictCan { cc_ev = new_ev - , cc_tyargs = xis - , cc_class = cls - , cc_pend_sc = pend_sc } - ; mb <- rewriteEvidence rewriters ev redn - ; traceTcS "canClass" (vcat [ ppr ev - , ppr xi, ppr mb ]) - ; return (fmap mk_ct mb) } + ; let redn = mkClassPredRedn cls redns + ; rewriteEvidence rewriters ev redn $ \new_ev -> + do { traceTcS "canClass" (vcat [ ppr new_ev, ppr (reductionReducedType redn) ]) + ; continueWith (CDictCan { cc_ev = new_ev + , cc_tyargs = xis + , cc_class = cls + , cc_pend_sc = pend_sc }) }} where cls_tc = classTyCon cls @@ -738,7 +735,7 @@ canIrred ev = do { let pred = ctEvPred ev ; traceTcS "can_pred" (text "IrredPred = " <+> ppr pred) ; (redn, rewriters) <- rewrite ev pred - ; rewriteEvidence rewriters ev redn `andWhenContinue` \ new_ev -> + ; rewriteEvidence rewriters ev redn $ \ new_ev -> do { -- Re-classify, in case rewriting has improved its shape -- Code is like the canNC, except @@ -863,9 +860,8 @@ canForAll :: CtEvidence -> ExpansionFuel -> TcS (StopOrContinue Ct) -- We have a constraint (forall as. blah => C tys) canForAll ev fuel = do { -- First rewrite it to apply the current substitution - let pred = ctEvPred ev - ; (redn, rewriters) <- rewrite ev pred - ; rewriteEvidence rewriters ev redn `andWhenContinue` \ new_ev -> + ; (redn, rewriters) <- rewrite ev (ctEvPred ev) + ; rewriteEvidence rewriters ev redn $ \ new_ev -> do { -- Now decompose into its pieces and solve it -- (It takes a lot less code to rewrite before decomposing.) @@ -979,32 +975,29 @@ rewriteEvidence :: RewriterSet -- ^ See Note [Wanteds rewrite Wanteds] -- in GHC.Tc.Types.Constraint -> CtEvidence -- ^ old evidence -> Reduction -- ^ new predicate + coercion, of type ~ new predicate - -> TcS (StopOrContinue CtEvidence) --- Returns Just new_ev iff either (i) 'co' is reflexivity --- or (ii) 'co' is not reflexivity, and 'new_pred' not cached --- In either case, there is nothing new to do with new_ev -{- - rewriteEvidence old_ev new_pred co -Main purpose: create new evidence for new_pred; - unless new_pred is cached already -* Returns a new_ev : new_pred, with same wanted/given flag as old_ev -* If old_ev was wanted, create a binding for old_ev, in terms of new_ev -* If old_ev was given, AND not cached, create a binding for new_ev, in terms of old_ev -* Returns Nothing if new_ev is already cached - - Old evidence New predicate is Return new evidence - flavour of same flavor - ------------------------------------------------------------------- - Wanted Already solved or in inert Nothing - Not Just new_evidence - - Given Already in inert Nothing - Not Just new_evidence - -Note [Rewriting with Refl] -~~~~~~~~~~~~~~~~~~~~~~~~~~ + -> (CtEvidence -> TcS (StopOrContinue Ct)) + -> TcS (StopOrContinue Ct) +-- (rewriteEvidence old_ev new_pred co do_next) +-- Main purpose: create new evidence for new_pred; +-- unless new_pred is cached already +-- * Calls do_next with (new_ev :: new_pred), with same wanted/given flag as old_ev +-- * If old_ev was wanted, create a binding for old_ev, in terms of new_ev +-- * If old_ev was given, AND not cached, create a binding for new_ev, in terms of old_ev +-- * Stops if new_ev is already cached +-- +-- Old evidence New predicate is Return new evidence +-- flavour of same flavor +-- ------------------------------------------------------------------- +-- Wanted Already solved or in inert Stop +-- Not do_next new_evidence +-- +-- Given Already in inert Stop +-- Not do_next new_evidence + +{- Note [Rewriting with Refl] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the coercion is just reflexivity then you may re-use the same -variable. But be careful! Although the coercion is Refl, new_pred +evidence variable. But be careful! Although the coercion is Refl, new_pred may reflect the result of unification alpha := ty, so new_pred might not _look_ the same as old_pred, and it's vital to proceed from now on using new_pred. @@ -1017,16 +1010,16 @@ the rewriter set. We check this with an assertion. -} -rewriteEvidence rewriters old_ev (Reduction co new_pred) +rewriteEvidence rewriters old_ev (Reduction co new_pred) do_next | isReflCo co -- See Note [Rewriting with Refl] = assert (isEmptyRewriterSet rewriters) $ - continueWith (setCtEvPredType old_ev new_pred) + do_next (setCtEvPredType old_ev new_pred) rewriteEvidence rewriters ev@(CtGiven { ctev_evar = old_evar, ctev_loc = loc }) - (Reduction co new_pred) + (Reduction co new_pred) do_next = assert (isEmptyRewriterSet rewriters) $ -- this is a Given, not a wanted do { new_ev <- newGivenEvVar loc (new_pred, new_tm) - ; continueWith new_ev } + ; do_next new_ev } where -- mkEvCast optimises ReflCo new_tm = mkEvCast (evId old_evar) @@ -1036,14 +1029,14 @@ rewriteEvidence new_rewriters ev@(CtWanted { ctev_dest = dest , ctev_loc = loc , ctev_rewriters = rewriters }) - (Reduction co new_pred) + (Reduction co new_pred) do_next = do { mb_new_ev <- newWanted loc rewriters' new_pred ; massert (coercionRole co == ctEvRole ev) ; setWantedEvTerm dest IsCoherent $ mkEvCast (getEvExpr mb_new_ev) (downgradeRole Representational (ctEvRole ev) (mkSymCo co)) ; case mb_new_ev of - Fresh new_ev -> continueWith new_ev + Fresh new_ev -> do_next new_ev Cached _ -> stopWith ev "Cached wanted" } where rewriters' = rewriters S.<> new_rewriters ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -71,8 +71,10 @@ doTopReactDict inerts work_item@(CDictCan { cc_ev = ev, cc_class = cls _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies with -- the instance environment - do { doTopFundepImprovement work_item - ; tryLastResortProhibitedSuperclass inerts work_item } } + do { improved <- doTopFundepImprovement work_item + ; if improved + then startAgainWith work_item + else tryLastResortProhibitedSuperclass inerts work_item } } where dict_loc = ctEvLoc ev @@ -831,7 +833,7 @@ as the fundeps. #7875 is a case in point. -} -doTopFundepImprovement :: Ct -> TcS () +doTopFundepImprovement :: Ct -> TcS Bool -- Try to functional-dependency improvement between the constraint -- and the top-level instance declarations -- See Note [Fundeps with instances, and equality orientation] @@ -841,7 +843,7 @@ doTopFundepImprovement work_item@(CDictCan { cc_ev = ev, cc_class = cls = do { traceTcS "try_fundeps" (ppr work_item) ; instEnvs <- getInstEnvs ; let fundep_eqns = improveFromInstEnv instEnvs mk_ct_loc cls xis - ; emitFunDepWanteds (ctEvRewriters ev) fundep_eqns } + ; emitFunDepWanteds ev fundep_eqns } where dict_pred = mkClassPred cls xis dict_loc = ctEvLoc ev ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -651,11 +651,12 @@ can_eq_app :: CtEvidence -- :: s1 t1 ~N s2 t2 -- to an irreducible constraint; see typecheck/should_compile/T10494 -- See Note [Decomposing AppTy equalities] can_eq_app ev s1 t1 s2 t2 - | CtWanted { ctev_dest = dest, ctev_rewriters = rewriters } <- ev - = do { co_s <- unifyWanted rewriters loc Nominal s1 s2 - ; let arg_loc = adjustCtLoc (isNextArgVisible s1) False loc - ; co_t <- unifyWanted rewriters arg_loc Nominal t1 t2 - ; let co = mkAppCo co_s co_t + | CtWanted { ctev_dest = dest } <- ev + = do { (co,_) <- unifyWanteds ev Nominal $ \uenv -> + do { co_s <- uType uenv s1 s2 + ; let arg_env = updUEnvLoc uenv (adjustCtLoc (isNextArgVisible s1) False) + ; co_t <- uType arg_env t1 t2 + ; return (mkAppCo co_s co_t) } ; setWantedEq dest co ; stopWith ev "Decomposed [W] AppTy" } @@ -802,7 +803,7 @@ then we will just decompose s1~s2, and it might be better to do so on the spot. An important special case is where s1=s2, and we get just Refl. -So canDecomposableTyConAppOK uses unifyWanted etc to short-cut that work. +So canDecomposableTyConAppOK uses unifyWanteds etc to short-cut that work. See also Note [Decomposing Dependent TyCons and Processing Wanted Equalities] Note [Decomposing TyConApp equalities] @@ -1172,15 +1173,17 @@ canDecomposableTyConAppOK ev eq_rel tc tys1 tys2 do { traceTcS "canDecomposableTyConAppOK" (ppr ev $$ ppr eq_rel $$ ppr tc $$ ppr tys1 $$ ppr tys2) ; case ev of - CtWanted { ctev_dest = dest, ctev_rewriters = rewriters } + CtWanted { ctev_dest = dest } -- new_locs and tc_roles are both infinite, so -- we are guaranteed that cos has the same lengthm -- as tys1 and tys2 -- See Note [Fast path when decomposing TyConApps] -- Caution: unifyWanteds is order sensitive -- See Note [Decomposing Dependent TyCons and Processing Wanted Equalities] - -> do { cos <- unifyWanteds rewriters new_locs tc_roles tys1 tys2 - ; setWantedEq dest (mkTyConAppCo role tc cos) } + -> do { (co, _) <- unifyWanteds ev role $ \uenv -> + do { cos <- zipWith4M (u_arg uenv) new_locs tc_roles tys1 tys2 + ; return (mkTyConAppCo role tc cos) } + ; setWantedEq dest co } CtGiven { ctev_evar = evar } -> do { let ev_co = mkCoVarCo evar @@ -1198,6 +1201,11 @@ canDecomposableTyConAppOK ev eq_rel tc tys1 tys2 loc = ctEvLoc ev role = eqRelRole eq_rel + u_arg uenv arg_loc arg_role = uType arg_env + where + arg_env = uenv `setUEnvRole` arg_role + `updUEnvLoc` const arg_loc + -- Infinite, to allow for over-saturated TyConApps tc_roles = tyConRoleListX role tc @@ -1223,11 +1231,15 @@ canDecomposableFunTy ev eq_rel af f1@(m1,a1,r1) f2@(m2,a2,r2) = do { traceTcS "canDecomposableFunTy" (ppr ev $$ ppr eq_rel $$ ppr f1 $$ ppr f2) ; case ev of - CtWanted { ctev_dest = dest, ctev_rewriters = rewriters } - -> do { mult <- unifyWanted rewriters mult_loc (funRole role SelMult) m1 m2 - ; arg <- unifyWanted rewriters loc (funRole role SelArg) a1 a2 - ; res <- unifyWanted rewriters loc (funRole role SelRes) r1 r2 - ; setWantedEq dest (mkNakedFunCo1 role af mult arg res) } + CtWanted { ctev_dest = dest } + -> do { (co, _) <- unifyWanteds ev Nominal $ \ uenv -> + do { let mult_env = uenv `updUEnvLoc` toInvisibleLoc + `setUEnvRole` funRole role SelMult + ; mult <- uType mult_env m1 m2 + ; arg <- uType (uenv `setUEnvRole` funRole role SelArg) a1 a2 + ; res <- uType (uenv `setUEnvRole` funRole role SelRes) r1 r2 + ; return (mkNakedFunCo1 role af mult arg res) } + ; setWantedEq dest co } CtGiven { ctev_evar = evar } -> do { let ev_co = mkCoVarCo evar @@ -1243,9 +1255,8 @@ canDecomposableFunTy ev eq_rel af f1@(m1,a1,r1) f2@(m2,a2,r2) ; stopWith ev "Decomposed TyConApp" } where - loc = ctEvLoc ev - role = eqRelRole eq_rel - mult_loc = updateCtLocOrigin loc toInvisibleOrigin + loc = ctEvLoc ev + role = eqRelRole eq_rel -- | Call when canonicalizing an equality fails, but if the equality is -- representational, there is some hope for the future. @@ -1549,46 +1560,13 @@ canEqCanLHS2 ev eq_rel swapped lhs1 ps_xi1 lhs2 ps_xi2 mco -- See Note [Decomposing type family applications] = do { traceTcS "canEqCanLHS2 two type families" (ppr lhs1 $$ ppr lhs2) - -- emit wanted equalities for injective type families - ; let inj_eqns :: [TypeEqn] -- TypeEqn = Pair Type - inj_eqns - | ReprEq <- eq_rel = [] -- injectivity applies only for nom. eqs. - | fun_tc1 /= fun_tc2 = [] -- if the families don't match, stop. - - | Injective inj <- tyConInjectivityInfo fun_tc1 - = [ Pair arg1 arg2 - | (arg1, arg2, True) <- zip3 fun_args1 fun_args2 inj ] - - -- built-in synonym families don't have an entry point - -- for this use case. So, we just use sfInteractInert - -- and pass two equal RHSs. We *could* add another entry - -- point, but then there would be a burden to make - -- sure the new entry point and existing ones were - -- internally consistent. This is slightly distasteful, - -- but it works well in practice and localises the - -- problem. - | Just ops <- isBuiltInSynFamTyCon_maybe fun_tc1 - = let ki1 = canEqLHSKind lhs1 - ki2 | MRefl <- mco - = ki1 -- just a small optimisation - | otherwise - = canEqLHSKind lhs2 - - fake_rhs1 = anyTypeOfKind ki1 - fake_rhs2 = anyTypeOfKind ki2 - in - sfInteractInert ops fun_args1 fake_rhs1 fun_args2 fake_rhs2 - - | otherwise -- ordinary, non-injective type family - = [] - - ; case ev of - CtWanted { ctev_rewriters = rewriters } -> - mapM_ (\ (Pair t1 t2) -> unifyWanted rewriters (ctEvLoc ev) Nominal t1 t2) inj_eqns - CtGiven {} -> return () - -- See Note [No Given/Given fundeps] in GHC.Tc.Solver.Interact - - ; tclvl <- getTcLevel + ; unifications_done <- tryFamFamInjectivity ev eq_rel + fun_tc1 fun_args1 fun_tc2 fun_args2 mco + ; if unifications_done + then -- Go round again, since the unifications affect lhs/rhs + startAgainWith (mkNonCanonical ev) + else + do { tclvl <- getTcLevel ; let tvs1 = tyCoVarsOfTypes fun_args1 tvs2 = tyCoVarsOfTypes fun_args2 @@ -1603,7 +1581,7 @@ canEqCanLHS2 ev eq_rel swapped lhs1 ps_xi1 lhs2 ps_xi2 mco ; if swap_for_rewriting || swap_for_size then finish_with_swapping - else finish_without_swapping } + else finish_without_swapping } } where sym_mco = mkSymMCo mco role = eqRelRole eq_rel @@ -2138,7 +2116,7 @@ in `GHC.Tc.Solver.Monad.checkTouchableTyVarEq`. Why TauTvs? See [Why TauTvs] below. Critically, we emit the two new constraints (the last two above) -directly instead of calling unifyWanted. (Otherwise, we'd end up +directly instead of calling unifyWanteds. (Otherwise, we'd end up unifying cbv1 and cbv2 immediately, achieving nothing.) Next, we unify alpha := cbv1 -> cbv2, having eliminated the occurs check. This unification happens immediately following a successful call to @@ -2472,9 +2450,11 @@ interactEq work_item@(EqCt { eq_lhs = lhs, eq_ev = ev, eq_eq_rel = eq_rel }) | otherwise -> case lhs of TyVarLHS {} -> finishEqCt work_item - TyFamLHS tc args -> do { improveLocalFunEqs inerts tc args work_item - ; improveTopFunEqs tc args work_item - ; finishEqCt work_item } } + TyFamLHS tc args -> do { imp1 <- improveLocalFunEqs inerts tc args work_item + ; imp2 <- improveTopFunEqs tc args work_item + ; if (imp1 || imp2) + then startAgainWith (mkNonCanonical ev) + else finishEqCt work_item } } inertsCanDischarge :: InertCans -> EqCt @@ -2695,7 +2675,7 @@ Of course, if we solve the first wanted first, the second becomes homogeneous. When looking for injectivity-inspired equalities, we work left-to-right, producing the two equalities in the order written above. However, these -equalities are then passed into unifyWanted, which will fail, adding these +equalities are then passed into unifyWanteds, which will fail, adding these to the work list. However, crucially, the work list operates like a *stack*. So, because we add w1 and then w2, we process w2 first. This is silly: solving w1 would unlock w2. So we make sure to add equalities to the work @@ -2753,28 +2733,72 @@ equality with the template on the left. Delicate, but it works. -} +tryFamFamInjectivity :: CtEvidence -> EqRel + -> TyCon -> [TcType] -> TyCon -> [TcType] -> MCoercion + -> TcS Bool -- True <=> some unification happened +tryFamFamInjectivity ev eq_rel fun_tc1 fun_args1 fun_tc2 fun_args2 mco + | ReprEq <- eq_rel + = return False -- Injectivity applies only for Nominal equalities + | fun_tc1 /= fun_tc2 + = return False -- If the families don't match, stop. + | isGiven ev + = return False -- See Note [No Given/Given fundeps] in GHC.Tc.Solver.Interact + + -- So this is a [W] (F tys1 ~N# F tys2) + + -- Is F an injective type family + | Injective inj <- tyConInjectivityInfo fun_tc1 + = unifyFunDeps ev Nominal $ \uenv -> + uPairsTcM uenv [ Pair ty1 ty2 + | (ty1,ty2,True) <- zip3 fun_args1 fun_args2 inj ] + + -- Built-in synonym families don't have an entry point for this + -- use case. So, we just use sfInteractInert and pass two equal + -- RHSs. We *could* add another entry point, but then there would + -- be a burden to make sure the new entry point and existing ones + -- were internally consistent. This is slightly distasteful, but + -- it works well in practice and localises the problem. Ugh. + | Just ops <- isBuiltInSynFamTyCon_maybe fun_tc1 + = let tc_kind = tyConKind fun_tc1 + ki1 = piResultTys tc_kind fun_args1 + ki2 | MRefl <- mco + = ki1 -- just a small optimisation + | otherwise + = piResultTys tc_kind fun_args2 + + fake_rhs1 = anyTypeOfKind ki1 + fake_rhs2 = anyTypeOfKind ki2 + + eqs :: [TypeEqn] + eqs = sfInteractInert ops fun_args1 fake_rhs1 fun_args2 fake_rhs2 + in + unifyFunDeps ev Nominal $ \uenv -> + uPairsTcM uenv eqs + + | otherwise -- ordinary, non-injective type family + = return False + -------------------- -improveTopFunEqs :: TyCon -> [TcType] -> EqCt -> TcS () +improveTopFunEqs :: TyCon -> [TcType] -> EqCt -> TcS Bool -- See Note [FunDep and implicit parameter reactions] improveTopFunEqs fam_tc args (EqCt { eq_ev = ev, eq_rhs = rhs }) - - | isGiven ev = return () -- See Note [No Given/Given fundeps] + | isGiven ev + = return False -- See Note [No Given/Given fundeps] | otherwise = do { fam_envs <- getFamInstEnvs ; eqns <- improve_top_fun_eqs fam_envs fam_tc args rhs ; traceTcS "improveTopFunEqs" (vcat [ ppr fam_tc <+> ppr args <+> ppr rhs - , ppr eqns ]) - ; mapM_ (\(Pair ty1 ty2) -> unifyWanted rewriters loc Nominal ty1 ty2) - (reverse eqns) } + , ppr eqns ]) + ; unifyFunDeps ev Nominal $ \uenv -> + uPairsTcM (bump_depth uenv) (reverse eqns) } -- Missing that `reverse` causes T13135 and T13135_simple to loop. -- See Note [Reverse order of fundep equations] where - loc = bumpCtLocDepth (ctEvLoc ev) + bump_depth env = env { u_loc = bumpCtLocDepth (u_loc env) } -- ToDo: this location is wrong; it should be FunDepOrigin2 -- See #14778 - rewriters = ctEvRewriters ev improve_top_fun_eqs :: FamInstEnvs -> TyCon -> [TcType] -> TcType @@ -2852,19 +2876,21 @@ improve_top_fun_eqs fam_envs fam_tc args rhs_ty , (ax_arg, arg, True) <- zip3 ax_args args inj_args ] } -improveLocalFunEqs :: InertCans -> TyCon -> [TcType] -> EqCt -> TcS () +improveLocalFunEqs :: InertCans -> TyCon -> [TcType] -> EqCt -> TcS Bool -- Generate improvement equalities, by comparing -- the current work item with inert CFunEqs -- E.g. x + y ~ z, x + y' ~ z => [W] y ~ y' -- -- See Note [FunDep and implicit parameter reactions] improveLocalFunEqs inerts fam_tc args (EqCt { eq_ev = work_ev, eq_rhs = rhs }) - = unless (null improvement_eqns) $ - do { traceTcS "interactFunEq improvements: " $ + | null improvement_eqns + = return False + | otherwise + = do { traceTcS "interactFunEq improvements: " $ vcat [ text "Eqns:" <+> ppr improvement_eqns , text "Candidates:" <+> ppr funeqs_for_tc , text "Inert eqs:" <+> ppr (inert_eqs inerts) ] - ; emitFunDepWanteds (ctEvRewriters work_ev) improvement_eqns } + ; emitFunDepWanteds work_ev improvement_eqns } where funeqs = inert_funeqs inerts funeqs_for_tc :: [EqCt] ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -308,7 +308,7 @@ runSolverPipeline :: [(String,SimplifierStage)] -- The pipeline -> WorkItem -- The work item -> TcS () -- Run this item down the pipeline, leaving behind new work and inerts -runSolverPipeline pipeline workItem +runSolverPipeline full_pipeline workItem = do { wl <- getWorkList ; inerts <- getTcSInerts ; tclevel <- getTcLevel @@ -320,7 +320,7 @@ runSolverPipeline pipeline workItem , text "rest of worklist =" <+> ppr wl ] ; bumpStepCountTcS -- One step for each constraint processed - ; final_res <- run_pipeline pipeline (ContinueWith workItem) + ; final_res <- run_pipeline full_pipeline workItem ; case final_res of Stop ev s -> do { traceFireTcS ev s @@ -330,26 +330,29 @@ runSolverPipeline pipeline workItem ; traceFireTcS (ctEvidence ct) (text "Kept as inert") ; traceTcS "End solver pipeline (kept as inert) }" $ (text "final_item =" <+> ppr ct) } + StartAgain ct -> pprPanic "runSolverPipeline: StartAgain" (ppr ct) } - where run_pipeline :: [(String,SimplifierStage)] -> StopOrContinue Ct - -> TcS (StopOrContinue Ct) - run_pipeline [] res = return res - run_pipeline _ (Stop ev s) = return (Stop ev s) - run_pipeline ((stg_name,stg):stgs) (ContinueWith ct) - = do { traceTcS ("runStage " ++ stg_name ++ " {") - (text "workitem = " <+> ppr ct) - ; res <- stg ct - ; traceTcS ("end stage " ++ stg_name ++ " }") empty - ; run_pipeline stgs res } + where + run_pipeline :: [(String,SimplifierStage)] -> Ct -> TcS (StopOrContinue Ct) + run_pipeline [] ct = return (ContinueWith ct) + run_pipeline ((stage_name,stage):stages) ct + = do { traceTcS ("runStage " ++ stage_name ++ " {") + (text "workitem = " <+> ppr ct) + ; res <- stage ct + ; traceTcS ("end stage " ++ stage_name ++ " }") (ppr res) + ; case res of + Stop {} -> return res + StartAgain ct -> run_pipeline full_pipeline ct + ContinueWith ct -> run_pipeline stages ct } {- Example 1: Inert: {c ~ d, F a ~ t, b ~ Int, a ~ ty} (all given) Reagent: a ~ [b] (given) -React with (c~d) ==> IR (ContinueWith (a~[b])) True [] -React with (F a ~ t) ==> IR (ContinueWith (a~[b])) False [F [b] ~ t] -React with (b ~ Int) ==> IR (ContinueWith (a~[Int]) True [] +React with (c~d) ==> IR (ContinueWith (a~[b])) True [] +React with (F a ~ t) ==> IR (ContinueWith (a~[b])) False [F [b] ~ t] +React with (b ~ Int) ==> IR (ContinueWith (a~[Int])) True [] Example 2: Inert: {c ~w d, F a ~g t, b ~w Int, a ~w ty} @@ -1025,8 +1028,10 @@ interactDict inerts ct_w@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs = t = interactGivenIP inerts ct_w | otherwise - = do { addFunDepWork inerts ev_w cls - ; continueWith ct_w } + = do { unif_happened <- addFunDepWork inerts ev_w cls + ; if unif_happened + then startAgainWith ct_w + else continueWith ct_w } interactDict _ wi = pprPanic "interactDict" (ppr wi) @@ -1131,30 +1136,36 @@ shortCutSolver dflags ev_w ev_i Nothing -> Fresh <$> newWantedNC loc (ctEvRewriters ev_w) pty | otherwise = mzero -addFunDepWork :: InertCans -> CtEvidence -> Class -> TcS () +addFunDepWork :: InertCans -> CtEvidence -> Class -> TcS Bool -- Add wanted constraints from type-class functional dependencies. addFunDepWork inerts work_ev cls - = mapBagM_ add_fds (findDictsByClass (inert_dicts inerts) cls) - -- No need to check flavour; fundeps work between - -- any pair of constraints, regardless of flavour - -- Importantly we don't throw workitem back in the - -- worklist because this can cause loops (see #5236) + = foldlM add_fds False (findDictsByClass (inert_dicts inerts) cls) + -- No need to check flavour; fundeps work between + -- any pair of constraints, regardless of flavour + -- Importantly we don't throw workitem back in the + -- worklist because this can cause loops (see #5236) where work_pred = ctEvPred work_ev work_loc = ctEvLoc work_ev - add_fds inert_ct + add_fds :: Bool -> Ct -> TcS Bool + add_fds so_far inert_ct + | isGiven work_ev && isGiven inert_ev + -- Do not create FDs from Given/Given interactions: See Note [No Given/Given fundeps] + = return so_far + | otherwise = do { traceTcS "addFunDepWork" (vcat [ ppr work_ev , pprCtLoc work_loc, ppr (isGivenLoc work_loc) , pprCtLoc inert_loc, ppr (isGivenLoc inert_loc) , pprCtLoc derived_loc, ppr (isGivenLoc derived_loc) ]) - ; unless (isGiven work_ev && isGiven inert_ev) $ - emitFunDepWanteds (ctEvRewriters work_ev) $ - improveFromAnother (derived_loc, inert_rewriters) inert_pred work_pred - -- We don't really rewrite tys2, see below _rewritten_tys2, so that's ok - -- Do not create FDs from Given/Given interactions: See Note [No Given/Given fundeps] + ; unifs <- emitFunDepWanteds work_ev $ + improveFromAnother (derived_loc, inert_rewriters) + inert_pred work_pred + -- We don't really rewrite tys2, see below + -- _rewritten_tys2, so that's ok + ; return (so_far || unifs) } where inert_ev = ctEvidence inert_ct ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -33,6 +33,7 @@ module GHC.Tc.Solver.Monad ( -- The pipeline StopOrContinue(..), continueWith, stopWith, andWhenContinue, + startAgainWith, -- Tracing etc panicTcS, traceTcS, @@ -94,7 +95,7 @@ module GHC.Tc.Solver.Monad ( instDFunType, -- Unification - unifyWanted, unifyWanteds, + unifyWanteds, unifyFunDeps, uPairsTcM, -- MetaTyVars newFlexiTcSTy, instFlexiX, @@ -154,6 +155,7 @@ import GHC.Tc.Utils.Unify import GHC.Core.Type import GHC.Core.TyCo.Rep as Rep import GHC.Core.Coercion +import GHC.Core.Coercion.Axiom( TypeEqn ) import GHC.Core.Predicate import GHC.Core.Reduction import GHC.Core.Class @@ -183,7 +185,7 @@ import GHC.Utils.Monad import GHC.Exts (oneShot) import Control.Monad import Data.IORef -import Data.List ( mapAccumL, zip4 ) +import Data.List ( mapAccumL ) import Data.Foldable import qualified Data.Semigroup as S @@ -199,7 +201,10 @@ import GHC.Data.Graph.Directed ********************************************************************* -} data StopOrContinue a - = ContinueWith a -- The constraint was not solved, although it may have + = StartAgain a -- Constraint is not solved, but some unifications + -- happened, so go back to the beginning of the pipeline + + | ContinueWith a -- The constraint was not solved, although it may have -- been rewritten | Stop CtEvidence -- The (rewritten) constraint was solved @@ -210,21 +215,25 @@ data StopOrContinue a instance Outputable a => Outputable (StopOrContinue a) where ppr (Stop ev s) = text "Stop" <> parens s <+> ppr ev ppr (ContinueWith w) = text "ContinueWith" <+> ppr w + ppr (StartAgain w) = text "StartAgain" <+> ppr w + +startAgainWith :: a -> TcS (StopOrContinue a) +startAgainWith ct = return (StartAgain ct) continueWith :: a -> TcS (StopOrContinue a) -continueWith = return . ContinueWith +continueWith ct = return (ContinueWith ct) stopWith :: CtEvidence -> String -> TcS (StopOrContinue a) stopWith ev s = return (Stop ev (text s)) andWhenContinue :: TcS (StopOrContinue a) - -> (a -> TcS (StopOrContinue b)) - -> TcS (StopOrContinue b) + -> (a -> TcS (StopOrContinue a)) + -> TcS (StopOrContinue a) andWhenContinue tcs1 tcs2 = do { r <- tcs1 ; case r of - Stop ev s -> return (Stop ev s) - ContinueWith ct -> tcs2 ct } + ContinueWith ct -> tcs2 ct + _ -> return r } infixr 0 `andWhenContinue` -- allow chaining with ($) @@ -1610,20 +1619,22 @@ cloneMetaTyVar :: TcTyVar -> TcS TcTyVar cloneMetaTyVar tv = wrapTcS (TcM.cloneMetaTyVar tv) instFlexiX :: Subst -> [TKVar] -> TcS Subst -instFlexiX subst tvs - = wrapTcS (foldlM instFlexiHelper subst tvs) +instFlexiX subst tvs = wrapTcS (instFlexiXTcM subst tvs) -instFlexiHelper :: Subst -> TKVar -> TcM Subst +instFlexiXTcM :: Subst -> [TKVar] -> TcM Subst -- Makes fresh tyvar, extends the substitution, and the in-scope set -instFlexiHelper subst tv +-- Takes account of the case [k::Type, a::k, ...], +-- where we must substitute for k in a's kind +instFlexiXTcM subst [] + = return subst +instFlexiXTcM subst (tv:tvs) = do { uniq <- TcM.newUnique ; details <- TcM.newMetaDetails TauTv ; let name = setNameUnique (tyVarName tv) uniq kind = substTyUnchecked subst (tyVarKind tv) tv' = mkTcTyVar name kind details subst' = extendTvSubstWithClone subst tv tv' - ; TcM.traceTc "instFlexi" (ppr tv') - ; return (extendTvSubst subst' tv (mkTyVarTy tv')) } + ; instFlexiXTcM subst' tvs } matchGlobalInst :: DynFlags -> Bool -- True <=> caller is the short-cut solver @@ -1889,43 +1900,47 @@ solverDepthError loc ty ************************************************************************ -} -emitFunDepWanteds :: RewriterSet -- from the work item - -> [FunDepEqn (CtLoc, RewriterSet)] -> TcS () +emitFunDepWanteds :: CtEvidence -- The work item + -> [FunDepEqn (CtLoc, RewriterSet)] + -> TcS Bool -- True <=> some unification happened -emitFunDepWanteds _ [] = return () -- common case noop +emitFunDepWanteds _ [] = return False -- common case noop -- See Note [FunDep and implicit parameter reactions] -emitFunDepWanteds work_rewriters fd_eqns - = mapM_ do_one_FDEqn fd_eqns +emitFunDepWanteds ev fd_eqns + = unifyFunDeps ev Nominal do_fundeps where - do_one_FDEqn (FDEqn { fd_qtvs = tvs, fd_eqs = eqs, fd_loc = (loc, rewriters) }) - | null tvs -- Common shortcut - = do { traceTcS "emitFunDepWanteds 1" (ppr (ctl_depth loc) $$ ppr eqs $$ ppr (isGivenLoc loc)) - ; mapM_ (\(Pair ty1 ty2) -> unifyWanted all_rewriters loc Nominal ty1 ty2) - (reverse eqs) } - -- See Note [Reverse order of fundep equations] - - | otherwise - = do { traceTcS "emitFunDepWanteds 2" (ppr (ctl_depth loc) $$ ppr tvs $$ ppr eqs) - ; subst <- instFlexiX emptySubst tvs -- Takes account of kind substitution - ; mapM_ (do_one_eq loc all_rewriters subst) (reverse eqs) } - -- See Note [Reverse order of fundep equations] - where - all_rewriters = work_rewriters S.<> rewriters - - do_one_eq loc rewriters subst (Pair ty1 ty2) - = unifyWanted rewriters loc Nominal (substTyUnchecked subst' ty1) ty2 - -- ty2 does not mention fd_qtvs, so no need to subst it. - -- See GHC.Tc.Instance.Fundeps Note [Improving against instances] - -- Wrinkle (1) + do_fundeps :: UnifyEnv -> TcM () + do_fundeps env = mapM_ (do_one env) fd_eqns + + do_one :: UnifyEnv -> FunDepEqn (CtLoc, RewriterSet) -> TcM () + do_one uenv (FDEqn { fd_qtvs = tvs, fd_eqs = eqs, fd_loc = (loc, rewriters) }) + = do { eqs' <- instantiate_eqs tvs (reverse eqs) + -- (reverse eqs): See Note [Reverse order of fundep equations] + ; uPairsTcM env_one eqs' } where - subst' = extendSubstInScopeSet subst (tyCoVarsOfType ty1) - -- The free vars of ty1 aren't just fd_qtvs: ty1 is the result - -- of matching with the [W] constraint. So we add its free - -- vars to InScopeSet, to satisfy substTy's invariants, even - -- though ty1 will never (currently) be a poytype, so this - -- InScopeSet will never be looked at. + env_one = uenv { u_rewriters = u_rewriters uenv S.<> rewriters + , u_loc = loc } + instantiate_eqs :: [TyVar] -> [TypeEqn] -> TcM [TypeEqn] + instantiate_eqs tvs eqs + | null tvs + = return eqs + | otherwise + = do { TcM.traceTc "emitFunDepWanteds 2" (ppr tvs $$ ppr eqs) + ; subst <- instFlexiXTcM emptySubst tvs -- Takes account of kind substitution + ; return [ Pair (substTyUnchecked subst' ty1) ty2 + -- ty2 does not mention fd_qtvs, so no need to subst it. + -- See GHC.Tc.Instance.Fundeps Note [Improving against instances] + -- Wrinkle (1) + | Pair ty1 ty2 <- eqs + , let subst' = extendSubstInScopeSet subst (tyCoVarsOfType ty1) ] + -- The free vars of ty1 aren't just fd_qtvs: ty1 is the result + -- of matching with the [W] constraint. So we add its free + -- vars to InScopeSet, to satisfy substTy's invariants, even + -- though ty1 will never (currently) be a poytype, so this + -- InScopeSet will never be looked at. + } {- ************************************************************************ @@ -1934,38 +1949,55 @@ emitFunDepWanteds work_rewriters fd_eqns * * ************************************************************************ -Note [unifyWanted] -~~~~~~~~~~~~~~~~~~ +Note [unifyWanteds] +~~~~~~~~~~~~~~~~~~~ When decomposing equalities we often create new wanted constraints for (s ~ t). But what if s=t? Then it'd be faster to return Refl right away. -Rather than making an equality test (which traverses the structure of the -type, perhaps fruitlessly), unifyWanted traverses the common structure, and -bales out when it finds a difference by creating a new Wanted constraint. -But where it succeeds in finding common structure, it just builds a coercion -to reflect it. --} +Rather than making an equality test (which traverses the structure of +the type, perhaps fruitlessly), unifyWanteds calls uType to traverse +the common structure, and bales out when it finds a difference by +creating a new Wanted constraint. But where it succeeds in finding +common structure, it just builds a coercion to reflect it. -} + -unifyWanted :: RewriterSet -> CtLoc - -> Role -> TcType -> TcType -> TcS Coercion --- Return coercion witnessing the equality of the two types, +uPairsTcM :: UnifyEnv -> [TypeEqn] -> TcM () +uPairsTcM uenv eqns = mapM_ (\(Pair ty1 ty2) -> uType uenv ty1 ty2) eqns + +unifyFunDeps :: CtEvidence -> Role + -> (UnifyEnv -> TcM ()) + -> TcS Bool +unifyFunDeps ev role do_unifications + = do { (_, unified) <- unifyWanteds ev role do_unifications + ; return (not (null unified)) } + +unifyWanteds :: CtEvidence -> Role + -> (UnifyEnv -> TcM a) + -> TcS (a, [TcTyVar]) +-- Return coercions witnessing the equality of the two types, -- emitting new work equalities where necessary to achieve that -- Very good short-cut when the two types are equal, or nearly so -- See Note [unifyWanted] -- The returned coercion's role matches the input parameter +-- +-- The [TcTyVar] is the list of unification variables +-- that were unified the process. -unifyWanted _rewriters loc role ty1 ty2 - = do { (co, unified, cts) <- wrapTcS $ +unifyWanteds ev role do_unifications + = do { (cos, unified, cts) <- wrapTcS $ do { defer_ref <- TcM.newTcRef [] ; unified_ref <- TcM.newTcRef [] - ; let env = UE { u_role = role - , u_loc = loc - , u_defer = defer_ref - , u_unified = Just unified_ref} - ; co <- uType env ty1 ty2 - ; cts <- TcM.readTcRef defer_ref + ; let env = UE { u_role = role + , u_rewriters = ctEvRewriters ev + , u_loc = ctEvLoc ev + , u_defer = defer_ref + , u_unified = Just unified_ref} + + ; cos <- do_unifications env + + ; cts <- TcM.readTcRef defer_ref ; unified <- TcM.readTcRef unified_ref - ; return (co, unified, cts) } + ; return (cos, unified, cts) } -- Emit the deferred constraints ; updWorkListTcS (extendWorkListEqs cts) @@ -1975,58 +2007,10 @@ unifyWanted _rewriters loc role ty1 ty2 -- be more efficient than one by one ; mapM_ kickOutAfterUnification unified - ; return co } + ; return (cos, unified) } -{- -unifyWanted rewriters loc Phantom ty1 ty2 - = do { kind_co <- unifyWanted rewriters loc Nominal (typeKind ty1) (typeKind ty2) - ; return (mkPhantomCo kind_co ty1 ty2) } - -unifyWanted rewriters loc role orig_ty1 orig_ty2 - = go orig_ty1 orig_ty2 - where - go ty1 ty2 | Just ty1' <- coreView ty1 = go ty1' ty2 - go ty1 ty2 | Just ty2' <- coreView ty2 = go ty1 ty2' - - go (FunTy af1 w1 s1 t1) (FunTy af2 w2 s2 t2) - | af1 == af2 -- Important! See #21530 - = do { co_s <- unifyWanted rewriters loc role s1 s2 - ; co_t <- unifyWanted rewriters loc role t1 t2 - ; co_w <- unifyWanted rewriters loc Nominal w1 w2 - ; return (mkNakedFunCo1 role af1 co_w co_s co_t) } - - go (TyConApp tc1 tys1) (TyConApp tc2 tys2) - | tc1 == tc2, tys1 `equalLength` tys2 - , isInjectiveTyCon tc1 role -- don't look under newtypes at Rep equality - = do { cos <- zipWith3M (unifyWanted rewriters loc) - (tyConRoleListX role tc1) tys1 tys2 - ; return (mkTyConAppCo role tc1 cos) } - - go ty1@(TyVarTy tv) ty2 - = do { mb_ty <- isFilledMetaTyVar_maybe tv - ; case mb_ty of - Just ty1' -> go ty1' ty2 - Nothing -> bale_out ty1 ty2} - go ty1 ty2@(TyVarTy tv) - = do { mb_ty <- isFilledMetaTyVar_maybe tv - ; case mb_ty of - Just ty2' -> go ty1 ty2' - Nothing -> bale_out ty1 ty2 } - - go ty1@(CoercionTy {}) (CoercionTy {}) - = return (mkReflCo role ty1) -- we just don't care about coercions! - - go ty1 ty2 = bale_out ty1 ty2 - - bale_out ty1 ty2 - | ty1 `tcEqType` ty2 = return (mkReflCo role ty1) - -- Check for equality; e.g. a ~ a, or (m a) ~ (m a) - | otherwise = emitNewWantedEq loc rewriters role orig_ty1 orig_ty2 --} - -{- -Note [Decomposing Dependent TyCons and Processing Wanted Equalities] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Decomposing Dependent TyCons and Processing Wanted Equalities] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When we decompose a dependent tycon we obtain a list of mixed wanted type and kind equalities. Ideally we want all the kind equalities to get solved first so that we avoid @@ -2059,21 +2043,6 @@ This is exactly what we do in `unifyWanteds`. NB: This ordering is not needed when we decompose FunTyCons as they are not dependently typed -} --- NB: Length of [CtLoc] and [Roles] may be infinite --- but list of RHS [TcType] and LHS [TcType] is finite and both are of equal length -unifyWanteds :: RewriterSet -> [CtLoc] -> [Role] - -> [TcType] -- List of RHS types - -> [TcType] -- List of LHS types - -> TcS [Coercion] -unifyWanteds rewriters ctlocs roles rhss lhss = unify_wanteds rewriters $ zip4 ctlocs roles rhss lhss - where - -- Order is important here - -- See Note [Decomposing Dependent TyCons and Processing Wanted Equalities] - unify_wanteds _ [] = return [] - unify_wanteds rewriters ((new_loc, tc_role, ty1, ty2) : rest) - = do { cos <- unify_wanteds rewriters rest - ; co <- unifyWanted rewriters new_loc tc_role ty1 ty2 - ; return (co:cos) } {- ************************************************************************ ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -71,7 +71,7 @@ module GHC.Tc.Types.Constraint ( -- CtEvidence CtEvidence(..), TcEvDest(..), - mkKindLoc, toKindLoc, mkGivenLoc, + mkKindLoc, toKindLoc, toInvisibleLoc, mkGivenLoc, isWanted, isGiven, ctEvRole, setCtEvPredType, setCtEvLoc, arisesFromGivens, tyCoVarsOfCtEvList, tyCoVarsOfCtEv, tyCoVarsOfCtEvsList, @@ -2429,13 +2429,16 @@ adjustCtLoc is_invis is_kind loc where loc1 | is_kind = toKindLoc loc | otherwise = loc - loc2 | is_invis = updateCtLocOrigin loc1 toInvisibleOrigin + loc2 | is_invis = toInvisibleLoc loc1 | otherwise = loc1 -- | Take a CtLoc and moves it to the kind level toKindLoc :: CtLoc -> CtLoc toKindLoc loc = loc { ctl_t_or_k = Just KindLevel } +toInvisibleLoc :: CtLoc -> CtLoc +toInvisibleLoc loc = updateCtLocOrigin loc toInvisibleOrigin + mkGivenLoc :: TcLevel -> SkolemInfoAnon -> TcLclEnv -> CtLoc mkGivenLoc tclvl skol_info env = CtLoc { ctl_origin = GivenOrigin skol_info ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -23,7 +23,8 @@ module GHC.Tc.Utils.Unify ( unifyType, unifyKind, unifyExpectedType, uTypeAndEmit, promoteTcType, swapOverTyVars, touchabilityAndShapeTest, - UnifyEnv(..), uType, + UnifyEnv(..), updUEnvLoc, setUEnvRole, + uType, -------------------------------- -- Holes @@ -1746,6 +1747,7 @@ uTypeAndEmit t_or_k orig ty1 ty2 = do { ref <- newTcRef [] ; loc <- getCtLocM orig (Just t_or_k) ; let env = UE { u_loc = loc, u_role = Nominal + , u_rewriters = emptyRewriterSet -- ToDo: check this , u_defer = ref, u_unified = Nothing } -- The hard work happens here @@ -1766,16 +1768,24 @@ uType is the heart of the unifier. -} data UnifyEnv - = UE { u_role :: Role - , u_loc :: CtLoc + = UE { u_role :: Role + , u_loc :: CtLoc + , u_rewriters :: RewriterSet - , u_defer :: TcRef [Ct] -- Deferred constraints + , u_defer :: TcRef [Ct] + -- Which variables are unified; + -- if Nothing, we don't care , u_unified :: Maybe (TcRef [TcTyVar]) - -- If Just, track unified type variables } +setUEnvRole :: UnifyEnv -> Role -> UnifyEnv +setUEnvRole uenv role = uenv { u_role = role } + +updUEnvLoc :: UnifyEnv -> (CtLoc -> CtLoc) -> UnifyEnv +updUEnvLoc uenv@(UE { u_loc = loc }) upd = uenv { u_loc = upd loc } + mkKindEnv :: UnifyEnv -> TcType -> TcType -> UnifyEnv -- Modify the UnifyEnv to be right for unifing -- the kinds of these two types @@ -1794,15 +1804,16 @@ uType, uType_defer -- It is always safe to defer unification to the main constraint solver -- See Note [Deferred unification] -uType_defer (UE { u_loc = loc, u_defer = ref, u_role = role }) +uType_defer (UE { u_loc = loc, u_defer = ref + , u_role = role, u_rewriters = rewriters }) ty1 ty2 -- ty1 is "actual", ty2 is "expected" = do { let pred_ty = mkPrimEqPredRole role ty1 ty2 ; hole <- newCoercionHole pred_ty ; let ct = mkNonCanonical $ - CtWanted { ctev_pred = pred_ty - , ctev_dest = HoleDest hole - , ctev_loc = loc - , ctev_rewriters = rewriterSetFromTypes [ty1, ty2] } + CtWanted { ctev_pred = pred_ty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = rewriters } co = HoleCo hole ; updTcRef ref (ct :) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3017ff4038d20190ae8887b4562a24df3895f8c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3017ff4038d20190ae8887b4562a24df3895f8c1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 09:26:45 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 07 Apr 2023 05:26:45 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] Only store Name in FunRhs rather than Id with knot-tied fields Message-ID: <642fe1d592994_3b0055445d1c246236c3@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 2838d3c7 by Matthew Pickering at 2023-04-07T14:56:30+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 12 changed files: - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Match.hs-boot - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/Language/Haskell/Syntax/Expr.hs - + testsuite/tests/ghci/scripts/T22695.script - + testsuite/tests/ghci/scripts/T22695.stderr - testsuite/tests/ghci/scripts/all.T - testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr Changes: ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -912,7 +912,7 @@ mkSimpleGeneratedFunBind loc fun pats expr emptyLocalBinds] -- | Make a prefix, non-strict function 'HsMatchContext' -mkPrefixFunRhs :: LIdP p -> HsMatchContext p +mkPrefixFunRhs :: LIdP (NoGhcTc p) -> HsMatchContext p mkPrefixFunRhs n = FunRhs { mc_fun = n , mc_fixity = Prefix , mc_strictness = NoSrcStrict } ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -943,7 +943,7 @@ instance HiePass p => ToHie (HsMatchContext (GhcPass p)) where name' :: LocatedN Name name' = case hiePass @p of HieRn -> name - HieTc -> mapLoc varName name + HieTc -> name toHie (StmtCtxt a) = toHie a toHie _ = pure [] ===================================== compiler/GHC/Tc/Gen/Arrow.hs ===================================== @@ -172,7 +172,7 @@ tc_cmd env in_cmd@(HsCmdCase x scrut matches) (stk, res_ty) tc_cmd env cmd@(HsCmdLamCase x lc_variant match) cmd_ty = addErrCtxt (cmdCtxt cmd) do { let match_ctxt = ArrowLamCaseAlt lc_variant - ; checkPatCounts (ArrowMatchCtxt match_ctxt) match + ; checkArgCounts (ArrowMatchCtxt match_ctxt) match ; (wrap, match') <- tcCmdMatchLambda env match_ctxt match cmd_ty ; return (mkHsCmdWrap wrap (HsCmdLamCase x lc_variant match')) } ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -615,7 +615,7 @@ tcPolyCheck prag_fn -- See Note [Relevant bindings and the binder stack] setSrcSpanA bind_loc $ - tcMatchesFun (L nm_loc mono_id) matches + tcMatchesFun (L nm_loc (idName mono_id)) matches (mkCheckExpType rho_ty) -- We make a funny AbsBinds, abstracting over nothing, @@ -1183,18 +1183,14 @@ tcMonoBinds is_rec sig_fn no_gen | NonRecursive <- is_rec -- ...binder isn't mentioned in RHS , Nothing <- sig_fn name -- ...with no type signature = setSrcSpanA b_loc $ - do { ((co_fn, matches'), mono_id, _) <- fixM $ \ ~(_, _, rhs_ty) -> - -- See Note [fixM for rhs_ty in tcMonoBinds] - do { mono_id <- newLetBndr no_gen name Many rhs_ty - ; (matches', rhs_ty') - <- tcInfer $ \ exp_ty -> + do { ((co_fn, matches'), rhs_ty') + <- tcInfer $ \ exp_ty -> tcExtendBinderStack [TcIdBndr_ExpType name exp_ty NotTopLevel] $ -- We extend the error context even for a non-recursive -- function so that in type error messages we show the -- type of the thing whose rhs we are type checking - tcMatchesFun (L nm_loc mono_id) matches exp_ty - ; return (matches', mono_id, rhs_ty') - } + tcMatchesFun (L nm_loc name) matches exp_ty + ; mono_id <- newLetBndr no_gen name Many rhs_ty' ; return (unitBag $ L b_loc $ FunBind { fun_id = L nm_loc mono_id, @@ -1308,19 +1304,6 @@ correctly elaborate 'id'. But we want to /infer/ q's higher rank type. There seems to be no way to do this. So currently we only switch to inference when we have no signature for any of the binders. -Note [fixM for rhs_ty in tcMonoBinds] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In order to create mono_id we need rhs_ty but we don't have it yet, -we only get it from tcMatchesFun later (which needs mono_id to put -into HsMatchContext for pretty printing). To solve this, create -a thunk of rhs_ty with fixM that we fill in later. - -This is fine only because neither newLetBndr or tcMatchesFun look -at the varType field of the Id. tcMatchesFun only looks at idName -of mono_id. - -Also see #20415 for the bigger picture of why tcMatchesFun needs -mono_id in the first place. -} @@ -1448,7 +1431,7 @@ tcRhs (TcFunBind info@(MBI { mbi_sig = mb_sig, mbi_mono_id = mono_id }) = tcExtendIdBinderStackForRhs [info] $ tcExtendTyVarEnvForRhs mb_sig $ do { traceTc "tcRhs: fun bind" (ppr mono_id $$ ppr (idType mono_id)) - ; (co_fn, matches') <- tcMatchesFun (L (noAnnSrcSpan loc) mono_id) + ; (co_fn, matches') <- tcMatchesFun (L (noAnnSrcSpan loc) (idName mono_id)) matches (mkCheckExpType $ idType mono_id) ; return ( FunBind { fun_id = L (noAnnSrcSpan loc) mono_id , fun_matches = matches' ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -31,7 +31,7 @@ module GHC.Tc.Gen.Match , tcBody , tcDoStmt , tcGuardStmt - , checkPatCounts + , checkArgCounts ) where @@ -93,12 +93,12 @@ is used in error messages. It checks that all the equations have the same number of arguments before using @tcMatches@ to do the work. -} -tcMatchesFun :: LocatedN Id -- MatchContext Id +tcMatchesFun :: LocatedN Name -- MatchContext Id -> MatchGroup GhcRn (LHsExpr GhcRn) -> ExpRhoType -- Expected type of function -> TcM (HsWrapper, MatchGroup GhcTc (LHsExpr GhcTc)) -- Returns type of body -tcMatchesFun fun_id matches exp_ty +tcMatchesFun fun_name matches exp_ty = do { -- Check that they all have the same no of arguments -- Location is in the monad, set the caller so that -- any inter-equation error messages get some vaguely @@ -106,9 +106,7 @@ tcMatchesFun fun_id matches exp_ty -- ann-grabbing, because we don't always have annotations in -- hand when we call tcMatchesFun... traceTc "tcMatchesFun" (ppr fun_name $$ ppr exp_ty) - -- We can't easily call checkPatCounts here because fun_id can be an - -- unfilled thunk - ; checkArgCounts fun_name matches + ; checkArgCounts what matches ; matchExpectedFunTys herald ctxt arity exp_ty $ \ pat_tys rhs_ty -> -- NB: exp_type may be polymorphic, but @@ -122,17 +120,11 @@ tcMatchesFun fun_id matches exp_ty -- a multiplicity argument, and scale accordingly. tcMatches match_ctxt pat_tys rhs_ty matches } where - fun_name = idName (unLoc fun_id) arity = matchGroupArity matches - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing (unLoc fun_name)) matches ctxt = GenSigCtxt -- Was: FunSigCtxt fun_name True -- But that's wrong for f :: Int -> forall a. blah - what = FunRhs { mc_fun = fun_id, mc_fixity = Prefix, mc_strictness = strictness } - -- Careful: this fun_id could be an unfilled - -- thunk from fixM in tcMonoBinds, so we're - -- not allowed to look at it, except for - -- idName. - -- See Note [fixM for rhs_ty in tcMonoBinds] + what = FunRhs { mc_fun = fun_name, mc_fixity = Prefix, mc_strictness = strictness } match_ctxt = MC { mc_what = what, mc_body = tcBody } strictness | [L _ match] <- unLoc $ mg_alts matches @@ -164,7 +156,7 @@ tcMatchLambda :: ExpectedFunTyOrigin -- see Note [Herald for matchExpectedFunTys -> ExpRhoType -> TcM (HsWrapper, MatchGroup GhcTc (LHsExpr GhcTc)) tcMatchLambda herald match_ctxt match res_ty - = do { checkPatCounts (mc_what match_ctxt) match + = do { checkArgCounts (mc_what match_ctxt) match ; matchExpectedFunTys herald GenSigCtxt n_pats res_ty $ \ pat_tys rhs_ty -> do -- checking argument counts since this is also used for \cases tcMatches match_ctxt pat_tys rhs_ty match } @@ -1136,39 +1128,28 @@ the variables they bind into scope, and typecheck the thing_inside. \subsection{Errors and contexts} * * ************************************************************************ - - at checkArgCounts@ takes a @[RenamedMatch]@ and decides whether the same -number of args are used in each equation. -} +-- | @checkArgCounts@ takes a @[RenamedMatch]@ and decides whether the same +-- number of args are used in each equation. checkArgCounts :: AnnoBody body - => Name -> MatchGroup GhcRn (LocatedA (body GhcRn)) -> TcM () -checkArgCounts = check_match_pats . (text "Equations for" <+>) . quotes . ppr - --- @checkPatCounts@ takes a @[RenamedMatch]@ and decides whether the same --- number of patterns are used in each alternative -checkPatCounts :: AnnoBody body - => HsMatchContext GhcTc -> MatchGroup GhcRn (LocatedA (body GhcRn)) - -> TcM () -checkPatCounts = check_match_pats . pprMatchContextNouns - -check_match_pats :: AnnoBody body - => SDoc -> MatchGroup GhcRn (LocatedA (body GhcRn)) - -> TcM () -check_match_pats _ (MG { mg_alts = L _ [] }) - = return () -check_match_pats err_msg (MG { mg_alts = L _ (match1:matches) }) - | null bad_matches + => HsMatchContext GhcTc -> MatchGroup GhcRn (LocatedA (body GhcRn)) + -> TcM () +checkArgCounts _ (MG { mg_alts = L _ [] }) = return () - | otherwise +checkArgCounts matchContext (MG { mg_alts = L _ (match1:matches) }) + | not (null bad_matches) = failWithTc $ TcRnUnknownMessage $ mkPlainError noHints $ (vcat [ err_msg <+> text "have different numbers of arguments" , nest 2 (ppr (getLocA match1)) , nest 2 (ppr (getLocA (head bad_matches)))]) + | otherwise + = return () where n_args1 = args_in_match match1 bad_matches = [m | m <- matches, args_in_match m /= n_args1] + err_msg = text "Equations for" <+> quotes (pprMatchContextNouns matchContext) args_in_match :: (LocatedA (Match GhcRn body1) -> Int) args_in_match (L _ (Match { m_pats = pats })) = length pats ===================================== compiler/GHC/Tc/Gen/Match.hs-boot ===================================== @@ -5,13 +5,13 @@ import GHC.Tc.Utils.TcType( ExpSigmaType, ExpRhoType ) import GHC.Tc.Types ( TcM ) import GHC.Hs.Extension ( GhcRn, GhcTc ) import GHC.Parser.Annotation ( LocatedN ) -import GHC.Types.Id (Id) +import GHC.Types.Name (Name) tcGRHSsPat :: GRHSs GhcRn (LHsExpr GhcRn) -> ExpRhoType -> TcM (GRHSs GhcTc (LHsExpr GhcTc)) -tcMatchesFun :: LocatedN Id +tcMatchesFun :: LocatedN Name -> MatchGroup GhcRn (LHsExpr GhcRn) -> ExpSigmaType -> TcM (HsWrapper, MatchGroup GhcTc (LHsExpr GhcTc)) ===================================== compiler/GHC/Tc/TyCl/PatSyn.hs ===================================== @@ -840,7 +840,7 @@ tcPatSynMatcher (L loc ps_name) lpat prag_fn , mg_ext = MatchGroupTc (map unrestricted [pat_ty, cont_ty, fail_ty]) res_ty , mg_origin = Generated } - match = mkMatch (mkPrefixFunRhs (L loc patsyn_id)) [] + match = mkMatch (mkPrefixFunRhs (L loc (idName patsyn_id))) [] (mkHsLams (rr_tv:res_tv:univ_tvs) req_dicts body') (EmptyLocalBinds noExtField) ===================================== compiler/Language/Haskell/Syntax/Expr.hs ===================================== @@ -1680,7 +1680,10 @@ data HsMatchContext p = FunRhs -- ^ A pattern matching on an argument of a -- function binding - { mc_fun :: LIdP p -- ^ function binder of @f@ + { mc_fun :: LIdP (NoGhcTc p) -- ^ function binder of @f@ + -- See Note [mc_fun field of FunRhs] + -- See #20415 for a long discussion about + -- this field and why it uses NoGhcTc. , mc_fixity :: LexicalFixity -- ^ fixing of @f@ , mc_strictness :: SrcStrictness -- ^ was @f@ banged? -- See Note [FunBind vs PatBind] @@ -1707,6 +1710,21 @@ data HsMatchContext p | ThPatQuote -- ^A Template Haskell pattern quotation [p| (a,b) |] | PatSyn -- ^A pattern synonym declaration +{- +Note [mc_fun field of FunRhs] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The mc_fun field of FunRhs has type `LIdP (NoGhcTc p)`, which means it will be +a `RdrName` in pass `GhcPs`, a `Name` in `GhcRn`, and (importantly) still a +`Name` in `GhcTc` -- not an `Id`. See Note [NoGhcTc] in GHC.Hs.Extension. + +Why a `Name` in the typechecker phase? Because: +* A `Name` is all we need, as it turns out. +* Using an `Id` involves knot-tying in the monad, which led to #22695. + +See #20415 for a long discussion. + +-} + isPatSynCtxt :: HsMatchContext p -> Bool isPatSynCtxt ctxt = case ctxt of @@ -1801,7 +1819,7 @@ matchSeparator ThPatSplice = panic "unused" matchSeparator ThPatQuote = panic "unused" matchSeparator PatSyn = panic "unused" -pprMatchContext :: (Outputable (IdP p), UnXRec p) +pprMatchContext :: (Outputable (IdP (NoGhcTc p)), UnXRec (NoGhcTc p)) => HsMatchContext p -> SDoc pprMatchContext ctxt | want_an ctxt = text "an" <+> pprMatchContextNoun ctxt @@ -1812,10 +1830,10 @@ pprMatchContext ctxt want_an (ArrowMatchCtxt KappaExpr) = True want_an _ = False -pprMatchContextNoun :: forall p. (Outputable (IdP p), UnXRec p) +pprMatchContextNoun :: forall p. (Outputable (IdP (NoGhcTc p)), UnXRec (NoGhcTc p)) => HsMatchContext p -> SDoc pprMatchContextNoun (FunRhs {mc_fun=fun}) = text "equation for" - <+> quotes (ppr (unXRec @p fun)) + <+> quotes (ppr (unXRec @(NoGhcTc p) fun)) pprMatchContextNoun CaseAlt = text "case alternative" pprMatchContextNoun (LamCaseAlt lc_variant) = lamCaseKeyword lc_variant <+> text "alternative" @@ -1831,10 +1849,10 @@ pprMatchContextNoun (StmtCtxt ctxt) = text "pattern binding in" $$ pprAStmtContext ctxt pprMatchContextNoun PatSyn = text "pattern synonym declaration" -pprMatchContextNouns :: forall p. (Outputable (IdP p), UnXRec p) +pprMatchContextNouns :: forall p. (Outputable (IdP (NoGhcTc p)), UnXRec (NoGhcTc p)) => HsMatchContext p -> SDoc pprMatchContextNouns (FunRhs {mc_fun=fun}) = text "equations for" - <+> quotes (ppr (unXRec @p fun)) + <+> quotes (ppr (unXRec @(NoGhcTc p) fun)) pprMatchContextNouns PatBindGuards = text "pattern binding guards" pprMatchContextNouns (ArrowMatchCtxt c) = pprArrowMatchContextNouns c pprMatchContextNouns (StmtCtxt ctxt) = text "pattern bindings in" @@ -1855,7 +1873,7 @@ pprArrowMatchContextNouns (ArrowLamCaseAlt lc_variant) = lamCaseKeyword lc_varia pprArrowMatchContextNouns ctxt = pprArrowMatchContextNoun ctxt <> char 's' ----------------- -pprAStmtContext, pprStmtContext :: (Outputable (IdP p), UnXRec p) +pprAStmtContext, pprStmtContext :: (Outputable (IdP (NoGhcTc p)), UnXRec (NoGhcTc p)) => HsStmtContext p -> SDoc pprAStmtContext (HsDoStmt flavour) = pprAHsDoFlavour flavour pprAStmtContext ctxt = text "a" <+> pprStmtContext ctxt ===================================== testsuite/tests/ghci/scripts/T22695.script ===================================== @@ -0,0 +1 @@ +test x | Just <- x = x ===================================== testsuite/tests/ghci/scripts/T22695.stderr ===================================== @@ -0,0 +1,8 @@ + +:1:10: error: + • The constructor ‘Just’ should have 1 argument, but has been given none + • In the pattern: Just + In a stmt of a pattern guard for + an equation for ‘test’: + Just <- x + In an equation for ‘test’: test x | Just <- x = x ===================================== testsuite/tests/ghci/scripts/all.T ===================================== @@ -367,3 +367,4 @@ test('T21088', normal, ghci_script, ['T21088.script']) test('T21110', [extra_files(['T21110A.hs'])], ghci_script, ['T21110.script']) test('T17830', [filter_stdout_lines(r'======.*')], ghci_script, ['T17830.script']) +test('T22695', normal, ghci_script, ['T22695.script']) ===================================== testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr ===================================== @@ -1557,7 +1557,7 @@ (FunRhs (L (SrcSpanAnn (EpAnnNotUsed) { DumpTypecheckedAst.hs:19:1-4 }) - {Var: main}) + {Name: main}) (Prefix) (NoSrcStrict)) [] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2838d3c7741d58f0c30729e34b0d2c776a2de985 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2838d3c7741d58f0c30729e34b0d2c776a2de985 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 11:26:35 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 07 Apr 2023 07:26:35 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Wibbles Message-ID: <642ffdeb43285_3b005546374268633236@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: ec8d3344 by Simon Peyton Jones at 2023-04-07T12:28:09+01:00 Wibbles - - - - - 6 changed files: - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -652,10 +652,13 @@ can_eq_app :: CtEvidence -- :: s1 t1 ~N s2 t2 -- See Note [Decomposing AppTy equalities] can_eq_app ev s1 t1 s2 t2 | CtWanted { ctev_dest = dest } <- ev - = do { (co,_) <- unifyWanteds ev Nominal $ \uenv -> - do { co_s <- uType uenv s1 s2 - ; let arg_env = updUEnvLoc uenv (adjustCtLoc (isNextArgVisible s1) False) + = do { traceTcS "can_eq_app" (vcat [ text "s1:" <+> ppr s1, text "t1:" <+> ppr t1 + , text "s2:" <+> ppr s2, text "t2:" <+> ppr t2 + , text "vis:" <+> ppr (isNextArgVisible s1) ]) + ; (co,_) <- unifyWanteds ev Nominal $ \uenv -> + do { let arg_env = updUEnvLoc uenv (adjustCtLoc (isNextArgVisible s1) False) ; co_t <- uType arg_env t1 t2 + ; co_s <- uType uenv s1 s2 ; return (mkAppCo co_s co_t) } ; setWantedEq dest co ; stopWith ev "Decomposed [W] AppTy" } ===================================== compiler/GHC/Tc/Solver/InertSet.hs ===================================== @@ -179,8 +179,10 @@ workListSize (WL { wl_eqs = eqs, wl_rest = rest }) extendWorkListEq :: Ct -> WorkList -> WorkList extendWorkListEq ct wl = wl { wl_eqs = ct : wl_eqs wl } -extendWorkListEqs :: [Ct] -> WorkList -> WorkList -extendWorkListEqs cts wl = wl { wl_eqs = cts ++ wl_eqs wl } +extendWorkListEqs :: Bag Ct -> WorkList -> WorkList +-- Add [eq1,...,eqn] to the work-list, retaining order +extendWorkListEqs eqs wl + = wl { wl_eqs = foldr (:) (wl_eqs wl) eqs } extendWorkListNonEq :: Ct -> WorkList -> WorkList -- Extension by non equality ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -1977,7 +1977,7 @@ unifyWanteds :: CtEvidence -> Role -- Return coercions witnessing the equality of the two types, -- emitting new work equalities where necessary to achieve that -- Very good short-cut when the two types are equal, or nearly so --- See Note [unifyWanted] +-- See Note [unifyWanteds] -- The returned coercion's role matches the input parameter -- -- The [TcTyVar] is the list of unification variables @@ -1985,7 +1985,7 @@ unifyWanteds :: CtEvidence -> Role unifyWanteds ev role do_unifications = do { (cos, unified, cts) <- wrapTcS $ - do { defer_ref <- TcM.newTcRef [] + do { defer_ref <- TcM.newTcRef emptyBag ; unified_ref <- TcM.newTcRef [] ; let env = UE { u_role = role , u_rewriters = ctEvRewriters ev @@ -2000,7 +2000,8 @@ unifyWanteds ev role do_unifications ; return (cos, unified, cts) } -- Emit the deferred constraints - ; updWorkListTcS (extendWorkListEqs cts) + ; unless (isEmptyBag cts) $ + updWorkListTcS (extendWorkListEqs cts) -- And kick out any inert constraint that we have unified -- ToDo: treating the tyvars together might ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -2415,22 +2415,22 @@ mkKindLoc s1 s2 loc = setCtLocOrigin (toKindLoc loc) adjustCtLocTyConBinder :: TyConBinder -> CtLoc -> CtLoc -- Adjust the CtLoc when decomposing a type constructor adjustCtLocTyConBinder tc_bndr loc - = adjustCtLoc is_invis is_kind loc + = adjustCtLoc is_vis is_kind loc where - is_invis = isInvisibleTyConBinder tc_bndr - is_kind = isNamedTyConBinder tc_bndr + is_vis = isVisibleTyConBinder tc_bndr + is_kind = isNamedTyConBinder tc_bndr -adjustCtLoc :: Bool -- True <=> An invisible argument +adjustCtLoc :: Bool -- True <=> A visible argument -> Bool -- True <=> A kind argument -> CtLoc -> CtLoc -- Adjust the CtLoc when decomposing a type constructor, application, etc -adjustCtLoc is_invis is_kind loc +adjustCtLoc is_vis is_kind loc = loc2 where loc1 | is_kind = toKindLoc loc | otherwise = loc - loc2 | is_invis = toInvisibleLoc loc1 - | otherwise = loc1 + loc2 | is_vis = loc1 + | otherwise = toInvisibleLoc loc1 -- | Take a CtLoc and moves it to the kind level toKindLoc :: CtLoc -> CtLoc ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -2321,10 +2321,11 @@ isNextTyConArgVisible tc tys = tcTyConVisibilities tc `getNth` length tys -- | Should this type be applied to a visible argument? +-- E.g. (s t): is `t` a visible argument of `s`? isNextArgVisible :: TcType -> Bool isNextArgVisible ty - | Just (bndr, _) <- tcSplitPiTy_maybe ty = isVisiblePiTyBinder bndr - | otherwise = True + | Just (bndr, _) <- tcSplitPiTy_maybe (typeKind ty) = isVisiblePiTyBinder bndr + | otherwise = True -- this second case might happen if, say, we have an unzonked TauTv. -- But TauTvs can't range over types that take invisible arguments ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1744,7 +1744,7 @@ unifyKind mb_thing ty1 ty2 uTypeAndEmit :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM CoercionN -- Make a ref-cell, unify, emit the collected constraints uTypeAndEmit t_or_k orig ty1 ty2 - = do { ref <- newTcRef [] + = do { ref <- newTcRef emptyBag ; loc <- getCtLocM orig (Just t_or_k) ; let env = UE { u_loc = loc, u_role = Nominal , u_rewriters = emptyRewriterSet -- ToDo: check this @@ -1754,7 +1754,7 @@ uTypeAndEmit t_or_k orig ty1 ty2 ; co <- uType env ty1 ty2 ; cts <- readTcRef ref - ; unless (null cts) (emitSimples (listToBag cts)) + ; unless (null cts) (emitSimples cts) ; return co } {- @@ -1773,7 +1773,7 @@ data UnifyEnv , u_rewriters :: RewriterSet -- Deferred constraints - , u_defer :: TcRef [Ct] + , u_defer :: TcRef (Bag Ct) -- Which variables are unified; -- if Nothing, we don't care @@ -1815,7 +1815,7 @@ uType_defer (UE { u_loc = loc, u_defer = ref , ctev_loc = loc , ctev_rewriters = rewriters } co = HoleCo hole - ; updTcRef ref (ct :) + ; updTcRef ref (`snocBag` ct) -- Error trace only -- NB. do *not* call mkErrInfo unless tracing is on, @@ -2135,7 +2135,7 @@ uUnfilledVar2 :: UnifyEnv -- definitely not a /filled/ meta-tyvar -> TcTauType -- Type 2, zonked -> TcM CoercionN -uUnfilledVar2 env swapped tv1 ty2 +uUnfilledVar2 env@(UE { u_defer = def_eq_ref }) swapped tv1 ty2 = do { cur_lvl <- getTcLevel -- See Note [Unification preconditions], (UNTOUCHABLE) wrinkles -- Here we don't know about given equalities here; so we treat @@ -2144,7 +2144,8 @@ uUnfilledVar2 env swapped tv1 ty2 && simpleUnifyCheck False tv1 ty2) then not_ok_so_defer else - do { co_k <- uType (mkKindEnv env ty1 ty2) (typeKind ty2) (tyVarKind tv1) + do { def_eqs <- readTcRef def_eq_ref + ; co_k <- uType (mkKindEnv env ty1 ty2) (typeKind ty2) (tyVarKind tv1) ; traceTc "uUnfilledVar2 ok" $ vcat [ ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1) , ppr ty2 <+> dcolon <+> ppr (typeKind ty2) @@ -2160,9 +2161,13 @@ uUnfilledVar2 env swapped tv1 ty2 Just uref -> updTcRef uref (tv1 :) ; return (mkNomReflCo ty2) } -- Unification is always Nominal - else defer -- This cannot be solved now. See GHC.Tc.Solver.Canonical - -- Note [Equalities with incompatible kinds] for how - -- this will be dealt with in the solver + else -- This cannot be solved now. See GHC.Tc.Solver.Canonical + -- Note [Equalities with incompatible kinds] for how this + -- will be dealt with in the solver + -- Since we are discarding co_k, also discard any constraints + -- emitted by kind unification; they are just useless clutter. + do { writeTcRef def_eq_ref def_eqs + ; defer } }} where ty1 = mkTyVarTy tv1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec8d3344bce8fceddc158e1c4ce9e5e31695e4a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec8d3344bce8fceddc158e1c4ce9e5e31695e4a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 18:57:01 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 14:57:01 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: nonmoving: Disable slop-zeroing Message-ID: <6430677dd65c_3b00554d977f50685271@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - 78d115c4 by Alex Dixon at 2023-04-07T14:56:55-04:00 Improve documentation for ($) (#22963) - - - - - e4169f93 by Alex Dixon at 2023-04-07T14:56:55-04:00 Remove trailing whitespace from ($) commentary - - - - - 9fe52a1d by Sebastian Graf at 2023-04-07T14:56:55-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 4 changed files: - docs/users_guide/using-warnings.rst - libraries/base/GHC/Base.hs - libraries/base/changelog.md - rts/include/rts/storage/ClosureMacros.h Changes: ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -1615,7 +1615,7 @@ of ``-W(no-)*``. :shortdesc: Warn when using :ghc-flag:`-fllvm` with an unsupported version of LLVM. :type: dynamic - :reverse: -Wno-monomorphism-restriction + :reverse: -Wno-unsupported-llvm-version :category: :since: 7.8 ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1606,18 +1606,69 @@ flip f x y = f y x -- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now -- it is equivalent to undefined `seq` () which diverges. --- | Application operator. This operator is redundant, since ordinary --- application @(f x)@ means the same as @(f '$' x)@. However, '$' has --- low, right-associative binding precedence, so it sometimes allows --- parentheses to be omitted; for example: --- --- > f $ g $ h x = f (g (h x)) --- --- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, --- or @'Data.List.zipWith' ('$') fs xs at . --- --- Note that @('$')@ is representation-polymorphic, so that --- @foo '$' 4#@ where @foo :: Int# -> Int#@ is well-typed. +{- | @($)@ is the __function application__ operator. + +Applying @($)@ to a function @f@ and an argument @x@ gives the same result as applying @f@ to @x@ directly. The definition is akin to this: + +@ +($) :: (a -> b) -> a -> b +($) f x = f x +@ + +On the face of it, this may appear pointless! But it's actually one of the most useful and important operators in Haskell. + +The order of operations is very different between @($)@ and normal function application. Normal function application has precedence 10 - higher than any operator - and associates to the left. So these two definitions are equivalent: + +@ +expr = min 5 1 + 5 +expr = ((min 5) 1) + 5 +@ + +@($)@ has precedence 0 (the lowest) and associates to the right, so these are equivalent: + +@ +expr = min 5 $ 1 + 5 +expr = (min 5) (1 + 5) +@ + +=== Uses + +A common use cases of @($)@ is to avoid parentheses in complex expressions. + +For example, instead of using nested parentheses in the following + Haskell function: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' ('Data.Maybe.mapMaybe' 'Text.Read.readMaybe' ('words' s)) +@ + +we can deploy the function application operator: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' '$' 'Data.Maybe.mapMaybe' 'Text.Read.readMaybe' '$' 'words' s +@ + +@($)@ is also used as a section (a partially applied operator), in order to indicate that we wish to apply some yet-unspecified function to a given value. For example, to apply the argument @5@ to a list of functions: + +@ +applyFive :: [Int] +applyFive = map ($ 5) [(+1), (2^)] +>>> [6, 32] +@ + +=== Technical Remark (Representation Polymorphism) + +@($)@ is fully representation-polymorphic. This allows it to also be used with arguments of unlifted and even unboxed kinds, such as unboxed integers: + +@ +fastMod :: Int -> Int -> Int +fastMod (I# x) (I# m) = I# $ remInt# x m +@ +-} {-# INLINE ($) #-} ($) :: forall repa repb (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ($) f = f ===================================== libraries/base/changelog.md ===================================== @@ -7,8 +7,6 @@ * Add `Data.List.!?` ([CLC proposal #110](https://github.com/haskell/core-libraries-committee/issues/110)) * `maximumBy`/`minimumBy` are now marked as `INLINE` improving performance for unpackable types significantly. - * Refactor `generalCategory` to stop very large literal string being inlined to call-sites. - ([CLC proposal #130](https://github.com/haskell/core-libraries-committee/issues/130)) * Add INLINABLE pragmas to `generic*` functions in Data.OldList ([CLC proposal #129](https://github.com/haskell/core-libraries-committee/issues/130)) * Export `getSolo` from `Data.Tuple`. ([CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113)) @@ -23,7 +21,7 @@ ([CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149)) * Make `($)` representation polymorphic ([CLC proposal #132](https://github.com/haskell/core-libraries-committee/issues/132)) -## 4.18.0.0 *TBA* +## 4.18.0.0 *March 2023* * Shipped with GHC 9.6.1 * `Foreign.C.ConstPtr.ConstrPtr` was added to encode `const`-qualified pointer types in foreign declarations when using `CApiFFI` extension. ([CLC proposal #117](https://github.com/haskell/core-libraries-committee/issues/117)) @@ -61,6 +59,9 @@ ([CLC proposal #50](https://github.com/haskell/core-libraries-committee/issues/50), [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md)) + * Switch to a pure Haskell implementation of `GHC.Unicode` + ([CLC proposals #59](https://github.com/haskell/core-libraries-committee/issues/59) + and [#130](https://github.com/haskell/core-libraries-committee/issues/130)) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -479,11 +479,13 @@ EXTERN_INLINE StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) memory we're about to zero. Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero - immutable closure's slop. + immutable closure's slop. Similarly, the concurrent GC's mark thread + may race when a mutator during slop-zeroing. Consequently, we also disable + zeroing when the non-moving GC is in use. Hence, an immutable closure's slop is zeroed when either: - - PROFILING && era > 0 (LDV is on) or + - PROFILING && era > 0 (LDV is on) && !nonmoving-gc-enabled or - !THREADED && DEBUG Additionally: @@ -535,8 +537,10 @@ zeroSlop (StgClosure *p, #endif ; - // Only if we're running single threaded. - const bool can_zero_immutable_slop = getNumCapabilities() == 1; + const bool can_zero_immutable_slop = + // Only if we're running single threaded. + getNumCapabilities() == 1 + && !RTS_DEREF(RtsFlags).GcFlags.useNonmoving; // see #23170 const bool zero_slop_immutable = want_to_zero_immutable_slop && can_zero_immutable_slop; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b79e3865d19ec02b3dba02052c2627c8ea0edb2...9fe52a1dbb53f07971f172a8502565109d2385e6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b79e3865d19ec02b3dba02052c2627c8ea0edb2...9fe52a1dbb53f07971f172a8502565109d2385e6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 21:30:05 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 07 Apr 2023 17:30:05 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 2 commits: Improve partial signatures Message-ID: <64308b5d7b540_3b00555039934c7122e0@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: 65fd65ab by Simon Peyton Jones at 2023-04-07T22:28:57+01:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 7d6284da by Simon Peyton Jones at 2023-04-07T22:29:24+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 10 changed files: - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Types/Origin.hs - testsuite/tests/partial-sigs/should_compile/T10403.stderr - testsuite/tests/partial-sigs/should_compile/T19106.hs - testsuite/tests/partial-sigs/should_compile/all.T - + testsuite/tests/partial-sigs/should_fail/T23223.hs - + testsuite/tests/partial-sigs/should_fail/T23223.stderr - testsuite/tests/partial-sigs/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/Bind.hs ===================================== @@ -751,57 +751,102 @@ tcPolyInfer rec_tc prag_fn tc_sig_fn bind_list checkMonomorphismRestriction :: [MonoBindInfo] -> [LHsBind GhcRn] -> TcM Bool -- True <=> apply the MR +-- See Note [When the MR applies] checkMonomorphismRestriction mbis lbinds - | null partial_sigs -- The normal case = do { mr_on <- xoptM LangExt.MonomorphismRestriction ; let mr_applies = mr_on && any (restricted . unLoc) lbinds - ; when mr_applies $ mapM_ checkOverloadedSig sigs + ; when mr_applies $ mapM_ checkOverloadedSig mbis ; return mr_applies } - - | otherwise -- See Note [Partial type signatures and the monomorphism restriction] - = return (all is_mono_psig partial_sigs) - where - sigs, partial_sigs :: [TcIdSigInst] - sigs = [sig | MBI { mbi_sig = Just sig } <- mbis] - partial_sigs = [sig | sig@(TISI { sig_inst_sig = PartialSig {} }) <- sigs] - - complete_sig_bndrs :: NameSet - complete_sig_bndrs - = mkNameSet [ idName bndr - | TISI { sig_inst_sig = CompleteSig { sig_bndr = bndr }} <- sigs ] - - is_mono_psig (TISI { sig_inst_theta = theta, sig_inst_wcx = mb_extra_constraints }) - = null theta && isNothing mb_extra_constraints + no_mr_bndrs :: NameSet + no_mr_bndrs = mkNameSet (mapMaybe no_mr_name mbis) + + no_mr_name :: MonoBindInfo -> Maybe Name + -- Just n for binders that have a signature that says "no MR needed for me" + no_mr_name (MBI { mbi_sig = Just sig }) + | TISI { sig_inst_sig = info, sig_inst_theta = theta, sig_inst_wcx = wcx } <- sig + = case info of + CompleteSig { sig_bndr = bndr } -> Just (idName bndr) + PartialSig { psig_name = nm } + | null theta, isNothing wcx -> Nothing -- f :: _ -> _ + | otherwise -> Just nm -- f :: Num a => a -> _ + -- For the latter case, we don't want the MR: + -- the user has explicitly specified a type-class context + no_mr_name _ = Nothing -- The Haskell 98 monomorphism restriction restricted (PatBind {}) = True - restricted (VarBind { var_id = v }) = no_sig v + restricted (VarBind { var_id = v }) = mr_needed_for v restricted (FunBind { fun_id = v, fun_matches = m }) = restricted_match m - && no_sig (unLoc v) + && mr_needed_for (unLoc v) restricted b = pprPanic "isRestrictedGroup/unrestricted" (ppr b) restricted_match mg = matchGroupArity mg == 0 -- No args => like a pattern binding -- Some args => a function binding - no_sig nm = not (nm `elemNameSet` complete_sig_bndrs) + mr_needed_for nm = not (nm `elemNameSet` no_mr_bndrs) -checkOverloadedSig :: TcIdSigInst -> TcM () +checkOverloadedSig :: MonoBindInfo -> TcM () -- Example: -- f :: Eq a => a -> a -- K f = e -- The MR applies, but the signature is overloaded, and it's -- best to complain about this directly -- c.f #11339 -checkOverloadedSig sig - | not (null (sig_inst_theta sig)) - , let orig_sig = sig_inst_sig sig +checkOverloadedSig (MBI { mbi_sig = mb_sig }) + | Just (TISI { sig_inst_sig = orig_sig, sig_inst_theta = theta, sig_inst_wcx = wcx }) <- mb_sig + , not (null theta && isNothing wcx) = setSrcSpan (sig_loc orig_sig) $ failWith $ TcRnOverloadedSig orig_sig | otherwise = return () +{- Note [When the MR applies] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The Monomorphism Restriction (MR) applies as specifies in the Haskell Report: + +* If -XMonomorphismRestriction is on, and +* Any binding is restricted + +A binding is restricted if: +* It is a pattern binding e.g. (x,y) = e +* Or it is a FunBind with no arguments e.g. f = rhs + and the binder `f` lacks a No-MR signature + +A binder f has a No-MR signature if + +* It has a complete type signature + e.g. f :: Num a => a -> a + +* Or it has a /partial/ type signature with a /context/ + e.g. f :: (_) => a -> _ + g :: Num a => a -> _ + h :: (Num a, _) => a -> _ + All of f,g,h have a No-MR signature. They say that the function is overloaded + so it's silly to try to apply the MR. This means that #20076 and #19106 work out + fine. Ditto #11016, which looked like + f4 :: (?loc :: Int) => _ + f4 = ?loc + + This partial-signature stuff is a bit ad-hoc but seems to match our + use-cases. See also Note [Constraints in partial type signatures] + in GHC.Tc.Solver. + +Example: the MR does apply to + k :: _ -> _ + k = rhs +because k's binding has no arguments, and `k` does not have +a No-MR signature. + +All of this checking takes place after synonym expansion. For example: + type Wombat a = forall b. Eq [b] => ...b...a... + f5 :: Wombat _ +This (and does) behave just like + f5 :: forall b. Eq [b] => ...b..._... + +-} + -------------- mkExport :: TcPragEnv -> WantedConstraints -- residual constraints, already emitted (for errors only) @@ -850,15 +895,9 @@ mkExport prag_fn residual insoluble qtvs theta then return idHsWrapper -- Fast path; also avoids complaint when we infer -- an ambiguous type and have AllowAmbiguousType -- e..g infer x :: forall a. F a -> Int - else tcSubTypeSigma GhcBug20076 + else tcSubTypeSigma (Shouldn'tHappenOrigin "mkExport") sig_ctxt sel_poly_ty poly_ty - -- as Note [Impedance matching] explains, this should never fail, - -- and thus we'll never see an error message. It *may* do - -- instantiation, but no message will ever be printed to the - -- user, and so we use Shouldn'tHappenOrigin. - -- Actually, there is a bug here: #20076. So we tell the user - -- that they hit the bug. Once #20076 is fixed, change this - -- back to Shouldn'tHappenOrigin. + -- See Note [Impedance matching] ; localSigWarn poly_id mb_sig @@ -1102,33 +1141,6 @@ It might be possible to fix these difficulties somehow, but there doesn't seem much point. Indeed, adding a partial type signature is a way to get per-binding inferred generalisation. -Note [Partial type signatures and the monomorphism restriction] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We apply the MR if /none/ of the partial signatures has a context. e.g. - f :: _ -> Int - f x = rhs -The partial type signature says, in effect, "there is no context", which -amounts to appplying the MR. Indeed, saying - f :: _ - f = rhs -is a way for forcing the MR to apply. - -But we /don't/ want to apply the MR if the partial signatures do have -a context e.g. (#11016): - f2 :: (?loc :: Int) => _ - f2 = ?loc -It's stupid to apply the MR here. This test includes an extra-constraints -wildcard; that is, we don't apply the MR if you write - f3 :: _ => blah - -But watch out. We don't want to apply the MR to - type Wombat a = forall b. Eq b => ...b...a... - f4 :: Wombat _ -Here f4 doesn't /look/ as if it has top-level overloading, but in fact it -does, hidden under Wombat. We can't "see" that because we only have access -to the HsType at the moment. That's why we do the check in -checkMonomorphismRestriction. - Note [Quantified variables in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1206,7 +1218,6 @@ considered: more indirect, but we need the "don't generalise over Concrete variables" stuff anyway. - Note [Impedance matching] ~~~~~~~~~~~~~~~~~~~~~~~~~ Consider ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -513,12 +513,12 @@ ppr_tvs tvs = braces (vcat [ ppr tv <+> dcolon <+> ppr (tyVarKind tv) tcInstSig :: TcIdSigInfo -> TcM TcIdSigInst -- Instantiate a type signature; only used with plan InferGen -tcInstSig sig@(CompleteSig { sig_bndr = poly_id, sig_loc = loc }) +tcInstSig hs_sig@(CompleteSig { sig_bndr = poly_id, sig_loc = loc }) = setSrcSpan loc $ -- Set the binding site of the tyvars do { (tv_prs, theta, tau) <- tcInstTypeBndrs (idType poly_id) -- See Note [Pattern bindings and complete signatures] - ; return (TISI { sig_inst_sig = sig + ; return (TISI { sig_inst_sig = hs_sig , sig_inst_skols = tv_prs , sig_inst_wcs = [] , sig_inst_wcx = Nothing ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE RecursiveDo #-} +{-# LANGUAGE MultiWayIf, RecursiveDo #-} module GHC.Tc.Solver( InferMode(..), simplifyInfer, findInferredDiff, @@ -1142,7 +1142,7 @@ simplifyInfer rhs_tclvl infer_mode sigs name_taus wanteds = do { -- When quantifying, we want to preserve any order of variables as they -- appear in partial signatures. cf. decideQuantifiedTyVars let psig_tv_tys = [ mkTyVarTy tv | sig <- partial_sigs - , (_,Bndr tv _) <- sig_inst_skols sig ] + , (_,Bndr tv _) <- sig_inst_skols sig ] psig_theta = [ pred | sig <- partial_sigs , pred <- sig_inst_theta sig ] @@ -1535,8 +1535,7 @@ decideQuantification decideQuantification skol_info infer_mode rhs_tclvl name_taus psigs candidates = do { -- Step 1: find the mono_tvs ; (candidates, co_vars, mono_tvs0) - <- decidePromotedTyVars infer_mode - name_taus psigs candidates + <- decidePromotedTyVars infer_mode name_taus psigs candidates -- Step 2: default any non-mono tyvars, and re-simplify -- This step may do some unification, but result candidates is zonked @@ -1553,19 +1552,16 @@ decideQuantification skol_info infer_mode rhs_tclvl name_taus psigs candidates ; psig_theta <- TcM.zonkTcTypes (concatMap sig_inst_theta psigs) ; min_theta <- pickQuantifiablePreds (mkVarSet qtvs) mono_tvs0 candidates - -- Add psig_theta back in here, even though it's already - -- part of candidates, because we always want to quantify over - -- psig_theta, and pickQuantifiableCandidates might have - -- dropped some e.g. CallStack constraints. c.f #14658 - -- equalities (a ~ Bool) - -- It's helpful to use the same "find difference" algorithm here as - -- we use in GHC.Tc.Gen.Bind.chooseInferredQuantifiers (#20921) + -- Take account of partial type signatures -- See Note [Constraints in partial type signatures] ; let min_psig_theta = mkMinimalBySCs id psig_theta - ; theta <- if null psig_theta - then return min_theta -- Fast path for the non-partial-sig case - else do { diff <- findInferredDiff min_psig_theta min_theta - ; return (min_psig_theta ++ diff) } + ; theta <- if + | null psigs -> return min_theta -- Case (P3) + | not (all has_extra_constraints_wildcard psigs) -- Case (P2) + -> return min_psig_theta + | otherwise -- Case (P1) + -> do { diff <- findInferredDiff min_psig_theta min_theta + ; return (min_psig_theta ++ diff) } ; traceTc "decideQuantification" (vcat [ text "infer_mode:" <+> ppr infer_mode @@ -1576,37 +1572,62 @@ decideQuantification skol_info infer_mode rhs_tclvl name_taus psigs candidates , text "theta:" <+> ppr theta ]) ; return (qtvs, theta, co_vars) } + where + has_extra_constraints_wildcard (TISI { sig_inst_wcx = Just {} }) = True + has_extra_constraints_wildcard _ = False + {- Note [Constraints in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose we have a partial type signature - f :: (Eq a, C a, _) => blah +Suppose we have decided to quantify over min_theta, say (Eq a, C a, Ix a). +Then we distinguish three cases: + +(P1) No partial type signatures: just quantify over min_theta + +(P2) Partial type signatures with no extra_constraints wildcard: + e.g. f :: (Eq a, C a) => a -> _ + Quantify over psig_theta: the user has explicitly specified the + entire context. + + That may mean we have an unsolved residual constraint (Ix a) arising + from the RHS of the function. But so be it: the user said (Eq a, C a). -We will ultimately quantify f over (Eq a, C a, ), where +(P3) Partial type signature with an extra_constraints wildcard. + e.g. f :: (Eq a, C a, _) => a -> a + Quantify over (psig_theta ++ diff) + where diff = min_theta - psig_theta, using findInferredDiff. + In our example, diff = Ix a - * is the result of - findInferredDiff (Eq a, C a) - in GHC.Tc.Gen.Bind.chooseInferredQuantifiers +Some rationale and observations - * is the theta returned right here, - by decideQuantification +* See Note [When the MR applies] in GHC.Tc.Gen.Bind. -At least for single functions we would like to quantify f over -precisely the same theta as , so that we get to take -the short-cut path in GHC.Tc.Gen.Bind.mkExport, and avoid calling -tcSubTypeSigma for impedance matching. Why avoid? Because it falls -over for ambiguous types (#20921). +* We always want to quantify over psig_theta (if present). The user specified + it! And pickQuantifiableCandidates might have dropped some + e.g. CallStack constraints. c.f #14658 + equalities (a ~ Bool) -We can get precisely the same theta by using the same algorithm, -findInferredDiff. +* In case (P3) we ask that /all/ the signatures have an extra-constraints + wildcard. It's a bit arbitrary; not clear what the "right" thing is. -All of this goes wrong if we have (a) mutual recursion, (b) multiple -partial type signatures, (c) with different constraints, and (d) -ambiguous types. Something like +* It's helpful to use the same "find difference" algorithm, `findInferredDiff`, + here as we use in GHC.Tc.Gen.Bind.chooseInferredQuantifiers (#20921) + + At least for single functions we would like to quantify f over precisely the + same theta as , so that we get to take the short-cut path in + `GHC.Tc.Gen.Bind.mkExport`, and avoid calling `tcSubTypeSigma` for impedance + matching. Why avoid? Because it falls over for ambiguous types (#20921). + + We can get precisely the same theta by using the same algorithm, + `findInferredDiff`. + +* All of this goes wrong if we have (a) mutual recursion, (b) multiple + partial type signatures, (c) with different constraints, and (d) + ambiguous types. Something like f :: forall a. Eq a => F a -> _ f x = (undefined :: a) == g x undefined g :: forall b. Show b => F b -> _ -> b g x y = let _ = (f y, show x) in x -But that's a battle for another day. + But that's a battle for another day. -} decidePromotedTyVars :: InferMode @@ -1704,7 +1725,7 @@ decidePromotedTyVars infer_mode name_taus psigs candidates -- by some variable that is free in the env't mono_tvs = (mono_tvs2 `unionVarSet` constrained_tvs) - `delVarSetList` psig_qtvs + `delVarSetList` psig_qtvs -- (`delVarSetList` psig_qtvs): if the user has explicitly -- asked for quantification, then that request "wins" -- over the MR. @@ -1723,6 +1744,8 @@ decidePromotedTyVars infer_mode name_taus psigs candidates ; traceTc "decidePromotedTyVars" $ vcat [ text "infer_mode =" <+> ppr infer_mode + , text "psigs =" <+> ppr psigs + , text "psig_qtvs =" <+> ppr psig_qtvs , text "mono_tvs0 =" <+> ppr mono_tvs0 , text "no_quant =" <+> ppr no_quant , text "maybe_quant =" <+> ppr maybe_quant @@ -1844,7 +1867,8 @@ decideQuantifiedTyVars skol_info name_taus psigs candidates -- See Note [pickQuantifiablePreds] pickQuantifiablePreds :: TyVarSet -- Quantifying over these - -> TcTyVarSet -- These ones are free in the enviroment + -> TcTyVarSet -- mono_tvs0: variables mentioned a candidate + -- constraint that come from some outer level -> TcThetaType -- Proposed constraints to quantify -> TcM TcThetaType -- A subset that we can actually quantify -- This function decides whether a particular constraint should be @@ -1856,9 +1880,9 @@ pickQuantifiablePreds qtvs mono_tvs0 theta mapMaybe (pick_me is_nested) theta) } where pick_me is_nested pred - | let pred_tvs = tyCoVarsOfType pred + = let pred_tvs = tyCoVarsOfType pred mentions_qtvs = pred_tvs `intersectsVarSet` qtvs - = case classifyPredType pred of + in case classifyPredType pred of ClassPred cls tys | Just {} <- isCallStackPred cls tys @@ -2109,15 +2133,16 @@ Definitely not. Since we're not quantifying over beta, it has been promoted; and then will be zapped to Any in the final zonk. So we end up with a (perhaps exported) type involving forall a. Zork a (Z [Char]) Any => blah -No no no. We never want to show the programmer a type with `Any` in it. +No no no: + + Key principle: we never want to show the programmer + a type with `Any` in it. What we really want (to catch the Zork example) is this: -Hence, for a top-level binding, we eliminate the candidate from the -pool, by asking - Do not quantify over the constraint if it mentions a variable that is - (a) not quantified (i.e. is determined by the type environment), but - (b) do not appear literally in the environment (mono_tvs0)? + Quantify over the constraint only if all its free variables are + (a) quantified, or + (b) appears in the type of something in the environment (mono_tvs0). To understand (b) consider @@ -2131,14 +2156,24 @@ In `f1` should we quantify over that `(C b alpha)`? Answer: since `alpha` is free in the type envt, yes we should. After all, if we'd typechecked `intify` first, we'd have set `alpha := Int`, and /then/ we'd certainly quantify. The delicate Zork situation applies when beta is completely -unconstrained -- except by the fudep. - -However this subtle reasoning is needed only for /top-level/ declarations. -For /nested/ decls we can see all the calls, so we'll instantiate that -quantifed `Zork a (Z [Char]) beta` constraint at call sites, and either solve -it or not (probably not). We won't be left with a still-callable function -with Any in its type. So for nested definitions we don't make this tricky -test. +unconstrained (not free in the environment) -- except by the fundep. + +Another way to put it: let's say `alpha` is in `mono_tvs0`. It must be that +some variable `x` has `alpha` free in its type. If we are at top-level (and we +are, because nested decls don't go through this path all), then `x` must also +be at top-level. And, by induction, `x` will not have Any in its type when all +is said and done. The induction is well-founded because, if `x` is mutually +recursive with the definition at hand, then their constraints get processed +together (or `x` has a type signature, in which case the type doesn't have +`Any`). So the key thing is that we must not introduce a new top-level +unconstrained variable here. + +However this regrettably-subtle reasoning is needed only for /top-level/ +declarations. For /nested/ decls we can see all the calls, so we'll +instantiate that quantifed `Zork a (Z [Char]) beta` constraint at call sites, +and either solve it or not (probably not). We won't be left with a +still-callable function with Any in its type. So for nested definitions we +don't make this tricky test. Historical note: we had a different, and more complicated test before, but it was utterly wrong: #23199. @@ -3155,32 +3190,41 @@ defaultTyVarTcS the_tv | otherwise = return False -- the common case -approximateWC :: Bool -> WantedConstraints -> Cts +approximateWC :: Bool -- See Wrinkle (W3) in Note [ApproximateWC] + -> WantedConstraints + -> Cts -- Second return value is the depleted wc --- Third return value is YesFDsCombined <=> multiple constraints for the same fundep floated -- Postcondition: Wanted Cts -- See Note [ApproximateWC] -- See Note [floatKindEqualities vs approximateWC] approximateWC float_past_equalities wc - = float_wc emptyVarSet wc + = float_wc False emptyVarSet wc where - float_wc :: TcTyCoVarSet -> WantedConstraints -> Cts - float_wc trapping_tvs (WC { wc_simple = simples, wc_impl = implics }) - = filterBag (is_floatable trapping_tvs) simples `unionBags` - concatMapBag (float_implic trapping_tvs) implics - float_implic :: TcTyCoVarSet -> Implication -> Cts - float_implic trapping_tvs imp - | float_past_equalities || ic_given_eqs imp /= MaybeGivenEqs - = float_wc new_trapping_tvs (ic_wanted imp) - | otherwise -- Take care with equalities - = emptyCts -- See (1) under Note [ApproximateWC] + float_wc :: Bool -- True <=> there are enclosing equalities + -> TcTyCoVarSet -- Enclosing skolem binders + -> WantedConstraints -> Cts + float_wc encl_eqs trapping_tvs (WC { wc_simple = simples, wc_impl = implics }) + = filterBag (is_floatable encl_eqs trapping_tvs) simples `unionBags` + concatMapBag (float_implic encl_eqs trapping_tvs) implics + + float_implic :: Bool -> TcTyCoVarSet -> Implication -> Cts + float_implic encl_eqs trapping_tvs imp + = float_wc new_encl_eqs new_trapping_tvs (ic_wanted imp) where new_trapping_tvs = trapping_tvs `extendVarSetList` ic_skols imp - - is_floatable skol_tvs ct - | isGivenCt ct = False - | insolubleEqCt ct = False - | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs + new_encl_eqs = encl_eqs || ic_given_eqs imp == MaybeGivenEqs + + is_floatable encl_eqs skol_tvs ct + | isGivenCt ct = False + | insolubleEqCt ct = False + | tyCoVarsOfCt ct `intersectsVarSet` skol_tvs = False + | otherwise + = case classifyPredType (ctPred ct) of + EqPred {} -> float_past_equalities || not encl_eqs + -- See Wrinkle (W1) + ClassPred {} -> True -- See Wrinkle (W2) + IrredPred {} -> True -- ..both in Note [ApproximateWC] + ForAllPred {} -> False {- Note [ApproximateWC] ~~~~~~~~~~~~~~~~~~~~~~~ @@ -3193,28 +3237,39 @@ out from inside, if they are not captured by skolems. The same function is used when doing type-class defaulting (see the call to applyDefaultingRules) to extract constraints that might be defaulted. -There is one caveat: - -1. When inferring most-general types (in simplifyInfer), we do *not* - float anything out if the implication binds equality constraints, - because that defeats the OutsideIn story. Consider - data T a where - TInt :: T Int - MkT :: T a - - f TInt = 3::Int - - We get the implication (a ~ Int => res ~ Int), where so far we've decided - f :: T a -> res - We don't want to float (res~Int) out because then we'll infer - f :: T a -> Int - which is only on of the possible types. (GHC 7.6 accidentally *did* - float out of such implications, which meant it would happily infer - non-principal types.) - - HOWEVER (#12797) in findDefaultableGroups we are not worried about - the most-general type; and we /do/ want to float out of equalities. - Hence the boolean flag to approximateWC. +Wrinkle (W1) + When inferring most-general types (in simplifyInfer), we + do *not* float an equality constraint if the implication binds + equality constraints, because that defeats the OutsideIn story. + Consider data T a where TInt :: T Int MkT :: T a + + f TInt = 3::Int + + We get the implication (a ~ Int => res ~ Int), where so far we've decided + f :: T a -> res + We don't want to float (res~Int) out because then we'll infer + f :: T a -> Int + which is only on of the possible types. (GHC 7.6 accidentally *did* + float out of such implications, which meant it would happily infer + non-principal types.) + +Wrinkle (W2) + We do allow /class/ constraints to float, even if + the implication binds equalities. This is a subtle point: see #23224. + In principle, a class constraint might ultimately be satisfiable from + a constraint bound by an implication (see #19106 for an example of this + kind), but it's extremely obscure and I was unable to construct a + concrete example. In any case, in super-subtle cases where this might + make a difference, you would be much better advised to simply write a + type signature. + + I included IrredPred here too, for good measure. In general, + abstracting over more constraints does no harm. + +Wrinkle (W3) + In findDefaultableGroups we are not worried about the + most-general type; and we /do/ want to float out of equalities + (#12797). Hence the boolean flag to approximateWC. ------ Historical note ----------- There used to be a second caveat, driven by #8155 ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -591,9 +591,7 @@ data CtOrigin | IfThenElseOrigin -- An if-then-else expression | BracketOrigin -- An overloaded quotation bracket | StaticOrigin -- A static form - | Shouldn'tHappenOrigin String - -- the user should never see this one - | GhcBug20076 -- see #20076 + | Shouldn'tHappenOrigin String -- The user should never see this one -- | Testing whether the constraint associated with an instance declaration -- in a signature file is satisfied upon instantiation. @@ -819,13 +817,6 @@ pprCtOrigin (Shouldn'tHappenOrigin note) , text "https://gitlab.haskell.org/ghc/ghc/wikis/report-a-bug >>" ] -pprCtOrigin GhcBug20076 - = vcat [ text "GHC Bug #20076 " - , text "Assuming you have a partial type signature, you can avoid this error" - , text "by either adding an extra-constraints wildcard (like `(..., _) => ...`," - , text "with the underscore at the end of the constraint), or by avoiding the" - , text "use of a simplifiable constraint in your partial type signature." ] - pprCtOrigin (ProvCtxtOrigin PSB{ psb_id = (L _ name) }) = hang (ctoHerald <+> text "the \"provided\" constraints claimed by") 2 (text "the signature of" <+> quotes (ppr name)) @@ -927,7 +918,6 @@ pprCtO (ProvCtxtOrigin {}) = text "a provided constraint" pprCtO (InstProvidedOrigin {}) = text "a provided constraint" pprCtO (CycleBreakerOrigin orig) = pprCtO orig pprCtO (FRROrigin {}) = text "a representation-polymorphism check" -pprCtO GhcBug20076 = text "GHC Bug #20076" pprCtO (WantedSuperclassOrigin {}) = text "a superclass constraint" pprCtO (InstanceSigOrigin {}) = text "a type signature in an instance" pprCtO (AmbiguityCheckOrigin {}) = text "a type ambiguity check" ===================================== testsuite/tests/partial-sigs/should_compile/T10403.stderr ===================================== @@ -14,41 +14,17 @@ T10403.hs:16:12: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] • In the type signature: h1 :: _ => _ T10403.hs:20:7: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ - standing for ‘(a1 -> a2) -> f0 a1 -> H f0’ - Where: ‘f0’ is an ambiguous type variable - ‘a2’, ‘a1’ are rigid type variables bound by - the inferred type of h2 :: (a1 -> a2) -> f0 a1 -> H f0 + • Found type wildcard ‘_’ standing for ‘(a1 -> a2) -> f a1 -> H f’ + Where: ‘a2’, ‘a1’, ‘f’ are rigid type variables bound by + the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f at T10403.hs:23:1-41 • In the type signature: h2 :: _ T10403.hs:23:15: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)] - • Ambiguous type variable ‘f0’ arising from a use of ‘fmap’ - prevents the constraint ‘(Functor f0)’ from being solved. - Relevant bindings include - b :: f0 a1 (bound at T10403.hs:23:6) - h2 :: (a1 -> a2) -> f0 a1 -> H f0 (bound at T10403.hs:23:1) - Probable fix: use a type annotation to specify what ‘f0’ should be. - Potentially matching instances: - instance Functor IO -- Defined in ‘GHC.Base’ - instance Functor (B t) -- Defined at T10403.hs:11:10 - ...plus 8 others - ...plus one instance involving out-of-scope types - (use -fprint-potential-instances to see them all) + • No instance for ‘Functor f’ arising from a use of ‘fmap’ + Possible fix: + add (Functor f) to the context of + the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f • In the second argument of ‘(.)’, namely ‘fmap (const ())’ In the expression: (H . fmap (const ())) (fmap f b) In an equation for ‘h2’: h2 f b = (H . fmap (const ())) (fmap f b) - -T10403.hs:29:8: warning: [GHC-46956] [-Wdeferred-type-errors (in -Wdefault)] - • Couldn't match type ‘f0’ with ‘B t’ - Expected: H (B t) - Actual: H f0 - • because type variable ‘t’ would escape its scope - This (rigid, skolem) type variable is bound by - the type signature for: - app2 :: forall t. H (B t) - at T10403.hs:28:1-15 - • In the expression: h2 (H . I) (B ()) - In an equation for ‘app2’: app2 = h2 (H . I) (B ()) - • Relevant bindings include - app2 :: H (B t) (bound at T10403.hs:29:1) ===================================== testsuite/tests/partial-sigs/should_compile/T19106.hs ===================================== @@ -3,6 +3,13 @@ module T19106 where +-- This is a very subtle program: +-- From the body of the function we get [W] Show a +-- That can be satisfied only from the /combination/ of +-- [G] a ~ [b] from type sig +-- [G] G a from pattern match (MkT x) +-- The type instance G [b] = Show b + f :: (a ~ [b]) => T a -> _ -> String f (MkT x) _ = show x ===================================== testsuite/tests/partial-sigs/should_compile/all.T ===================================== @@ -71,7 +71,7 @@ test('T10519', normal, compile, ['']) test('T10463', normal, compile, ['']) test('ExprSigLocal', normal, compile, ['']) test('T11016', normal, compile, ['']) -test('T11192', normal, compile, ['']) +test('T11192', expect_broken(23232), compile, ['']) test('SuperCls', normal, compile, ['']) test('T12033', normal, compile, ['']) test('T11339a', normal, compile, ['']) ===================================== testsuite/tests/partial-sigs/should_fail/T23223.hs ===================================== @@ -0,0 +1,5 @@ +{-# LANGUAGE PartialTypeSignatures #-} +module Foo where + +f :: (Show a) => a -> _ -> Bool +f x y = x>x ===================================== testsuite/tests/partial-sigs/should_fail/T23223.stderr ===================================== @@ -0,0 +1,11 @@ + +T23223.hs:5:10: error: [GHC-39999] + • Could not deduce ‘Ord a’ arising from a use of ‘>’ + from the context: Show a + bound by the inferred type of f :: Show a => a -> w -> Bool + at T23223.hs:5:1-11 + Possible fix: + add (Ord a) to the context of + the inferred type of f :: Show a => a -> w -> Bool + • In the expression: x > x + In an equation for ‘f’: f x y = x > x ===================================== testsuite/tests/partial-sigs/should_fail/all.T ===================================== @@ -1,6 +1,6 @@ test('AnnotatedConstraint', normal, compile_fail, ['']) test('AnnotatedConstraintNotForgotten', normal, compile_fail, ['']) -test('Defaulting1MROff', normal, compile, ['']) +test('Defaulting1MROff', expect_broken(23232), compile, ['']) test('ExtraConstraintsWildcardInExpressionSignature', normal, compile, ['']) test('ExtraConstraintsWildcardInPatternSignature', normal, compile_fail, ['']) test('ExtraConstraintsWildcardInPatternSplice', [req_interp, normal], compile_fail, ['']) @@ -58,7 +58,7 @@ test('WildcardInTypeSynonymRHS', normal, compile_fail, ['']) test('T10615', normal, compile_fail, ['']) test('T10045', normal, compile_fail, ['']) test('T10999', normalise_fun(normalise_errmsg), compile_fail, ['']) -test('T11122', normal, compile, ['']) +test('T11122', expect_broken(23232), compile, ['']) test('T11515', normal, compile_fail, ['']) test('T11976', normal, compile_fail, ['']) test('PatBind3', normal, compile_fail, ['']) @@ -72,3 +72,4 @@ test('T14449', normal, compile_fail, ['']) test('T14479', normal, compile_fail, ['']) test('T14584', normal, compile, ['']) test('T14584a', normal, compile, ['']) +test('T23223', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58df60df7efe9e7920d962da3525a35826608b2d...7d6284dacc3bf215bfe55006e830583b0d163074 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58df60df7efe9e7920d962da3525a35826608b2d...7d6284dacc3bf215bfe55006e830583b0d163074 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 22:27:21 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 18:27:21 -0400 Subject: [Git][ghc/ghc][master] Add release note for GHC.Unicode refactor in base-4.18. Message-ID: <643098c987e3_3b005551486e9871754@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - 1 changed file: - libraries/base/changelog.md Changes: ===================================== libraries/base/changelog.md ===================================== @@ -7,8 +7,6 @@ * Add `Data.List.!?` ([CLC proposal #110](https://github.com/haskell/core-libraries-committee/issues/110)) * `maximumBy`/`minimumBy` are now marked as `INLINE` improving performance for unpackable types significantly. - * Refactor `generalCategory` to stop very large literal string being inlined to call-sites. - ([CLC proposal #130](https://github.com/haskell/core-libraries-committee/issues/130)) * Add INLINABLE pragmas to `generic*` functions in Data.OldList ([CLC proposal #129](https://github.com/haskell/core-libraries-committee/issues/130)) * Export `getSolo` from `Data.Tuple`. ([CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113)) @@ -23,7 +21,7 @@ ([CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149)) * Make `($)` representation polymorphic ([CLC proposal #132](https://github.com/haskell/core-libraries-committee/issues/132)) -## 4.18.0.0 *TBA* +## 4.18.0.0 *March 2023* * Shipped with GHC 9.6.1 * `Foreign.C.ConstPtr.ConstrPtr` was added to encode `const`-qualified pointer types in foreign declarations when using `CApiFFI` extension. ([CLC proposal #117](https://github.com/haskell/core-libraries-committee/issues/117)) @@ -61,6 +59,9 @@ ([CLC proposal #50](https://github.com/haskell/core-libraries-committee/issues/50), [the migration guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md)) + * Switch to a pure Haskell implementation of `GHC.Unicode` + ([CLC proposals #59](https://github.com/haskell/core-libraries-committee/issues/59) + and [#130](https://github.com/haskell/core-libraries-committee/issues/130)) * Update to [Unicode 15.0.0](https://www.unicode.org/versions/Unicode15.0.0/). * Add standard Unicode case predicates `isUpperCase` and `isLowerCase` to `GHC.Unicode` and `Data.Char`. These predicates use the standard Unicode View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c990e13c36b7be7d3bd3af050ad49182a028f21 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c990e13c36b7be7d3bd3af050ad49182a028f21 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 22:28:04 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 18:28:04 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Improve documentation for ($) (#22963) Message-ID: <643098f42a5ee_3b0055515a2d187224b8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 1 changed file: - libraries/base/GHC/Base.hs Changes: ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1606,18 +1606,69 @@ flip f x y = f y x -- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now -- it is equivalent to undefined `seq` () which diverges. --- | Application operator. This operator is redundant, since ordinary --- application @(f x)@ means the same as @(f '$' x)@. However, '$' has --- low, right-associative binding precedence, so it sometimes allows --- parentheses to be omitted; for example: --- --- > f $ g $ h x = f (g (h x)) --- --- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, --- or @'Data.List.zipWith' ('$') fs xs at . --- --- Note that @('$')@ is representation-polymorphic, so that --- @foo '$' 4#@ where @foo :: Int# -> Int#@ is well-typed. +{- | @($)@ is the __function application__ operator. + +Applying @($)@ to a function @f@ and an argument @x@ gives the same result as applying @f@ to @x@ directly. The definition is akin to this: + +@ +($) :: (a -> b) -> a -> b +($) f x = f x +@ + +On the face of it, this may appear pointless! But it's actually one of the most useful and important operators in Haskell. + +The order of operations is very different between @($)@ and normal function application. Normal function application has precedence 10 - higher than any operator - and associates to the left. So these two definitions are equivalent: + +@ +expr = min 5 1 + 5 +expr = ((min 5) 1) + 5 +@ + +@($)@ has precedence 0 (the lowest) and associates to the right, so these are equivalent: + +@ +expr = min 5 $ 1 + 5 +expr = (min 5) (1 + 5) +@ + +=== Uses + +A common use cases of @($)@ is to avoid parentheses in complex expressions. + +For example, instead of using nested parentheses in the following + Haskell function: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' ('Data.Maybe.mapMaybe' 'Text.Read.readMaybe' ('words' s)) +@ + +we can deploy the function application operator: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' '$' 'Data.Maybe.mapMaybe' 'Text.Read.readMaybe' '$' 'words' s +@ + +@($)@ is also used as a section (a partially applied operator), in order to indicate that we wish to apply some yet-unspecified function to a given value. For example, to apply the argument @5@ to a list of functions: + +@ +applyFive :: [Int] +applyFive = map ($ 5) [(+1), (2^)] +>>> [6, 32] +@ + +=== Technical Remark (Representation Polymorphism) + +@($)@ is fully representation-polymorphic. This allows it to also be used with arguments of unlifted and even unboxed kinds, such as unboxed integers: + +@ +fastMod :: Int -> Int -> Int +fastMod (I# x) (I# m) = I# $ remInt# x m +@ +-} {-# INLINE ($) #-} ($) :: forall repa repb (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ($) f = f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c990e13c36b7be7d3bd3af050ad49182a028f21...b384523bab0650ba1e6b09f3c7aa64a92a90fe3b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c990e13c36b7be7d3bd3af050ad49182a028f21...b384523bab0650ba1e6b09f3c7aa64a92a90fe3b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 23:18:39 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 07 Apr 2023 19:18:39 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 31 commits: JS: Linker: use saturated JExpr Message-ID: <6430a4cf38069_3b0055524a584c7240fa@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 90eb4d85 by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - a96b14fd by Simon Peyton Jones at 2023-04-06T10:47:36+01:00 Add some documentation about redundant constraints - - - - - 65fd65ab by Simon Peyton Jones at 2023-04-07T22:28:57+01:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 7d6284da by Simon Peyton Jones at 2023-04-07T22:29:24+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 04bb9568 by Simon Peyton Jones at 2023-04-07T22:34:11+01:00 First steps killing unifyWanted - - - - - 7e585596 by Simon Peyton Jones at 2023-04-07T22:34:11+01:00 Fix a boo boo - - - - - cc990ff8 by Simon Peyton Jones at 2023-04-07T22:34:11+01:00 Fix another error: missing kick-out - - - - - b691a4dc by Simon Peyton Jones at 2023-04-07T22:34:11+01:00 Maybe working now - - - - - 697a5710 by Simon Peyton Jones at 2023-04-07T22:34:11+01:00 Wibbles - - - - - 9db42e84 by Simon Peyton Jones at 2023-04-07T23:04:53+01:00 Stop loop - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec8d3344bce8fceddc158e1c4ce9e5e31695e4a2...9db42e84401798e8eedf43a2287e9aa74ac8f209 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec8d3344bce8fceddc158e1c4ce9e5e31695e4a2...9db42e84401798e8eedf43a2287e9aa74ac8f209 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 7 23:29:27 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 19:29:27 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Improve documentation for ($) (#22963) Message-ID: <6430a7571aef2_3b005552a2969c7260df@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 551b74c7 by Torsten Schmits at 2023-04-07T19:29:13-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6ff849e2 by sheaf at 2023-04-07T19:29:18-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - 14 changed files: - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Reader.hs - libraries/base/GHC/Base.hs - testsuite/tests/backpack/should_fail/bkpfail29.stderr - testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr - testsuite/tests/module/mod27.stderr - + testsuite/tests/rename/should_compile/T23240.hs - + testsuite/tests/rename/should_compile/T23240_aux.hs - testsuite/tests/rename/should_compile/all.T Changes: ===================================== compiler/GHC/Rename/Env.hs ===================================== @@ -534,30 +534,29 @@ lookupRecFieldOcc mb_con rdr_name = return $ mk_unbound_rec_fld con | Just con <- mb_con = do { let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - ; res <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] + ; mb_nm <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] do { flds <- lookupConstructorFields con ; env <- getGlobalRdrEnv - ; let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - mb_gre = do fl <- find ((== lbl) . flLabel) flds + ; let mb_gre = do fl <- find ((== lbl) . flLabel) flds -- We have the label, now check it is in scope. If -- there is a qualifier, use pickGREs to check that -- the qualifier is correct, and return the filtered -- GRE so we get import usage right (see #17853). gre <- lookupGRE_FieldLabel env fl if isQual rdr_name - then listToMaybe (pickGREs rdr_name [gre]) + then listToMaybe $ pickGREs rdr_name [gre] else return gre ; traceRn "lookupRecFieldOcc" $ vcat [ text "mb_con:" <+> ppr mb_con , text "rdr_name:" <+> ppr rdr_name , text "flds:" <+> ppr flds , text "mb_gre:" <+> ppr mb_gre ] - ; return mb_gre } - ; case res of + ; mapM_ (addUsedGRE True) mb_gre + ; return $ flSelector . fieldGRELabel <$> mb_gre } + ; case mb_nm of { Nothing -> do { addErr (badFieldConErr con lbl) ; return $ mk_unbound_rec_fld con } - ; Just gre -> do { addUsedGRE True gre - ; return (flSelector $ fieldGRELabel gre) } } } + ; Just nm -> return nm } } | otherwise -- Can't use the data constructor to disambiguate = greName <$> lookupGlobalOccRn' (IncludeFields WantField) rdr_name @@ -572,7 +571,9 @@ lookupRecFieldOcc mb_con rdr_name mkRecFieldOccFS (getOccFS con) (occNameFS occ) occ = rdrNameOcc rdr_name - ensure_recfld gre = do { guard (isRecFldGRE gre) ; return gre } + ensure_recfld :: GlobalRdrElt -> Maybe Name + ensure_recfld gre = do { guard (isRecFldGRE gre) + ; return $ greName gre } {- Note [DisambiguateRecordFields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1855,7 +1855,10 @@ mkImportMap gres RealSrcLoc decl_loc _ -> Map.insertWith add decl_loc [gre] imp_map UnhelpfulLoc _ -> imp_map where - best_imp_spec = bestImport (bagToList imp_specs) + best_imp_spec = + case bagToList imp_specs of + [] -> pprPanic "mkImportMap: GRE with no ImportSpecs" (ppr gre) + is:iss -> bestImport (is NE.:| iss) add _ gres = gre : gres warnUnusedImport :: WarningFlag -> GlobalRdrEnv ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1716,6 +1716,18 @@ instance Diagnostic TcRnMessage where -> mkSimpleDecorated $ text "Illegal" <+> (text $ levelString typeOrKind) <> colon <+> quotes (ppr thing) + TcRnTypeSynonymCycle decl_or_tcs + -> mkSimpleDecorated $ + sep [ text "Cycle in type synonym declarations:" + , nest 2 (vcat (map ppr_decl decl_or_tcs)) ] + where + ppr_decl = \case + Right (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl + Left tc -> + let n = tyConName tc + in ppr (getSrcSpan n) <> colon <+> ppr (tyConName tc) + <+> text "from external module" + diagnosticReason = \case TcRnUnknownMessage m @@ -2286,6 +2298,8 @@ instance Diagnostic TcRnMessage where -> WarningWithFlag Opt_WarnUnusedForalls TcRnDataKindsError{} -> ErrorWithoutFlag + TcRnTypeSynonymCycle{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -2883,6 +2897,8 @@ instance Diagnostic TcRnMessage where -> noHints TcRnDataKindsError{} -> [suggestExtension LangExt.DataKinds] + TcRnTypeSynonymCycle{} + -> noHints diagnosticCode = constructorCode ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -108,6 +108,7 @@ module GHC.Tc.Errors.Types ( , TyFamsDisabledReason(..) , HsTypeOrSigType(..) , HsTyVarBndrExistentialFlag(..) + , TySynCycleTyCons ) where import GHC.Prelude @@ -3787,6 +3788,15 @@ data TcRnMessage where -> HsExpr GhcPs -- ^ Section -> TcRnMessage + {-| TcRnTypeSynonymCycle is an error indicating that a cycle between type + synonyms has occurred. + + Test cases: + mod27, ghc-e-fail2, bkpfail29 + -} + TcRnTypeSynonymCycle :: !TySynCycleTyCons -- ^ The tycons involved in the cycle + -> TcRnMessage + deriving Generic -- | Things forbidden in @type data@ declarations. @@ -5192,3 +5202,6 @@ data HsTyVarBndrExistentialFlag = forall flag. OutputableBndrFlag flag 'Renamed instance Outputable HsTyVarBndrExistentialFlag where ppr (HsTyVarBndrExistentialFlag hsTyVarBndr) = ppr hsTyVarBndr + +type TySynCycleTyCons = + [Either TyCon (LTyClDecl GhcRn)] ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -65,7 +65,6 @@ import GHC.Data.FastString import GHC.Unit.Module import GHC.Types.Basic -import GHC.Types.Error import GHC.Types.FieldLabel import GHC.Types.SrcLoc import GHC.Types.SourceFile @@ -168,7 +167,7 @@ synonymTyConsOfType ty -- track of the TyCons which are known to be acyclic, or -- a failure message reporting that a cycle was found. newtype SynCycleM a = SynCycleM { - runSynCycleM :: SynCycleState -> Either (SrcSpan, SDoc) (a, SynCycleState) } + runSynCycleM :: SynCycleState -> Either (SrcSpan, TySynCycleTyCons) (a, SynCycleState) } deriving (Functor) -- TODO: TyConSet is implemented as IntMap over uniques. @@ -188,8 +187,8 @@ instance Monad SynCycleM where runSynCycleM (f x) state' Left err -> Left err -failSynCycleM :: SrcSpan -> SDoc -> SynCycleM () -failSynCycleM loc err = SynCycleM $ \_ -> Left (loc, err) +failSynCycleM :: SrcSpan -> TySynCycleTyCons -> SynCycleM () +failSynCycleM loc seen_tcs = SynCycleM $ \_ -> Left (loc, seen_tcs) -- | Test if a 'Name' is acyclic, short-circuiting if we've -- seen it already. @@ -209,7 +208,7 @@ checkTyConIsAcyclic tc m = SynCycleM $ \s -> checkSynCycles :: Unit -> [TyCon] -> [LTyClDecl GhcRn] -> TcM () checkSynCycles this_uid tcs tyclds = case runSynCycleM (mapM_ (go emptyTyConSet []) tcs) emptyTyConSet of - Left (loc, err) -> setSrcSpan loc $ failWithTc (mkTcRnUnknownMessage $ mkPlainError noHints err) + Left (loc, err) -> setSrcSpan loc $ failWithTc (TcRnTypeSynonymCycle err) Right _ -> return () where -- Try our best to print the LTyClDecl for locally defined things @@ -226,9 +225,7 @@ checkSynCycles this_uid tcs tyclds = go' :: TyConSet -> [TyCon] -> TyCon -> SynCycleM () go' so_far seen_tcs tc | tc `elemTyConSet` so_far - = failSynCycleM (getSrcSpan (head seen_tcs)) $ - sep [ text "Cycle in type synonym declarations:" - , nest 2 (vcat (map ppr_decl seen_tcs)) ] + = failSynCycleM (getSrcSpan (head seen_tcs)) (lookup_decl <$> seen_tcs) -- Optimization: we don't allow cycles through external packages, -- so once we find a non-local name we are guaranteed to not -- have a cycle. @@ -245,13 +242,10 @@ checkSynCycles this_uid tcs tyclds = where n = tyConName tc mod = nameModule n - ppr_decl tc = - case lookupNameEnv lcl_decls n of - Just (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl - Nothing -> ppr (getSrcSpan n) <> colon <+> ppr n - <+> text "from external module" - where - n = tyConName tc + lookup_decl tc = + case lookupNameEnv lcl_decls (tyConName tc) of + Just decl -> Right decl + Nothing -> Left tc go_ty :: TyConSet -> [TyCon] -> Type -> SynCycleM () go_ty so_far seen_tcs ty = ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -578,6 +578,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnRoleAnnotationsDisabled" = 17779 GhcDiagnosticCode "TcRnIncoherentRoles" = 18273 GhcDiagnosticCode "TcRnTyFamNameMismatch" = 88221 + GhcDiagnosticCode "TcRnTypeSynonymCycle" = 97522 -- TcRnBadFieldAnnotation/BadFieldAnnotationReason GhcDiagnosticCode "LazyFieldsDisabled" = 81601 ===================================== compiler/GHC/Types/Name/Reader.hs ===================================== @@ -126,7 +126,6 @@ import GHC.Utils.Panic import Control.DeepSeq import Control.Monad ( guard ) import Data.Data -import Data.List ( sortBy ) import qualified Data.List.NonEmpty as NE import qualified Data.Map.Strict as Map import qualified Data.Semigroup as S @@ -1654,12 +1653,9 @@ data ImpItemSpec -- only @T@ is named explicitly. deriving (Eq, Data) -bestImport :: [ImportSpec] -> ImportSpec +bestImport :: NE.NonEmpty ImportSpec -> ImportSpec -- See Note [Choosing the best import declaration] -bestImport iss - = case sortBy best iss of - (is:_) -> is - [] -> pprPanic "bestImport" (ppr iss) +bestImport iss = NE.head $ NE.sortBy best iss where best :: ImportSpec -> ImportSpec -> Ordering -- Less means better ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1606,18 +1606,69 @@ flip f x y = f y x -- (\x -> undefined x) `seq` () and thus would just evaluate to (), but now -- it is equivalent to undefined `seq` () which diverges. --- | Application operator. This operator is redundant, since ordinary --- application @(f x)@ means the same as @(f '$' x)@. However, '$' has --- low, right-associative binding precedence, so it sometimes allows --- parentheses to be omitted; for example: --- --- > f $ g $ h x = f (g (h x)) --- --- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@, --- or @'Data.List.zipWith' ('$') fs xs at . --- --- Note that @('$')@ is representation-polymorphic, so that --- @foo '$' 4#@ where @foo :: Int# -> Int#@ is well-typed. +{- | @($)@ is the __function application__ operator. + +Applying @($)@ to a function @f@ and an argument @x@ gives the same result as applying @f@ to @x@ directly. The definition is akin to this: + +@ +($) :: (a -> b) -> a -> b +($) f x = f x +@ + +On the face of it, this may appear pointless! But it's actually one of the most useful and important operators in Haskell. + +The order of operations is very different between @($)@ and normal function application. Normal function application has precedence 10 - higher than any operator - and associates to the left. So these two definitions are equivalent: + +@ +expr = min 5 1 + 5 +expr = ((min 5) 1) + 5 +@ + +@($)@ has precedence 0 (the lowest) and associates to the right, so these are equivalent: + +@ +expr = min 5 $ 1 + 5 +expr = (min 5) (1 + 5) +@ + +=== Uses + +A common use cases of @($)@ is to avoid parentheses in complex expressions. + +For example, instead of using nested parentheses in the following + Haskell function: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' ('Data.Maybe.mapMaybe' 'Text.Read.readMaybe' ('words' s)) +@ + +we can deploy the function application operator: + +@ +-- | Sum numbers in a string: strSum "100 5 -7" == 98 +strSum :: 'String' -> 'Int' +strSum s = 'sum' '$' 'Data.Maybe.mapMaybe' 'Text.Read.readMaybe' '$' 'words' s +@ + +@($)@ is also used as a section (a partially applied operator), in order to indicate that we wish to apply some yet-unspecified function to a given value. For example, to apply the argument @5@ to a list of functions: + +@ +applyFive :: [Int] +applyFive = map ($ 5) [(+1), (2^)] +>>> [6, 32] +@ + +=== Technical Remark (Representation Polymorphism) + +@($)@ is fully representation-polymorphic. This allows it to also be used with arguments of unlifted and even unboxed kinds, such as unboxed integers: + +@ +fastMod :: Int -> Int -> Int +fastMod (I# x) (I# m) = I# $ remInt# x m +@ +-} {-# INLINE ($) #-} ($) :: forall repa repb (a :: TYPE repa) (b :: TYPE repb). (a -> b) -> a -> b ($) f = f ===================================== testsuite/tests/backpack/should_fail/bkpfail29.stderr ===================================== @@ -5,7 +5,7 @@ [3 of 3] Processing r [1 of 4] Compiling A[sig] ( r/A.hsig, nothing ) -bkpfail29.bkp:8:9: error: +bkpfail29.bkp:8:9: error: [GHC-97522] • Cycle in type synonym declarations: bkpfail29.bkp:8:9-18: S from external module bkpfail29.bkp:7:9-14: T from external module ===================================== testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr ===================================== @@ -1,5 +1,5 @@ -:0:1: error: +:0:1: error: [GHC-97522] Cycle in type synonym declarations: :0:1-10: type A = A 1 ===================================== testsuite/tests/module/mod27.stderr ===================================== @@ -1,5 +1,5 @@ -mod27.hs:3:1: error: +mod27.hs:3:1: error: [GHC-97522] Cycle in type synonym declarations: mod27.hs:3:1-18: type T1 = (Int, T2) mod27.hs:4:1-18: type T2 = (Int, T1) ===================================== testsuite/tests/rename/should_compile/T23240.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +-- Crucial to triggering the bug. +{-# LANGUAGE DisambiguateRecordFields #-} + +-- Need to enable the unused imports warning to trigger the bug. +{-# OPTIONS_GHC -Wunused-imports #-} + +module T23240 ( test ) where +import T23240_aux ( D, mkD ) + +test :: D +test = $$mkD ===================================== testsuite/tests/rename/should_compile/T23240_aux.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +module T23240_aux where + +import Language.Haskell.TH ( CodeQ ) + +data D = MkD { myFld :: () } +mkD :: CodeQ D +mkD = [|| MkD { myFld = () } ||] ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -209,3 +209,4 @@ test('ImportNullaryRecordWildcard', [extra_files(['NullaryRecordWildcard.hs', 'N test('GHCINullaryRecordWildcard', combined_output, ghci_script, ['GHCINullaryRecordWildcard.script']) test('GHCIImplicitImportNullaryRecordWildcard', combined_output, ghci_script, ['GHCIImplicitImportNullaryRecordWildcard.script']) test('T22122', [expect_broken(22122), extra_files(['T22122_aux.hs'])], multimod_compile, ['T22122', '-v0']) +test('T23240', [req_th, extra_files(['T23240_aux.hs'])], multimod_compile, ['T23240', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9fe52a1dbb53f07971f172a8502565109d2385e6...6ff849e25c4a5cf4d56611482014c9ddd46c4fa6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9fe52a1dbb53f07971f172a8502565109d2385e6...6ff849e25c4a5cf4d56611482014c9ddd46c4fa6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 8 02:29:44 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 22:29:44 -0400 Subject: [Git][ghc/ghc][master] Add structured error messages for GHC.Tc.TyCl.Utils Message-ID: <6430d198759f5_3b005555ad0fd47443e7@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 7 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/backpack/should_fail/bkpfail29.stderr - testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr - testsuite/tests/module/mod27.stderr Changes: ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1716,6 +1716,18 @@ instance Diagnostic TcRnMessage where -> mkSimpleDecorated $ text "Illegal" <+> (text $ levelString typeOrKind) <> colon <+> quotes (ppr thing) + TcRnTypeSynonymCycle decl_or_tcs + -> mkSimpleDecorated $ + sep [ text "Cycle in type synonym declarations:" + , nest 2 (vcat (map ppr_decl decl_or_tcs)) ] + where + ppr_decl = \case + Right (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl + Left tc -> + let n = tyConName tc + in ppr (getSrcSpan n) <> colon <+> ppr (tyConName tc) + <+> text "from external module" + diagnosticReason = \case TcRnUnknownMessage m @@ -2286,6 +2298,8 @@ instance Diagnostic TcRnMessage where -> WarningWithFlag Opt_WarnUnusedForalls TcRnDataKindsError{} -> ErrorWithoutFlag + TcRnTypeSynonymCycle{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -2883,6 +2897,8 @@ instance Diagnostic TcRnMessage where -> noHints TcRnDataKindsError{} -> [suggestExtension LangExt.DataKinds] + TcRnTypeSynonymCycle{} + -> noHints diagnosticCode = constructorCode ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -108,6 +108,7 @@ module GHC.Tc.Errors.Types ( , TyFamsDisabledReason(..) , HsTypeOrSigType(..) , HsTyVarBndrExistentialFlag(..) + , TySynCycleTyCons ) where import GHC.Prelude @@ -3787,6 +3788,15 @@ data TcRnMessage where -> HsExpr GhcPs -- ^ Section -> TcRnMessage + {-| TcRnTypeSynonymCycle is an error indicating that a cycle between type + synonyms has occurred. + + Test cases: + mod27, ghc-e-fail2, bkpfail29 + -} + TcRnTypeSynonymCycle :: !TySynCycleTyCons -- ^ The tycons involved in the cycle + -> TcRnMessage + deriving Generic -- | Things forbidden in @type data@ declarations. @@ -5192,3 +5202,6 @@ data HsTyVarBndrExistentialFlag = forall flag. OutputableBndrFlag flag 'Renamed instance Outputable HsTyVarBndrExistentialFlag where ppr (HsTyVarBndrExistentialFlag hsTyVarBndr) = ppr hsTyVarBndr + +type TySynCycleTyCons = + [Either TyCon (LTyClDecl GhcRn)] ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -65,7 +65,6 @@ import GHC.Data.FastString import GHC.Unit.Module import GHC.Types.Basic -import GHC.Types.Error import GHC.Types.FieldLabel import GHC.Types.SrcLoc import GHC.Types.SourceFile @@ -168,7 +167,7 @@ synonymTyConsOfType ty -- track of the TyCons which are known to be acyclic, or -- a failure message reporting that a cycle was found. newtype SynCycleM a = SynCycleM { - runSynCycleM :: SynCycleState -> Either (SrcSpan, SDoc) (a, SynCycleState) } + runSynCycleM :: SynCycleState -> Either (SrcSpan, TySynCycleTyCons) (a, SynCycleState) } deriving (Functor) -- TODO: TyConSet is implemented as IntMap over uniques. @@ -188,8 +187,8 @@ instance Monad SynCycleM where runSynCycleM (f x) state' Left err -> Left err -failSynCycleM :: SrcSpan -> SDoc -> SynCycleM () -failSynCycleM loc err = SynCycleM $ \_ -> Left (loc, err) +failSynCycleM :: SrcSpan -> TySynCycleTyCons -> SynCycleM () +failSynCycleM loc seen_tcs = SynCycleM $ \_ -> Left (loc, seen_tcs) -- | Test if a 'Name' is acyclic, short-circuiting if we've -- seen it already. @@ -209,7 +208,7 @@ checkTyConIsAcyclic tc m = SynCycleM $ \s -> checkSynCycles :: Unit -> [TyCon] -> [LTyClDecl GhcRn] -> TcM () checkSynCycles this_uid tcs tyclds = case runSynCycleM (mapM_ (go emptyTyConSet []) tcs) emptyTyConSet of - Left (loc, err) -> setSrcSpan loc $ failWithTc (mkTcRnUnknownMessage $ mkPlainError noHints err) + Left (loc, err) -> setSrcSpan loc $ failWithTc (TcRnTypeSynonymCycle err) Right _ -> return () where -- Try our best to print the LTyClDecl for locally defined things @@ -226,9 +225,7 @@ checkSynCycles this_uid tcs tyclds = go' :: TyConSet -> [TyCon] -> TyCon -> SynCycleM () go' so_far seen_tcs tc | tc `elemTyConSet` so_far - = failSynCycleM (getSrcSpan (head seen_tcs)) $ - sep [ text "Cycle in type synonym declarations:" - , nest 2 (vcat (map ppr_decl seen_tcs)) ] + = failSynCycleM (getSrcSpan (head seen_tcs)) (lookup_decl <$> seen_tcs) -- Optimization: we don't allow cycles through external packages, -- so once we find a non-local name we are guaranteed to not -- have a cycle. @@ -245,13 +242,10 @@ checkSynCycles this_uid tcs tyclds = where n = tyConName tc mod = nameModule n - ppr_decl tc = - case lookupNameEnv lcl_decls n of - Just (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl - Nothing -> ppr (getSrcSpan n) <> colon <+> ppr n - <+> text "from external module" - where - n = tyConName tc + lookup_decl tc = + case lookupNameEnv lcl_decls (tyConName tc) of + Just decl -> Right decl + Nothing -> Left tc go_ty :: TyConSet -> [TyCon] -> Type -> SynCycleM () go_ty so_far seen_tcs ty = ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -578,6 +578,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnRoleAnnotationsDisabled" = 17779 GhcDiagnosticCode "TcRnIncoherentRoles" = 18273 GhcDiagnosticCode "TcRnTyFamNameMismatch" = 88221 + GhcDiagnosticCode "TcRnTypeSynonymCycle" = 97522 -- TcRnBadFieldAnnotation/BadFieldAnnotationReason GhcDiagnosticCode "LazyFieldsDisabled" = 81601 ===================================== testsuite/tests/backpack/should_fail/bkpfail29.stderr ===================================== @@ -5,7 +5,7 @@ [3 of 3] Processing r [1 of 4] Compiling A[sig] ( r/A.hsig, nothing ) -bkpfail29.bkp:8:9: error: +bkpfail29.bkp:8:9: error: [GHC-97522] • Cycle in type synonym declarations: bkpfail29.bkp:8:9-18: S from external module bkpfail29.bkp:7:9-14: T from external module ===================================== testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr ===================================== @@ -1,5 +1,5 @@ -:0:1: error: +:0:1: error: [GHC-97522] Cycle in type synonym declarations: :0:1-10: type A = A 1 ===================================== testsuite/tests/module/mod27.stderr ===================================== @@ -1,5 +1,5 @@ -mod27.hs:3:1: error: +mod27.hs:3:1: error: [GHC-97522] Cycle in type synonym declarations: mod27.hs:3:1-18: type T1 = (Int, T2) mod27.hs:4:1-18: type T2 = (Int, T1) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a788f0ad465cf49673b187c5feeae80b738ce54 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a788f0ad465cf49673b187c5feeae80b738ce54 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 8 02:30:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 07 Apr 2023 22:30:25 -0400 Subject: [Git][ghc/ghc][master] Renamer: don't call addUsedGRE on an exact Name Message-ID: <6430d1c1cafeb_3b005555c5d730749122@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - 6 changed files: - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Types/Name/Reader.hs - + testsuite/tests/rename/should_compile/T23240.hs - + testsuite/tests/rename/should_compile/T23240_aux.hs - testsuite/tests/rename/should_compile/all.T Changes: ===================================== compiler/GHC/Rename/Env.hs ===================================== @@ -534,30 +534,29 @@ lookupRecFieldOcc mb_con rdr_name = return $ mk_unbound_rec_fld con | Just con <- mb_con = do { let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - ; res <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] + ; mb_nm <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] do { flds <- lookupConstructorFields con ; env <- getGlobalRdrEnv - ; let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - mb_gre = do fl <- find ((== lbl) . flLabel) flds + ; let mb_gre = do fl <- find ((== lbl) . flLabel) flds -- We have the label, now check it is in scope. If -- there is a qualifier, use pickGREs to check that -- the qualifier is correct, and return the filtered -- GRE so we get import usage right (see #17853). gre <- lookupGRE_FieldLabel env fl if isQual rdr_name - then listToMaybe (pickGREs rdr_name [gre]) + then listToMaybe $ pickGREs rdr_name [gre] else return gre ; traceRn "lookupRecFieldOcc" $ vcat [ text "mb_con:" <+> ppr mb_con , text "rdr_name:" <+> ppr rdr_name , text "flds:" <+> ppr flds , text "mb_gre:" <+> ppr mb_gre ] - ; return mb_gre } - ; case res of + ; mapM_ (addUsedGRE True) mb_gre + ; return $ flSelector . fieldGRELabel <$> mb_gre } + ; case mb_nm of { Nothing -> do { addErr (badFieldConErr con lbl) ; return $ mk_unbound_rec_fld con } - ; Just gre -> do { addUsedGRE True gre - ; return (flSelector $ fieldGRELabel gre) } } } + ; Just nm -> return nm } } | otherwise -- Can't use the data constructor to disambiguate = greName <$> lookupGlobalOccRn' (IncludeFields WantField) rdr_name @@ -572,7 +571,9 @@ lookupRecFieldOcc mb_con rdr_name mkRecFieldOccFS (getOccFS con) (occNameFS occ) occ = rdrNameOcc rdr_name - ensure_recfld gre = do { guard (isRecFldGRE gre) ; return gre } + ensure_recfld :: GlobalRdrElt -> Maybe Name + ensure_recfld gre = do { guard (isRecFldGRE gre) + ; return $ greName gre } {- Note [DisambiguateRecordFields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1855,7 +1855,10 @@ mkImportMap gres RealSrcLoc decl_loc _ -> Map.insertWith add decl_loc [gre] imp_map UnhelpfulLoc _ -> imp_map where - best_imp_spec = bestImport (bagToList imp_specs) + best_imp_spec = + case bagToList imp_specs of + [] -> pprPanic "mkImportMap: GRE with no ImportSpecs" (ppr gre) + is:iss -> bestImport (is NE.:| iss) add _ gres = gre : gres warnUnusedImport :: WarningFlag -> GlobalRdrEnv ===================================== compiler/GHC/Types/Name/Reader.hs ===================================== @@ -126,7 +126,6 @@ import GHC.Utils.Panic import Control.DeepSeq import Control.Monad ( guard ) import Data.Data -import Data.List ( sortBy ) import qualified Data.List.NonEmpty as NE import qualified Data.Map.Strict as Map import qualified Data.Semigroup as S @@ -1654,12 +1653,9 @@ data ImpItemSpec -- only @T@ is named explicitly. deriving (Eq, Data) -bestImport :: [ImportSpec] -> ImportSpec +bestImport :: NE.NonEmpty ImportSpec -> ImportSpec -- See Note [Choosing the best import declaration] -bestImport iss - = case sortBy best iss of - (is:_) -> is - [] -> pprPanic "bestImport" (ppr iss) +bestImport iss = NE.head $ NE.sortBy best iss where best :: ImportSpec -> ImportSpec -> Ordering -- Less means better ===================================== testsuite/tests/rename/should_compile/T23240.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +-- Crucial to triggering the bug. +{-# LANGUAGE DisambiguateRecordFields #-} + +-- Need to enable the unused imports warning to trigger the bug. +{-# OPTIONS_GHC -Wunused-imports #-} + +module T23240 ( test ) where +import T23240_aux ( D, mkD ) + +test :: D +test = $$mkD ===================================== testsuite/tests/rename/should_compile/T23240_aux.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +module T23240_aux where + +import Language.Haskell.TH ( CodeQ ) + +data D = MkD { myFld :: () } +mkD :: CodeQ D +mkD = [|| MkD { myFld = () } ||] ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -209,3 +209,4 @@ test('ImportNullaryRecordWildcard', [extra_files(['NullaryRecordWildcard.hs', 'N test('GHCINullaryRecordWildcard', combined_output, ghci_script, ['GHCINullaryRecordWildcard.script']) test('GHCIImplicitImportNullaryRecordWildcard', combined_output, ghci_script, ['GHCIImplicitImportNullaryRecordWildcard.script']) test('T22122', [expect_broken(22122), extra_files(['T22122_aux.hs'])], multimod_compile, ['T22122', '-v0']) +test('T23240', [req_th, extra_files(['T23240_aux.hs'])], multimod_compile, ['T23240', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ba77b369a170ba68f4eb5c8f3ae13e03dcbb28d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ba77b369a170ba68f4eb5c8f3ae13e03dcbb28d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 11:45:46 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 07:45:46 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 6 commits: Rename Message-ID: <6432a56ad373_3b005575526bf480481c@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: a8197fc9 by Sven Tennie at 2023-04-09T08:44:19+00:00 Rename - - - - - a5fb3142 by Sven Tennie at 2023-04-09T08:50:48+00:00 getClosure returns Closure - - - - - 30ec94ec by Sven Tennie at 2023-04-09T08:54:55+00:00 getClosure: One WordOffset is enough - - - - - 048ba80b by Sven Tennie at 2023-04-09T08:59:38+00:00 getWord: One offset is enough - - - - - 5a3a1bb3 by Sven Tennie at 2023-04-09T09:16:47+00:00 decodeBitmaps: One offset is enough - - - - - bb6ea826 by Sven Tennie at 2023-04-09T11:45:20+00:00 Formatting, notes - - - - - 2 changed files: - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -6,7 +6,6 @@ {-# LANGUAGE GHCForeignImportPrim #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE RankNTypes #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeInType #-} @@ -26,9 +25,9 @@ import GHC.Exts import GHC.Exts.Heap.ClosureTypes import GHC.Exts.Heap.Closures import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) +import GHC.Exts.Heap.Decode import GHC.Exts.Heap.InfoTable import GHC.Exts.Stack.Constants -import GHC.Exts.Heap.Decode import GHC.IO (IO (..)) import GHC.Stack.CloneStack import GHC.Word @@ -43,38 +42,30 @@ simplified perspective) at any time. The array of closures inside an StgStack (that makeup the execution stack; the stack frames) is moved as bare memory by the garbage collector. References -(pointers) to stack frames are not updated. +(pointers) to stack frames are not updated by the garbage collector. As the StgStack closure is moved as whole, the relative offsets inside it stay the same. (Though, the absolute addresses change!) -Stack frame iterator +Decoding ==================== -A stack frame iterator (StackFrameIter) deals with the mentioned challenges -regarding garbage collected memory. It consists of the StgStack itself and the -mentioned offset (or index) where needed. - -It has three constructors: +Stack frames are defined by their `StackSnapshot#` (`StgStack*` in RTS) and +their relative offset. This tuple is described by `StackFrameLocation`. -- SfiStackClosure: Represents the StgStack closure itself. As stacks are chained - by underflow frames, there can be multiple StgStack closures per logical - stack. +`StackFrame` is an ADT for decoded stack frames. Where it points to heap located +closures or primitive Words (in bitmap encoded payloads), `Closure` is used to +describe the referenced payload. -- SfiClosure: Represents a closure on the stack. The location on the stack is - defined by the StgStack itself and an index into it. +The decoding happens in two phases: -- SfiPrimitive: Is structurally equivalent to SfiClosure, but represents a data - Word on the stack. These appear as payloads to closures with bitmap layout. - From the RTS-perspective, there's no information about the concrete type of - the Word. So, it's just handled as Word in further processing. +1. The whole stack is decoded into `StackFrameLocation`s. -The `stackSnapshot# :: !StackSnapshot#` field represents a StgStack closure. It -is updated by the garbage collector when the stack closure is moved. +2. All `StackFrameLocation`s are decoded into `StackFrame`s which have +`Closure`s as fields/references. -The relative offset (index) describes the location of a stack frame on the -stack. As stack frames come in various sizes, one cannot simply step over the -stack array with a constant offset. +`StackSnapshot#` parameters are updated by the garbage collector and thus safe +to hand around. The head of the stack frame array has offset (index) 0. To traverse the stack frames the latest stack frame's offset is incremented by the closure size. The @@ -83,16 +74,24 @@ unit of the offset is machine words (32bit or 64bit.) Boxes ===== -As references into the stack frame array aren't updated by the garbage collector, -creating a Box with a pointer (address) to a stack frame would break as soon as -the StgStack closure is moved. +`Closure` makes extensive usage of `Box`es. Unfortunately, we cannot simply apply the +same here: + +- Bitmap encoded payloads can be either words or closure pointers. + +- Underflow frames point to `StgStack` closures. -To deal with this another kind of Box is introduced: A StackFrameBox contains a -stack frame iterator (StackFrameIter). +These three cases are hard to encode in boxes. Additionally, introducing new box +types would break existing box usages. Thus, the stack is decoded unboxed, while +the referenced `Closure`s use boxes. This seems to be a good compromise between +optimization (with boxes) and simplicity (by leaving out the mentioned special +cases.) -Heap-represented closures referenced by stack frames are boxed the usual way, -with a Box that contains a pointer to the closure as it's payload. In -Haskell-land this means: A Box which contains the closure. +IO +== + +Unfortunately, ghc-heap decodes `Closure`s in `IO`. This leads to `StackFrames` +also being decoded in `IO`, due to references to `Closure`s. Technical details ================= @@ -109,21 +108,24 @@ Technical details This keeps the code very portable. -} -foreign import prim "getUnderflowFrameNextChunkzh" getUnderflowFrameNextChunk# :: StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, StackSnapshot# #) +foreign import prim "getUnderflowFrameNextChunkzh" + getUnderflowFrameNextChunk# :: + StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, StackSnapshot# #) getUnderflowFrameNextChunk :: StackSnapshot# -> WordOffset -> IO StackSnapshot getUnderflowFrameNextChunk stackSnapshot# index = IO $ \s -> case getUnderflowFrameNextChunk# stackSnapshot# (wordOffsetToWord# index) s of (# s1, stack# #) -> (# s1, StackSnapshot stack# #) -foreign import prim "getWordzh" getWord# :: StackSnapshot# -> Word# -> Word# -> State# RealWorld -> (# State# RealWorld, Word# #) +foreign import prim "getWordzh" + getWord# :: + StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Word# #) -getWord :: StackSnapshot# -> WordOffset -> WordOffset -> IO Word -getWord stackSnapshot# index relativeOffset = IO $ \s -> +getWord :: StackSnapshot# -> WordOffset -> IO Word +getWord stackSnapshot# index = IO $ \s -> case getWord# stackSnapshot# (wordOffsetToWord# index) - (wordOffsetToWord# relativeOffset) s of (# s1, w# #) -> (# s1, W# w# #) @@ -171,9 +173,13 @@ getInfoTableForStack stackSnapshot# = peekItbl $ Ptr (getStackInfoTableAddr# stackSnapshot#) -foreign import prim "getBoxedClosurezh" getBoxedClosure# :: StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Any #) +foreign import prim "getBoxedClosurezh" + getBoxedClosure# :: + StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Any #) -foreign import prim "getStackFieldszh" getStackFields# :: StackSnapshot# -> State# RealWorld -> (# State# RealWorld, Word32#, Word8#, Word8# #) +foreign import prim "getStackFieldszh" + getStackFields# :: + StackSnapshot# -> State# RealWorld -> (# State# RealWorld, Word32#, Word8#, Word8# #) getStackFields :: StackSnapshot# -> IO (Word32, Word8, Word8) getStackFields stackSnapshot# = IO $ \s -> @@ -183,13 +189,15 @@ getStackFields stackSnapshot# = IO $ \s -> -- | Get an interator starting with the top-most stack frame stackHead :: StackSnapshot -> (StackSnapshot, WordOffset) -stackHead (StackSnapshot s#) = (StackSnapshot s#, 0 ) -- GHC stacks are never empty +stackHead (StackSnapshot s#) = (StackSnapshot s#, 0) -- GHC stacks are never empty -- | Advance to the next stack frame (if any) -- -- The last `Int#` in the result tuple is meant to be treated as bool -- (has_next). -foreign import prim "advanceStackFrameIterzh" advanceStackFrameIter# :: StackSnapshot# -> Word# -> (# StackSnapshot#, Word#, Int# #) +foreign import prim "advanceStackFrameIterzh" + advanceStackFrameIter# :: + StackSnapshot# -> Word# -> (# StackSnapshot#, Word#, Int# #) -- | Advance iterator to the next stack frame (if any) advanceStackFrameIter :: StackSnapshot -> WordOffset -> Maybe (StackSnapshot, WordOffset) @@ -202,23 +210,24 @@ advanceStackFrameIter (StackSnapshot stackSnapshot#) index = primWordToWordOffset :: Word# -> WordOffset primWordToWordOffset w# = fromIntegral (W# w#) -getClosure :: StackSnapshot# -> WordOffset -> WordOffset -> IO Box -getClosure stackSnapshot# index relativeOffset = - IO $ \s -> - case getBoxedClosure# - stackSnapshot# - (wordOffsetToWord# (index + relativeOffset)) - s of - (# s1, ptr #) -> - (# s1, Box ptr #) - --- TODO: Inline later +getClosure :: StackSnapshot# -> WordOffset -> IO Closure +getClosure stackSnapshot# index = + ( IO $ \s -> + case getBoxedClosure# + stackSnapshot# + (wordOffsetToWord# index) + s of + (# s1, ptr #) -> + (# s1, Box ptr #) + ) + >>= getBoxedClosureData + -- | Iterator state for stack decoding -data StackFrameIter = - -- | Represents a closure on the stack - SfiClosure !StackSnapshot# !WordOffset - -- | Represents a primitive word on the stack - | SfiPrimitive !StackSnapshot# !WordOffset +data StackFrameIter + = -- | Represents a closure on the stack + SfiClosure !StackSnapshot# !WordOffset + | -- | Represents a primitive word on the stack + SfiPrimitive !StackSnapshot# !WordOffset decodeLargeBitmap :: LargeBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do @@ -226,7 +235,7 @@ decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do case getterFun# stackSnapshot# (wordOffsetToWord# index) s of (# s1, ba#, s# #) -> (# s1, (ByteArray ba#, W# s#) #) let bitmapWords :: [Word] = byteArrayToList bitmapArray - decodeBitmaps stackSnapshot# index relativePayloadOffset bitmapWords size + decodeBitmaps stackSnapshot# (index + relativePayloadOffset) bitmapWords size where byteArrayToList :: ByteArray -> [Word] byteArrayToList (ByteArray bArray) = go 0 @@ -239,16 +248,16 @@ decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do sizeofByteArray :: ByteArray# -> Int sizeofByteArray arr# = I# (sizeofByteArray# arr#) -decodeBitmaps :: StackSnapshot# -> WordOffset -> WordOffset -> [Word] -> Word -> IO [Closure] -decodeBitmaps stackSnapshot# index relativePayloadOffset bitmapWords size = - let bes = wordsToBitmapEntries (index + relativePayloadOffset) bitmapWords size +decodeBitmaps :: StackSnapshot# -> WordOffset -> [Word] -> Word -> IO [Closure] +decodeBitmaps stackSnapshot# index bitmapWords size = + let bes = wordsToBitmapEntries index bitmapWords size in mapM toBitmapPayload bes where toBitmapPayload :: StackFrameIter -> IO Closure - toBitmapPayload (SfiPrimitive stack# i) = do - w <- getWord stack# i 0 + toBitmapPayload (SfiPrimitive stack# i) = do + w <- getWord stack# i pure $ UnknownTypeWordSizedPrimitive w - toBitmapPayload (SfiClosure stack# i) = getBoxedClosureData =<< getClosure stack# i 0 + toBitmapPayload (SfiClosure stack# i) = getClosure stack# i wordsToBitmapEntries :: WordOffset -> [Word] -> Word -> [StackFrameIter] wordsToBitmapEntries _ [] 0 = [] @@ -261,7 +270,7 @@ decodeBitmaps stackSnapshot# index relativePayloadOffset bitmapWords size = Just sfi' -> entries ++ wordsToBitmapEntries - ((getIndex sfi') + 1) + (getIndex sfi' + 1) bs subtractDecodedBitmapWord _ -> error "This should never happen! Recursion ended not in base case." @@ -287,6 +296,8 @@ decodeBitmaps stackSnapshot# index relativePayloadOffset bitmapWords size = getIndex (SfiClosure _ i) = i getIndex (SfiPrimitive _ i) = i +-- TODO: (auto-) format the code +-- TODO: Check all functions with two WordOffsets? Can't it be one? decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = do @@ -294,10 +305,10 @@ decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = case getterFun# stackSnapshot# (wordOffsetToWord# index) s of (# s1, b#, s# #) -> (# s1, (W# b#, W# s#) #) let bitmapWords = [bitmap | size > 0] - decodeBitmaps stackSnapshot# index relativePayloadOffset bitmapWords size + decodeBitmaps stackSnapshot# (index + relativePayloadOffset) bitmapWords size -unpackStackFrame :: (StackSnapshot, WordOffset) -> IO StackFrame -unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do +unpackStackFrame :: StackFrameLocation -> IO StackFrame +unpackStackFrame (StackSnapshot stackSnapshot#, index) = do info <- getInfoTableOnStack stackSnapshot# index unpackStackFrame' info where @@ -305,7 +316,7 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do unpackStackFrame' info = case tipe info of RET_BCO -> do - bco' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgClosurePayload + bco' <- getClosure stackSnapshot# (index + offsetStgClosurePayload) -- The arguments begin directly after the payload's one element bcoArgs' <- decodeLargeBitmap getBCOLargeBitmap# stackSnapshot# index (offsetStgClosurePayload + 1) pure @@ -330,8 +341,8 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do } RET_FUN -> do retFunType' <- getRetFunType stackSnapshot# index - retFunSize' <- getWord stackSnapshot# index offsetStgRetFunFrameSize - retFunFun' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgRetFunFrameFun + retFunSize' <- getWord stackSnapshot# (index + offsetStgRetFunFrameSize) + retFunFun' <- getClosure stackSnapshot# (index + offsetStgRetFunFrameFun) retFunPayload' <- if retFunType' == ARG_GEN_BIG then decodeLargeBitmap getRetFunLargeBitmap# stackSnapshot# index offsetStgRetFunFramePayload @@ -345,15 +356,15 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do retFunPayload = retFunPayload' } UPDATE_FRAME -> do - updatee' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgUpdateFrameUpdatee + updatee' <- getClosure stackSnapshot# (index + offsetStgUpdateFrameUpdatee) pure $ UpdateFrame { info_tbl = info, updatee = updatee' } CATCH_FRAME -> do - exceptions_blocked' <- getWord stackSnapshot# index offsetStgCatchFrameExceptionsBlocked - handler' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgCatchFrameHandler + exceptions_blocked' <- getWord stackSnapshot# (index + offsetStgCatchFrameExceptionsBlocked) + handler' <- getClosure stackSnapshot# (index + offsetStgCatchFrameHandler) pure $ CatchFrame { info_tbl = info, @@ -370,8 +381,8 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do } STOP_FRAME -> pure $ StopFrame {info_tbl = info} ATOMICALLY_FRAME -> do - atomicallyFrameCode' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgAtomicallyFrameCode - result' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgAtomicallyFrameResult + atomicallyFrameCode' <- getClosure stackSnapshot# (index + offsetStgAtomicallyFrameCode) + result' <- getClosure stackSnapshot# (index + offsetStgAtomicallyFrameResult) pure $ AtomicallyFrame { info_tbl = info, @@ -379,9 +390,9 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do result = result' } CATCH_RETRY_FRAME -> do - running_alt_code' <- getWord stackSnapshot# index offsetStgCatchRetryFrameRunningAltCode - first_code' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgCatchRetryFrameRunningFirstCode - alt_code' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgCatchRetryFrameAltCode + running_alt_code' <- getWord stackSnapshot# (index + offsetStgCatchRetryFrameRunningAltCode) + first_code' <- getClosure stackSnapshot# (index + offsetStgCatchRetryFrameRunningFirstCode) + alt_code' <- getClosure stackSnapshot# (index + offsetStgCatchRetryFrameAltCode) pure $ CatchRetryFrame { info_tbl = info, @@ -390,8 +401,8 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do alt_code = alt_code' } CATCH_STM_FRAME -> do - catchFrameCode' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgCatchSTMFrameCode - handler' <- getBoxedClosureData =<< getClosure stackSnapshot# index offsetStgCatchSTMFrameHandler + catchFrameCode' <- getClosure stackSnapshot# (index + offsetStgCatchSTMFrameCode) + handler' <- getClosure stackSnapshot# (index + offsetStgCatchSTMFrameHandler) pure $ CatchStmFrame { info_tbl = info, @@ -400,25 +411,27 @@ unpackStackFrame ((StackSnapshot stackSnapshot#), index) = do } x -> error $ "Unexpected closure type on stack: " ++ show x -getClosureDataFromHeapObject - :: a - -- ^ Heap object to decode. - -> IO Closure - -- ^ Heap representation of the closure. +-- TODO: Duplicate +getClosureDataFromHeapObject :: + -- | Heap object to decode. + a -> + -- | Heap representation of the closure. + IO Closure getClosureDataFromHeapObject x = do - case unpackClosure# x of - (# infoTableAddr, heapRep, pointersArray #) -> do - let infoTablePtr = Ptr infoTableAddr - ptrList = [case indexArray# pointersArray i of - (# ptr #) -> Box ptr - | I# i <- [0..I# (sizeofArray# pointersArray) - 1] - ] - - infoTable <- peekItbl infoTablePtr - case tipe infoTable of - TSO -> pure $ UnsupportedClosure infoTable - STACK -> pure $ UnsupportedClosure infoTable - _ -> getClosureDataFromHeapRep heapRep infoTablePtr ptrList + case unpackClosure# x of + (# infoTableAddr, heapRep, pointersArray #) -> do + let infoTablePtr = Ptr infoTableAddr + ptrList = + [ case indexArray# pointersArray i of + (# ptr #) -> Box ptr + | I# i <- [0 .. I# (sizeofArray# pointersArray) - 1] + ] + + infoTable <- peekItbl infoTablePtr + case tipe infoTable of + TSO -> pure $ UnsupportedClosure infoTable + STACK -> pure $ UnsupportedClosure infoTable + _ -> getClosureDataFromHeapRep heapRep infoTablePtr ptrList -- | Like 'getClosureData', but taking a 'Box', so it is easier to work with. getBoxedClosureData :: Box -> IO Closure @@ -435,21 +448,18 @@ intToWord# i = int2Word# (toInt# i) wordOffsetToWord# :: WordOffset -> Word# wordOffsetToWord# wo = intToWord# (fromIntegral wo) --- | Decode `StackSnapshot` to a Closure +type StackFrameLocation = (StackSnapshot, WordOffset) + +-- | Decode `StackSnapshot` to a `StgStackClosure` -- --- Due to the use of `Box` this decoding is lazy. The first decoded closure is --- the representation of the @StgStack@ itself. +-- The return value is the representation of the @StgStack@ itself. decodeStack :: StackSnapshot -> IO StgStackClosure -decodeStack (StackSnapshot stack#) = - unpackStack stack# - -unpackStack :: StackSnapshot# -> IO StgStackClosure -unpackStack stack# = do +decodeStack (StackSnapshot stack#) = do info <- getInfoTableForStack stack# (stack_size', stack_dirty', stack_marking') <- getStackFields stack# case tipe info of STACK -> do - let sfis = decodeStackToBoxes (StackSnapshot stack#) + let sfis = stackFrameLocations (StackSnapshot stack#) stack' <- mapM unpackStackFrame sfis pure $ StgStackClosure @@ -461,15 +471,16 @@ unpackStack stack# = do } _ -> error $ "Expected STACK closure, got " ++ show info where - decodeStackToBoxes :: StackSnapshot -> [(StackSnapshot, WordOffset)] - decodeStackToBoxes s = - (stackHead s) - : go (advanceStackFrameIter (fst (stackHead s)) (snd (stackHead s))) + stackFrameLocations :: StackSnapshot -> [StackFrameLocation] + stackFrameLocations s = + stackHead s + : go (uncurry advanceStackFrameIter (stackHead s)) where - go :: Maybe (StackSnapshot, WordOffset) -> [(StackSnapshot, WordOffset)] + go :: Maybe StackFrameLocation -> [StackFrameLocation] go Nothing = [] - go (Just r) = r : go (advanceStackFrameIter (fst r) (snd r)) + go (Just r) = r : go (uncurry advanceStackFrameIter r) #else module GHC.Exts.Stack.Decode where +import GHC.Base (IO) #endif ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -114,10 +114,10 @@ getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) { return (stgArrBytes, size); } -// getWordzh(StgStack* stack, StgWord offsetWords, StgWord offsetBytes) -getWordzh(P_ stack, W_ offsetWords, W_ offsetBytes) { +// getWordzh(StgStack* stack, StgWord offsetWords) +getWordzh(P_ stack, W_ offsetWords) { P_ wordAddr; - wordAddr = (StgStack_sp(stack) + WDS(offsetWords) + WDS(offsetBytes)); + wordAddr = (StgStack_sp(stack) + WDS(offsetWords)); return (W_[wordAddr]); } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c2bbf8f83d6d82c66746d3de47266e92408c2fc...bb6ea826ac0d7d543623e8b98a74b6f266b5b512 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c2bbf8f83d6d82c66746d3de47266e92408c2fc...bb6ea826ac0d7d543623e8b98a74b6f266b5b512 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 14:20:37 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 10:20:37 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Minimize diff Message-ID: <6432c9b5d56d_3b005577cc7a28810655@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 75c42867 by Sven Tennie at 2023-04-09T14:20:06+00:00 Minimize diff - - - - - 8 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - − libraries/ghc-heap/GHC/Exts/Heap/Decode.hs - + libraries/ghc-heap/GHC/Exts/Stack.hs - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/ghc-heap.cabal.in - libraries/ghc-heap/tests/ClosureSizeUtils.hs - libraries/ghc-heap/tests/stack_misc_closures.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -7,9 +7,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE RankNTypes #-} -#if MIN_TOOL_VERSION_ghc(9,7,0) -{-# LANGUAGE RecordWildCards #-} -#endif {-# LANGUAGE UnliftedFFITypes #-} {-| @@ -26,12 +23,10 @@ module GHC.Exts.Heap ( -- * Closure types Closure , GenClosure(..) - , StackFrame(..) , ClosureType(..) , PrimType(..) , WhatNext(..) , WhyBlocked(..) - , RetFunType(..) , TsoFlags(..) , HasHeapRep(getClosureData) , getClosureDataFromHeapRep @@ -55,12 +50,7 @@ module GHC.Exts.Heap ( -- * Closure inspection , getBoxedClosureData , allClosures - , closureSize -#if MIN_TOOL_VERSION_ghc(9,7,0) - -- * Stack inspection - , decodeStack - , stackFrameSize -#endif + -- * Boxes , Box(..) , asBox @@ -70,22 +60,22 @@ module GHC.Exts.Heap ( import Prelude import GHC.Exts.Heap.Closures import GHC.Exts.Heap.ClosureTypes +import GHC.Exts.Heap.Constants import GHC.Exts.Heap.ProfInfo.Types #if defined(PROFILING) import GHC.Exts.Heap.InfoTableProf #else import GHC.Exts.Heap.InfoTable #endif -import GHC.Exts.Heap.Decode +import GHC.Exts.Heap.Utils +import qualified GHC.Exts.Heap.FFIClosures as FFIClosures +import qualified GHC.Exts.Heap.ProfInfo.PeekProfInfo as PPI +import Data.Bits +import Foreign import GHC.Exts import GHC.Int import GHC.Word -#if MIN_TOOL_VERSION_ghc(9,7,0) -import GHC.Exts.Stack.Decode -import GHC.Exts.Stack.Constants -#endif - #include "ghcconfig.h" @@ -173,34 +163,223 @@ getClosureDataFromHeapObject x = do STACK -> pure $ UnsupportedClosure infoTable _ -> getClosureDataFromHeapRep heapRep infoTablePtr ptrList + +-- | Convert an unpacked heap object, to a `GenClosure b`. The inputs to this +-- function can be generated from a heap object using `unpackClosure#`. +getClosureDataFromHeapRep :: ByteArray# -> Ptr StgInfoTable -> [b] -> IO (GenClosure b) +getClosureDataFromHeapRep heapRep infoTablePtr pts = do + itbl <- peekItbl infoTablePtr + getClosureDataFromHeapRepPrim (dataConNames infoTablePtr) PPI.peekTopCCS itbl heapRep pts + +getClosureDataFromHeapRepPrim + :: IO (String, String, String) + -- ^ A continuation used to decode the constructor description field, + -- in ghc-debug this code can lead to segfaults because dataConNames + -- will dereference a random part of memory. + -> (Ptr a -> IO (Maybe CostCentreStack)) + -- ^ A continuation which is used to decode a cost centre stack + -- In ghc-debug, this code will need to call back into the debuggee to + -- fetch the representation of the CCS before decoding it. Using + -- `peekTopCCS` for this argument can lead to segfaults in ghc-debug as + -- the CCS argument will point outside the copied closure. + -> StgInfoTable + -- ^ The `StgInfoTable` of the closure, extracted from the heap + -- representation. + -> ByteArray# + -- ^ Heap representation of the closure as returned by `unpackClosure#`. + -- This includes all of the object including the header, info table + -- pointer, pointer data, and non-pointer data. The ByteArray# may be + -- pinned or unpinned. + -> [b] + -- ^ Pointers in the payload of the closure, extracted from the heap + -- representation as returned by `collect_pointers()` in `Heap.c`. The type + -- `b` is some representation of a pointer e.g. `Any` or `Ptr Any`. + -> IO (GenClosure b) + -- ^ Heap representation of the closure. +getClosureDataFromHeapRepPrim getConDesc decodeCCS itbl heapRep pts = do + let -- heapRep as a list of words. + rawHeapWords :: [Word] + rawHeapWords = [W# (indexWordArray# heapRep i) | I# i <- [0.. end] ] + where + nelems = I# (sizeofByteArray# heapRep) `div` wORD_SIZE + end = fromIntegral nelems - 1 + + -- Just the payload of rawHeapWords (no header). + payloadWords :: [Word] + payloadWords = drop (closureTypeHeaderSize (tipe itbl)) rawHeapWords + + -- The non-pointer words in the payload. Only valid for closures with a + -- "pointers first" layout. Not valid for bit field layout. + npts :: [Word] + npts = drop (closureTypeHeaderSize (tipe itbl) + length pts) rawHeapWords + case tipe itbl of + t | t >= CONSTR && t <= CONSTR_NOCAF -> do + (p, m, n) <- getConDesc + pure $ ConstrClosure itbl pts npts p m n + + t | t >= THUNK && t <= THUNK_STATIC -> do + pure $ ThunkClosure itbl pts npts + + THUNK_SELECTOR -> case pts of + [] -> fail "Expected at least 1 ptr argument to THUNK_SELECTOR" + hd : _ -> pure $ SelectorClosure itbl hd + + t | t >= FUN && t <= FUN_STATIC -> do + pure $ FunClosure itbl pts npts + + AP -> case pts of + [] -> fail "Expected at least 1 ptr argument to AP" + hd : tl -> case payloadWords of + -- We expect at least the arity, n_args, and fun fields + splitWord : _ : _ -> + pure $ APClosure itbl +#if defined(WORDS_BIGENDIAN) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) + (fromIntegral splitWord) +#else + (fromIntegral splitWord) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) +#endif + hd tl + _ -> fail "Expected at least 2 raw words to AP" + + PAP -> case pts of + [] -> fail "Expected at least 1 ptr argument to PAP" + hd : tl -> case payloadWords of + -- We expect at least the arity, n_args, and fun fields + splitWord : _ : _ -> + pure $ PAPClosure itbl +#if defined(WORDS_BIGENDIAN) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) + (fromIntegral splitWord) +#else + (fromIntegral splitWord) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) +#endif + hd tl + _ -> fail "Expected at least 2 raw words to PAP" + + AP_STACK -> case pts of + [] -> fail "Expected at least 1 ptr argument to AP_STACK" + hd : tl -> pure $ APStackClosure itbl hd tl + + IND -> case pts of + [] -> fail "Expected at least 1 ptr argument to IND" + hd : _ -> pure $ IndClosure itbl hd + + IND_STATIC -> case pts of + [] -> fail "Expected at least 1 ptr argument to IND_STATIC" + hd : _ -> pure $ IndClosure itbl hd + + BLACKHOLE -> case pts of + [] -> fail "Expected at least 1 ptr argument to BLACKHOLE" + hd : _ -> pure $ BlackholeClosure itbl hd + + BCO -> case pts of + pts0 : pts1 : pts2 : _ -> case payloadWords of + _ : _ : _ : splitWord : payloadRest -> + pure $ BCOClosure itbl pts0 pts1 pts2 +#if defined(WORDS_BIGENDIAN) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) + (fromIntegral splitWord) +#else + (fromIntegral splitWord) + (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) +#endif + payloadRest + _ -> fail $ "Expected at least 4 words to BCO, found " + ++ show (length payloadWords) + _ -> fail $ "Expected at least 3 ptr argument to BCO, found " + ++ show (length pts) + + ARR_WORDS -> case payloadWords of + [] -> fail $ "Expected at least 1 words to ARR_WORDS, found " + ++ show (length payloadWords) + hd : tl -> pure $ ArrWordsClosure itbl hd tl + + t | t >= MUT_ARR_PTRS_CLEAN && t <= MUT_ARR_PTRS_FROZEN_CLEAN -> case payloadWords of + p0 : p1 : _ -> pure $ MutArrClosure itbl p0 p1 pts + _ -> fail $ "Expected at least 2 words to MUT_ARR_PTRS_* " + ++ "found " ++ show (length payloadWords) + + t | t >= SMALL_MUT_ARR_PTRS_CLEAN && t <= SMALL_MUT_ARR_PTRS_FROZEN_CLEAN -> case payloadWords of + [] -> fail $ "Expected at least 1 word to SMALL_MUT_ARR_PTRS_* " + ++ "found " ++ show (length payloadWords) + hd : _ -> pure $ SmallMutArrClosure itbl hd pts + + t | t == MUT_VAR_CLEAN || t == MUT_VAR_DIRTY -> case pts of + [] -> fail $ "Expected at least 1 words to MUT_VAR, found " + ++ show (length pts) + hd : _ -> pure $ MutVarClosure itbl hd + + t | t == MVAR_CLEAN || t == MVAR_DIRTY -> case pts of + pts0 : pts1 : pts2 : _ -> pure $ MVarClosure itbl pts0 pts1 pts2 + _ -> fail $ "Expected at least 3 ptrs to MVAR, found " + ++ show (length pts) + + BLOCKING_QUEUE -> + pure $ OtherClosure itbl pts rawHeapWords + + WEAK -> case pts of + pts0 : pts1 : pts2 : pts3 : rest -> pure $ WeakClosure + { info = itbl + , cfinalizers = pts0 + , key = pts1 + , value = pts2 + , finalizer = pts3 + , weakLink = case rest of + [] -> Nothing + [p] -> Just p + _ -> error $ "Expected 4 or 5 words in WEAK, but found more: " ++ show (length pts) + } + _ -> error $ "Expected 4 or 5 words in WEAK, but found less: " ++ show (length pts) + TSO | ( u_lnk : u_gbl_lnk : tso_stack : u_trec : u_blk_ex : u_bq : other) <- pts + -> withArray rawHeapWords (\ptr -> do + fields <- FFIClosures.peekTSOFields decodeCCS ptr + pure $ TSOClosure + { info = itbl + , link = u_lnk + , global_link = u_gbl_lnk + , tsoStack = tso_stack + , trec = u_trec + , blocked_exceptions = u_blk_ex + , bq = u_bq + , thread_label = case other of + [tl] -> Just tl + [] -> Nothing + _ -> error $ "thead_label:Expected 0 or 1 extra arguments" + , what_next = FFIClosures.tso_what_next fields + , why_blocked = FFIClosures.tso_why_blocked fields + , flags = FFIClosures.tso_flags fields + , threadId = FFIClosures.tso_threadId fields + , saved_errno = FFIClosures.tso_saved_errno fields + , tso_dirty = FFIClosures.tso_dirty fields + , alloc_limit = FFIClosures.tso_alloc_limit fields + , tot_stack_size = FFIClosures.tso_tot_stack_size fields + , prof = FFIClosures.tso_prof fields + }) + | otherwise + -> fail $ "Expected at least 6 ptr arguments to TSO, found " + ++ show (length pts) + STACK + | [] <- pts + -> withArray rawHeapWords (\ptr -> do + fields <- FFIClosures.peekStackFields ptr + pure $ StackClosure + { info = itbl + , stack_size = FFIClosures.stack_size fields + , stack_dirty = FFIClosures.stack_dirty fields +#if __GLASGOW_HASKELL__ >= 811 + , stack_marking = FFIClosures.stack_marking fields +#endif + }) + | otherwise + -> fail $ "Expected 0 ptr argument to STACK, found " + ++ show (length pts) + + _ -> + pure $ UnsupportedClosure itbl + -- | Like 'getClosureData', but taking a 'Box', so it is easier to work with. getBoxedClosureData :: Box -> IO Closure getBoxedClosureData (Box a) = getClosureData a - --- | Get the size of the top-level closure in words. --- Includes header and payload. Does not follow pointers. --- --- @since 8.10.1 -closureSize :: Box -> IO Int -closureSize (Box x) = pure $ I# (closureSize# x) - -#if MIN_TOOL_VERSION_ghc(9,7,0) --- TODO: Pattern match may move to function arguments -stackFrameSize :: StackFrame -> Int -stackFrameSize = - \c -> - case c of - UpdateFrame {} -> sizeStgUpdateFrame - CatchFrame {} -> sizeStgCatchFrame - CatchStmFrame {} -> sizeStgCatchSTMFrame - CatchRetryFrame {} -> sizeStgCatchRetryFrame - AtomicallyFrame {} -> sizeStgAtomicallyFrame - RetSmall {..} -> sizeStgClosure + length stack_payload - RetBig {..} -> sizeStgClosure + length stack_payload - RetFun {..} -> sizeStgRetFunFrame + length retFunPayload - -- The one additional word is a pointer to the StgBCO in the closure's payload - RetBCO {..} -> sizeStgClosure + 1 + length bcoArgs - -- The one additional word is a pointer to the next stack chunk - UnderflowFrame {} -> sizeStgClosure + 1 - _ -> error "Unexpected closure type" -#endif ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -17,6 +17,7 @@ module GHC.Exts.Heap.Closures ( , TsoFlags(..) , RetFunType(..) , allClosures + , closureSize -- * Stack , StgStackClosure(..) @@ -553,3 +554,10 @@ allClosures (BlockingQueueClosure {..}) = [link, blackHole, owner, queue] allClosures (WeakClosure {..}) = [cfinalizers, key, value, finalizer] ++ Data.Foldable.toList weakLink allClosures (OtherClosure {..}) = hvalues allClosures _ = [] + +-- | Get the size of the top-level closure in words. +-- Includes header and payload. Does not follow pointers. +-- +-- @since 8.10.1 +closureSize :: Box -> Int +closureSize (Box x) = I# (closureSize# x) ===================================== libraries/ghc-heap/GHC/Exts/Heap/Decode.hs deleted ===================================== @@ -1,243 +0,0 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MagicHash #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE UnliftedFFITypes #-} - -module GHC.Exts.Heap.Decode where -import Prelude -import GHC.Exts.Heap.Closures -import GHC.Exts.Heap.ClosureTypes -import GHC.Exts.Heap.Constants -import GHC.Exts.Heap.ProfInfo.Types -#if defined(PROFILING) -import GHC.Exts.Heap.InfoTableProf -#else -import GHC.Exts.Heap.InfoTable -#endif -import GHC.Exts.Heap.Utils -import qualified GHC.Exts.Heap.FFIClosures as FFIClosures -import qualified GHC.Exts.Heap.ProfInfo.PeekProfInfo as PPI - -import Data.Bits -import Foreign -import GHC.Exts - --- | Convert an unpacked heap object, to a `GenClosure b`. The inputs to this --- function can be generated from a heap object using `unpackClosure#`. -getClosureDataFromHeapRep :: ByteArray# -> Ptr StgInfoTable -> [b] -> IO (GenClosure b) -getClosureDataFromHeapRep heapRep infoTablePtr pts = do - itbl <- peekItbl infoTablePtr - getClosureDataFromHeapRepPrim (dataConNames infoTablePtr) PPI.peekTopCCS itbl heapRep pts - -getClosureDataFromHeapRepPrim - :: IO (String, String, String) - -- ^ A continuation used to decode the constructor description field, - -- in ghc-debug this code can lead to segfaults because dataConNames - -- will dereference a random part of memory. - -> (Ptr a -> IO (Maybe CostCentreStack)) - -- ^ A continuation which is used to decode a cost centre stack - -- In ghc-debug, this code will need to call back into the debuggee to - -- fetch the representation of the CCS before decoding it. Using - -- `peekTopCCS` for this argument can lead to segfaults in ghc-debug as - -- the CCS argument will point outside the copied closure. - -> StgInfoTable - -- ^ The `StgInfoTable` of the closure, extracted from the heap - -- representation. - -> ByteArray# - -- ^ Heap representation of the closure as returned by `unpackClosure#`. - -- This includes all of the object including the header, info table - -- pointer, pointer data, and non-pointer data. The ByteArray# may be - -- pinned or unpinned. - -> [b] - -- ^ Pointers in the payload of the closure, extracted from the heap - -- representation as returned by `collect_pointers()` in `Heap.c`. The type - -- `b` is some representation of a pointer e.g. `Any` or `Ptr Any`. - -> IO (GenClosure b) - -- ^ Heap representation of the closure. -getClosureDataFromHeapRepPrim getConDesc decodeCCS itbl heapRep pts = do - let -- heapRep as a list of words. - rawHeapWords :: [Word] - rawHeapWords = [W# (indexWordArray# heapRep i) | I# i <- [0.. end] ] - where - nelems = I# (sizeofByteArray# heapRep) `div` wORD_SIZE - end = fromIntegral nelems - 1 - - -- Just the payload of rawHeapWords (no header). - payloadWords :: [Word] - payloadWords = drop (closureTypeHeaderSize (tipe itbl)) rawHeapWords - - -- The non-pointer words in the payload. Only valid for closures with a - -- "pointers first" layout. Not valid for bit field layout. - npts :: [Word] - npts = drop (closureTypeHeaderSize (tipe itbl) + length pts) rawHeapWords - case tipe itbl of - t | t >= CONSTR && t <= CONSTR_NOCAF -> do - (p, m, n) <- getConDesc - pure $ ConstrClosure itbl pts npts p m n - - t | t >= THUNK && t <= THUNK_STATIC -> do - pure $ ThunkClosure itbl pts npts - - THUNK_SELECTOR -> case pts of - [] -> fail "Expected at least 1 ptr argument to THUNK_SELECTOR" - hd : _ -> pure $ SelectorClosure itbl hd - - t | t >= FUN && t <= FUN_STATIC -> do - pure $ FunClosure itbl pts npts - - AP -> case pts of - [] -> fail "Expected at least 1 ptr argument to AP" - hd : tl -> case payloadWords of - -- We expect at least the arity, n_args, and fun fields - splitWord : _ : _ -> - pure $ APClosure itbl -#if defined(WORDS_BIGENDIAN) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) - (fromIntegral splitWord) -#else - (fromIntegral splitWord) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) -#endif - hd tl - _ -> fail "Expected at least 2 raw words to AP" - - PAP -> case pts of - [] -> fail "Expected at least 1 ptr argument to PAP" - hd : tl -> case payloadWords of - -- We expect at least the arity, n_args, and fun fields - splitWord : _ : _ -> - pure $ PAPClosure itbl -#if defined(WORDS_BIGENDIAN) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) - (fromIntegral splitWord) -#else - (fromIntegral splitWord) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) -#endif - hd tl - _ -> fail "Expected at least 2 raw words to PAP" - - AP_STACK -> case pts of - [] -> fail "Expected at least 1 ptr argument to AP_STACK" - hd : tl -> pure $ APStackClosure itbl hd tl - - IND -> case pts of - [] -> fail "Expected at least 1 ptr argument to IND" - hd : _ -> pure $ IndClosure itbl hd - - IND_STATIC -> case pts of - [] -> fail "Expected at least 1 ptr argument to IND_STATIC" - hd : _ -> pure $ IndClosure itbl hd - - BLACKHOLE -> case pts of - [] -> fail "Expected at least 1 ptr argument to BLACKHOLE" - hd : _ -> pure $ BlackholeClosure itbl hd - - BCO -> case pts of - pts0 : pts1 : pts2 : _ -> case payloadWords of - _ : _ : _ : splitWord : payloadRest -> - pure $ BCOClosure itbl pts0 pts1 pts2 -#if defined(WORDS_BIGENDIAN) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) - (fromIntegral splitWord) -#else - (fromIntegral splitWord) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) -#endif - payloadRest - _ -> fail $ "Expected at least 4 words to BCO, found " - ++ show (length payloadWords) - _ -> fail $ "Expected at least 3 ptr argument to BCO, found " - ++ show (length pts) - - ARR_WORDS -> case payloadWords of - [] -> fail $ "Expected at least 1 words to ARR_WORDS, found " - ++ show (length payloadWords) - hd : tl -> pure $ ArrWordsClosure itbl hd tl - - t | t >= MUT_ARR_PTRS_CLEAN && t <= MUT_ARR_PTRS_FROZEN_CLEAN -> case payloadWords of - p0 : p1 : _ -> pure $ MutArrClosure itbl p0 p1 pts - _ -> fail $ "Expected at least 2 words to MUT_ARR_PTRS_* " - ++ "found " ++ show (length payloadWords) - - t | t >= SMALL_MUT_ARR_PTRS_CLEAN && t <= SMALL_MUT_ARR_PTRS_FROZEN_CLEAN -> case payloadWords of - [] -> fail $ "Expected at least 1 word to SMALL_MUT_ARR_PTRS_* " - ++ "found " ++ show (length payloadWords) - hd : _ -> pure $ SmallMutArrClosure itbl hd pts - - t | t == MUT_VAR_CLEAN || t == MUT_VAR_DIRTY -> case pts of - [] -> fail $ "Expected at least 1 words to MUT_VAR, found " - ++ show (length pts) - hd : _ -> pure $ MutVarClosure itbl hd - - t | t == MVAR_CLEAN || t == MVAR_DIRTY -> case pts of - pts0 : pts1 : pts2 : _ -> pure $ MVarClosure itbl pts0 pts1 pts2 - _ -> fail $ "Expected at least 3 ptrs to MVAR, found " - ++ show (length pts) - - BLOCKING_QUEUE -> - pure $ OtherClosure itbl pts rawHeapWords - - WEAK -> case pts of - pts0 : pts1 : pts2 : pts3 : rest -> pure $ WeakClosure - { info = itbl - , cfinalizers = pts0 - , key = pts1 - , value = pts2 - , finalizer = pts3 - , weakLink = case rest of - [] -> Nothing - [p] -> Just p - _ -> error $ "Expected 4 or 5 words in WEAK, but found more: " ++ show (length pts) - } - _ -> error $ "Expected 4 or 5 words in WEAK, but found less: " ++ show (length pts) - TSO | ( u_lnk : u_gbl_lnk : tso_stack : u_trec : u_blk_ex : u_bq : other) <- pts - -> withArray rawHeapWords (\ptr -> do - fields <- FFIClosures.peekTSOFields decodeCCS ptr - pure $ TSOClosure - { info = itbl - , link = u_lnk - , global_link = u_gbl_lnk - , tsoStack = tso_stack - , trec = u_trec - , blocked_exceptions = u_blk_ex - , bq = u_bq - , thread_label = case other of - [tl] -> Just tl - [] -> Nothing - _ -> error $ "thead_label:Expected 0 or 1 extra arguments" - , what_next = FFIClosures.tso_what_next fields - , why_blocked = FFIClosures.tso_why_blocked fields - , flags = FFIClosures.tso_flags fields - , threadId = FFIClosures.tso_threadId fields - , saved_errno = FFIClosures.tso_saved_errno fields - , tso_dirty = FFIClosures.tso_dirty fields - , alloc_limit = FFIClosures.tso_alloc_limit fields - , tot_stack_size = FFIClosures.tso_tot_stack_size fields - , prof = FFIClosures.tso_prof fields - }) - | otherwise - -> fail $ "Expected at least 6 ptr arguments to TSO, found " - ++ show (length pts) - STACK - | [] <- pts - -> withArray rawHeapWords (\ptr -> do - fields <- FFIClosures.peekStackFields ptr - pure $ StackClosure - { info = itbl - , stack_size = FFIClosures.stack_size fields - , stack_dirty = FFIClosures.stack_dirty fields -#if __GLASGOW_HASKELL__ >= 811 - , stack_marking = FFIClosures.stack_marking fields -#endif - }) - | otherwise - -> fail $ "Expected 0 ptr argument to STACK, found " - ++ show (length pts) - - _ -> - pure $ UnsupportedClosure itbl ===================================== libraries/ghc-heap/GHC/Exts/Stack.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE CPP #-} +#if MIN_TOOL_VERSION_ghc(9,7,0) +{-# LANGUAGE RecordWildCards #-} +module GHC.Exts.Stack ( + -- * Stack inspection + decodeStack + , stackFrameSize + ) +where +import GHC.Exts.Heap.Closures +import GHC.Exts.Stack.Decode +import GHC.Exts.Stack.Constants +import Prelude + +-- TODO: Pattern match may move to function arguments +stackFrameSize :: StackFrame -> Int +stackFrameSize = + \c -> + case c of + UpdateFrame {} -> sizeStgUpdateFrame + CatchFrame {} -> sizeStgCatchFrame + CatchStmFrame {} -> sizeStgCatchSTMFrame + CatchRetryFrame {} -> sizeStgCatchRetryFrame + AtomicallyFrame {} -> sizeStgAtomicallyFrame + RetSmall {..} -> sizeStgClosure + length stack_payload + RetBig {..} -> sizeStgClosure + length stack_payload + RetFun {..} -> sizeStgRetFunFrame + length retFunPayload + -- The one additional word is a pointer to the StgBCO in the closure's payload + RetBCO {..} -> sizeStgClosure + 1 + length bcoArgs + -- The one additional word is a pointer to the next stack chunk + UnderflowFrame {} -> sizeStgClosure + 1 + _ -> error "Unexpected closure type" +#else +module GHC.Exts.Stack where +#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -23,9 +23,9 @@ import Data.Maybe import Foreign import GHC.Exts import GHC.Exts.Heap.ClosureTypes -import GHC.Exts.Heap.Closures +import GHC.Exts.Heap.Closures (Box(..), RetFunType(..), Closure, GenClosure(UnknownTypeWordSizedPrimitive), StackFrame(..), StgStackClosure(..)) import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) -import GHC.Exts.Heap.Decode +import GHC.Exts.Heap import GHC.Exts.Heap.InfoTable import GHC.Exts.Stack.Constants import GHC.IO (IO (..)) @@ -296,8 +296,6 @@ decodeBitmaps stackSnapshot# index bitmapWords size = getIndex (SfiClosure _ i) = i getIndex (SfiPrimitive _ i) = i --- TODO: (auto-) format the code --- TODO: Check all functions with two WordOffsets? Can't it be one? decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = do @@ -411,32 +409,6 @@ unpackStackFrame (StackSnapshot stackSnapshot#, index) = do } x -> error $ "Unexpected closure type on stack: " ++ show x --- TODO: Duplicate -getClosureDataFromHeapObject :: - -- | Heap object to decode. - a -> - -- | Heap representation of the closure. - IO Closure -getClosureDataFromHeapObject x = do - case unpackClosure# x of - (# infoTableAddr, heapRep, pointersArray #) -> do - let infoTablePtr = Ptr infoTableAddr - ptrList = - [ case indexArray# pointersArray i of - (# ptr #) -> Box ptr - | I# i <- [0 .. I# (sizeofArray# pointersArray) - 1] - ] - - infoTable <- peekItbl infoTablePtr - case tipe infoTable of - TSO -> pure $ UnsupportedClosure infoTable - STACK -> pure $ UnsupportedClosure infoTable - _ -> getClosureDataFromHeapRep heapRep infoTablePtr ptrList - --- | Like 'getClosureData', but taking a 'Box', so it is easier to work with. -getBoxedClosureData :: Box -> IO Closure -getBoxedClosureData (Box a) = getClosureDataFromHeapObject a - -- | Unbox 'Int#' from 'Int' toInt# :: Int -> Int# toInt# (I# i) = i @@ -482,5 +454,4 @@ decodeStack (StackSnapshot stack#) = do #else module GHC.Exts.Stack.Decode where -import GHC.Base (IO) #endif ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -39,7 +39,6 @@ library GHC.Exts.Heap.Closures GHC.Exts.Heap.ClosureTypes GHC.Exts.Heap.Constants - GHC.Exts.Heap.Decode GHC.Exts.Heap.InfoTable GHC.Exts.Heap.InfoTable.Types GHC.Exts.Heap.InfoTableProf @@ -52,4 +51,5 @@ library GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingDisabled GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled GHC.Exts.Stack.Constants + GHC.Exts.Stack GHC.Exts.Stack.Decode ===================================== libraries/ghc-heap/tests/ClosureSizeUtils.hs ===================================== @@ -11,7 +11,6 @@ module ClosureSizeUtils (assertSize, assertSizeUnlifted) where import Control.Monad import GHC.Exts -import GHC.Exts.Heap import GHC.Exts.Heap.Closures import GHC.Stack import Type.Reflection @@ -46,7 +45,7 @@ assertSizeBox -> Int -- ^ expected size in words -> IO () assertSizeBox x ty expected = do - !size <- closureSize x + let !size = closureSize x when (size /= expected') $ do putStrLn $ "closureSize ("++show ty++") == "++show size++", expected "++show expected' putStrLn $ prettyCallStack callStack ===================================== libraries/ghc-heap/tests/stack_misc_closures.hs ===================================== @@ -17,6 +17,7 @@ import Debug.Trace import GHC.Exts import GHC.Exts.Heap import GHC.Exts.Heap.Closures +import GHC.Exts.Stack import GHC.Exts.Stack.Decode import GHC.IO (IO (..)) import GHC.Stack (HasCallStack) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75c42867294427feb3c430151d1619600f19cb0c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75c42867294427feb3c430151d1619600f19cb0c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 15:19:13 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 11:19:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/supersven/riscv-ncg Message-ID: <6432d7717126e_3b005578cd44e8811580@gitlab.mail> Sven Tennie pushed new branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/supersven/riscv-ncg You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 15:23:51 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 11:23:51 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Fix overloaded naming issues Message-ID: <6432d887929b8_3b005578d8c1c48135c1@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 7aa6a581 by Sven Tennie at 2023-04-09T15:23:34+00:00 Fix overloaded naming issues - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -23,9 +23,9 @@ import Data.Maybe import Foreign import GHC.Exts import GHC.Exts.Heap.ClosureTypes -import GHC.Exts.Heap.Closures (Box(..), RetFunType(..), Closure, GenClosure(UnknownTypeWordSizedPrimitive), StackFrame(..), StgStackClosure(..)) +import GHC.Exts.Heap.Closures (RetFunType(..), Closure, GenClosure(UnknownTypeWordSizedPrimitive), StackFrame(..), StgStackClosure(..)) import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) -import GHC.Exts.Heap +import GHC.Exts.Heap (Box(..), getBoxedClosureData) import GHC.Exts.Heap.InfoTable import GHC.Exts.Stack.Constants import GHC.IO (IO (..)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7aa6a581a21544a442db1d68d7017ecddd8ae085 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7aa6a581a21544a442db1d68d7017ecddd8ae085 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 15:24:24 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 11:24:24 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 36 commits: Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage Message-ID: <6432d8a837308_3b005578f365388140a1@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - 3bb3013f by Sven Tennie at 2023-04-09T15:24:12+00:00 ghc-heap: Decode StgStack and its frames Previously, ghc-heap could only decode heap closures. The approach is explained in detail in note [Decoding the stack]. - - - - - a05e65b0 by Sven Tennie at 2023-04-09T15:24:12+00:00 Splitting StackFrames from Closures: Compiles - - - - - 4a937757 by Sven Tennie at 2023-04-09T15:24:12+00:00 Fix tests - - - - - 6df604f2 by Sven Tennie at 2023-04-09T15:24:12+00:00 Validate - - - - - 3ab93797 by Sven Tennie at 2023-04-09T15:24:12+00:00 Remove unnecessary instances - - - - - b9934345 by Sven Tennie at 2023-04-09T15:24:12+00:00 Smaller diff - - - - - 97cb9a06 by Sven Tennie at 2023-04-09T15:24:12+00:00 Add comment - - - - - 5b7f3162 by Sven Tennie at 2023-04-09T15:24:12+00:00 Add comment - - - - - c41f7b6f by Sven Tennie at 2023-04-09T15:24:12+00:00 Add C function signatures to Cmm for readability - - - - - ca6f2e87 by Sven Tennie at 2023-04-09T15:24:12+00:00 Better assertion message - - - - - 818cbf2f by Sven Tennie at 2023-04-09T15:24:12+00:00 More iterations to get more underflow frames - - - - - 0de3fe37 by Sven Tennie at 2023-04-09T15:24:12+00:00 Rename - - - - - 833bf9ec by Sven Tennie at 2023-04-09T15:24:12+00:00 getClosure returns Closure - - - - - 3f099552 by Sven Tennie at 2023-04-09T15:24:13+00:00 getClosure: One WordOffset is enough - - - - - 28f0ce24 by Sven Tennie at 2023-04-09T15:24:13+00:00 getWord: One offset is enough - - - - - 598156d6 by Sven Tennie at 2023-04-09T15:24:13+00:00 decodeBitmaps: One offset is enough - - - - - f0bdc0b5 by Sven Tennie at 2023-04-09T15:24:13+00:00 Formatting, notes - - - - - 574cd35a by Sven Tennie at 2023-04-09T15:24:13+00:00 Minimize diff - - - - - 9887028d by Sven Tennie at 2023-04-09T15:24:13+00:00 Fix overloaded naming issues - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Reader.hs - docs/users_guide/using-warnings.rst - libraries/base/Data/Array/Byte.hs - libraries/base/Foreign/Marshal/Utils.hs - libraries/base/GHC/Base.hs - libraries/base/Unsafe/Coerce.hs - libraries/base/changelog.md - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/InfoTable/Types.hsc - + libraries/ghc-heap/GHC/Exts/Stack.hs - + libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc - + libraries/ghc-heap/GHC/Exts/Stack/Decode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7aa6a581a21544a442db1d68d7017ecddd8ae085...9887028dd014359f2013dfe67ca857ad4c0e1373 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7aa6a581a21544a442db1d68d7017ecddd8ae085...9887028dd014359f2013dfe67ca857ad4c0e1373 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 9 16:27:53 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 09 Apr 2023 12:27:53 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 2 commits: Reduce diff Message-ID: <6432e7894389d_3b005579fea0008269f@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: c7d7be36 by Sven Tennie at 2023-04-09T16:27:02+00:00 Reduce diff - - - - - 1409fc67 by Sven Tennie at 2023-04-09T16:27:17+00:00 Use function level pattern match - - - - - 3 changed files: - libraries/ghc-heap/GHC/Exts/Stack.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/Run.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack.hs ===================================== @@ -1,35 +1,34 @@ {-# LANGUAGE CPP #-} #if MIN_TOOL_VERSION_ghc(9,7,0) {-# LANGUAGE RecordWildCards #-} -module GHC.Exts.Stack ( - -- * Stack inspection - decodeStack - , stackFrameSize - ) + +module GHC.Exts.Stack + ( -- * Stack inspection + decodeStack, + stackFrameSize, + ) where + import GHC.Exts.Heap.Closures -import GHC.Exts.Stack.Decode import GHC.Exts.Stack.Constants +import GHC.Exts.Stack.Decode import Prelude --- TODO: Pattern match may move to function arguments stackFrameSize :: StackFrame -> Int -stackFrameSize = - \c -> - case c of - UpdateFrame {} -> sizeStgUpdateFrame - CatchFrame {} -> sizeStgCatchFrame - CatchStmFrame {} -> sizeStgCatchSTMFrame - CatchRetryFrame {} -> sizeStgCatchRetryFrame - AtomicallyFrame {} -> sizeStgAtomicallyFrame - RetSmall {..} -> sizeStgClosure + length stack_payload - RetBig {..} -> sizeStgClosure + length stack_payload - RetFun {..} -> sizeStgRetFunFrame + length retFunPayload - -- The one additional word is a pointer to the StgBCO in the closure's payload - RetBCO {..} -> sizeStgClosure + 1 + length bcoArgs - -- The one additional word is a pointer to the next stack chunk - UnderflowFrame {} -> sizeStgClosure + 1 - _ -> error "Unexpected closure type" +stackFrameSize (UpdateFrame {}) = sizeStgUpdateFrame +stackFrameSize (CatchFrame {}) = sizeStgCatchFrame +stackFrameSize (CatchStmFrame {}) = sizeStgCatchSTMFrame +stackFrameSize (CatchRetryFrame {}) = sizeStgCatchRetryFrame +stackFrameSize (AtomicallyFrame {}) = sizeStgAtomicallyFrame +stackFrameSize (RetSmall {..}) = sizeStgClosure + length stack_payload +stackFrameSize (RetBig {..}) = sizeStgClosure + length stack_payload +stackFrameSize (RetFun {..}) = sizeStgRetFunFrame + length retFunPayload +-- The one additional word is a pointer to the StgBCO in the closure's payload +stackFrameSize (RetBCO {..}) = sizeStgClosure + 1 + length bcoArgs +-- The one additional word is a pointer to the next stack chunk +stackFrameSize (UnderflowFrame {}) = sizeStgClosure + 1 +stackFrameSize _ = error "Unexpected stack frame type" + #else module GHC.Exts.Stack where #endif ===================================== libraries/ghci/GHCi/Message.hs ===================================== @@ -474,7 +474,7 @@ instance Binary Heap.TsoFlags instance Binary Heap.StgInfoTable instance Binary Heap.ClosureType instance Binary Heap.PrimType -instance (Binary a) => Binary (Heap.GenClosure a) +instance Binary a => Binary (Heap.GenClosure a) data Msg = forall a . (Binary a, Show a) => Msg (Message a) ===================================== libraries/ghci/GHCi/Run.hs ===================================== @@ -1,4 +1,5 @@ -{-# LANGUAGE GADTs, RecordWildCards, MagicHash, ScopedTypeVariables, CPP, UnboxedTuples #-} +{-# LANGUAGE GADTs, RecordWildCards, MagicHash, ScopedTypeVariables, CPP, + UnboxedTuples #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} -- | @@ -372,21 +373,21 @@ mkString0 bs = B.unsafeUseAsCStringLen bs $ \(cstr,len) -> do return (castRemotePtr (toRemotePtr ptr)) mkCostCentres :: String -> [(String,String)] -> IO [RemotePtr CostCentre] - - - - - - - - - - - - - +#if defined(PROFILING) +mkCostCentres mod ccs = do + c_module <- newCString mod + mapM (mk_one c_module) ccs + where + mk_one c_module (decl_path,srcspan) = do + c_name <- newCString decl_path + c_srcspan <- newCString srcspan + toRemotePtr <$> c_mkCostCentre c_name c_module c_srcspan + +foreign import ccall unsafe "mkCostCentre" + c_mkCostCentre :: Ptr CChar -> Ptr CChar -> Ptr CChar -> IO (Ptr CostCentre) +#else mkCostCentres _ _ = return [] - +#endif getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue) getIdValFromApStack apStack (I# stackDepth) = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9887028dd014359f2013dfe67ca857ad4c0e1373...1409fc6789205cfaad0e909b4313d6ebd01a3231 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9887028dd014359f2013dfe67ca857ad4c0e1373...1409fc6789205cfaad0e909b4313d6ebd01a3231 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 05:24:27 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Mon, 10 Apr 2023 01:24:27 -0400 Subject: [Git][ghc/ghc][wip/expand-do] 27 commits: Allow WARNING pragmas to be controlled with custom categories Message-ID: <64339d8bc3bfd_3b0055866c6b3886414@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - 80fdb84d by Apoorv Ingle at 2023-03-27T11:12:44-05:00 HsExpand for HsDo Fixes for #18324 - fixed rec do blocks to use mfix - make sure fail is used for pattern match failures in bind statments - - - - - bb631e73 by Apoorv Ingle at 2023-03-27T11:12:44-05:00 move expand_do_stmts GHC.Tc.Match so that we can type check patterns and determine more accurately if we need to generate a fail block - - - - - 72161935 by Apoorv Ingle at 2023-03-27T11:12:44-05:00 do stmt expansion for Applicative Do - - - - - 49e28b44 by Apoorv Ingle at 2023-03-27T11:12:44-05:00 expansion of a bind statement may not be as easy as it looks. T18324b.hs is a an example. I think its some delicate interaction between quick look and type families - - - - - fad59d32 by Apoorv Ingle at 2023-03-27T11:12:44-05:00 do not add explicit return for `mfix` mdo blocks. This whole last stmt business is very messy. - - - - - 25a888e0 by Apoorv Ingle at 2023-03-27T11:12:44-05:00 wrap the mfix function arg tuple in a lazy pattern so that we do not go in a recursive loop - - - - - 17cb23ea by Apoorv Ingle at 2023-03-28T19:39:55-05:00 carry over some location info into the expanded expresion - - - - - 6b5ddc4f by Apoorv Ingle at 2023-04-10T00:23:05-05:00 trying to add warnings for unused bindings at type checking rather than HsToCore. Current state is that spurious warnings are generated - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Unit/Module/Warnings.hs - compiler/GHC/Utils/Error.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/9.8.1-notes.rst - docs/users_guide/exts/pragmas.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7bbd88de8535ade0bb26864e2d0021550a83ddcb...6b5ddc4f8471d50696e5a771327fb99968b534eb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7bbd88de8535ade0bb26864e2d0021550a83ddcb...6b5ddc4f8471d50696e5a771327fb99968b534eb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 10:10:37 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 10 Apr 2023 06:10:37 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Minimum to compile empty Cmm files Message-ID: <6433e09dca760_3b00558ac4b94c8760e2@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: aae14179 by Sven Tennie at 2023-04-10T10:10:05+00:00 Minimum to compile empty Cmm files - - - - - 4 changed files: - compiler/GHC/CmmToAsm/RISCV64.hs - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/Driver/Backend.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64.hs ===================================== @@ -38,7 +38,7 @@ ncgRISCV64 config = NcgImpl , invertCondBranches = \_ _ -> id } --- | Instruction instance for powerpc +-- | Instruction instance for RISC-V 64bit instance Instruction RISCV64.Instr where regUsageOfInstr = RISCV64.regUsageOfInstr patchRegsOfInstr = RISCV64.patchRegsOfInstr ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -8,7 +8,8 @@ import Prelude cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr] -cmmTopCodeGen _ = error "TODO: cmmTopCodeGen" +-- "TODO: cmmTopCodeGen" +cmmTopCodeGen _ = pure [] generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) ===================================== compiler/GHC/Driver/Backend.hs ===================================== @@ -217,6 +217,7 @@ platformNcgSupported platform = if ArchPPC_64 {} -> True ArchAArch64 -> True ArchWasm32 -> True + ArchRISCV64 -> True _ -> False -- | Is the platform supported by the JS backend? ===================================== compiler/ghc.cabal.in ===================================== @@ -261,6 +261,12 @@ Library GHC.CmmToAsm.Reg.Liveness GHC.CmmToAsm.Reg.Target GHC.CmmToAsm.Reg.Utils + GHC.CmmToAsm.RISCV64 + GHC.CmmToAsm.RISCV64.CodeGen + GHC.CmmToAsm.RISCV64.Instr + GHC.CmmToAsm.RISCV64.Ppr + GHC.CmmToAsm.RISCV64.RegInfo + GHC.CmmToAsm.RISCV64.Regs GHC.CmmToAsm.Types GHC.CmmToAsm.Utils GHC.CmmToAsm.X86 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aae14179e71d0430e45a43d323e693d7e33d47ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aae14179e71d0430e45a43d323e693d7e33d47ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 13:25:59 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 10 Apr 2023 09:25:59 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 4 commits: Store dehydrated data structures in CgModBreaks Message-ID: <64340e6731245_3b00558e1f48a089083c@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: b5999c54 by Matthew Pickering at 2023-04-10T18:53:09+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - f3cbc858 by Matthew Pickering at 2023-04-10T18:53:16+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - 808afe94 by Matthew Pickering at 2023-04-10T18:53:24+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 2f6b954d by Matthew Pickering at 2023-04-10T18:55:41+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 8 changed files: - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Unit/Module/Graph.hs Changes: ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -22,12 +22,10 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Data.SizedSeq -import GHC.Types.Id import GHC.Types.Name import GHC.Types.Name.Env import GHC.Utils.Outputable import GHC.Builtin.PrimOps -import GHC.Core.Type import GHC.Types.SrcLoc import GHCi.BreakArray import GHCi.RemoteTypes @@ -40,10 +38,10 @@ import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap -import Data.Maybe (catMaybes) import qualified GHC.Exts.Heap as Heap import GHC.Stack.CCS import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList ) +import GHC.Iface.Syntax -- ----------------------------------------------------------------------------- -- Compiled Byte Code @@ -163,18 +161,22 @@ instance NFData BCONPtr where rnf x = x `seq` () -- | Information about a breakpoint that we know at code-generation time +-- In order to be used, this needs to be hydrated relative to the current HscEnv by +-- 'hydrateCgBreakInfo'. Everything here can be fully forced and that's critical for +-- preventing space leaks (see #22530) data CgBreakInfo = CgBreakInfo - { cgb_vars :: [Maybe (Id,Word16)] - , cgb_resty :: Type + { cgb_tyvars :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint + , cgb_vars :: ![Maybe (IfaceIdBndr, Word16)] + , cgb_resty :: !IfaceType } -- See Note [Syncing breakpoint info] in GHC.Runtime.Eval --- Not a real NFData instance because we can't rnf Id or Type seqCgBreakInfo :: CgBreakInfo -> () seqCgBreakInfo CgBreakInfo{..} = - rnf (map snd (catMaybes (cgb_vars))) `seq` - seqType cgb_resty + rnf cgb_tyvars `seq` + rnf cgb_vars `seq` + rnf cgb_resty instance Outputable UnlinkedBCO where ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs) ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -42,12 +42,18 @@ module GHC.CoreToIface , toIfaceVar -- * Other stuff , toIfaceLFInfo + -- * CgBreakInfo + , dehydrateCgBreakInfo ) where import GHC.Prelude +import Data.Word + import GHC.StgToCmm.Types +import GHC.ByteCode.Types + import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -658,6 +664,16 @@ toIfaceLFInfo nm lfi = case lfi of LFLetNoEscape -> panic "toIfaceLFInfo: LFLetNoEscape" +-- Dehydrating CgBreakInfo + +dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word16)] -> Type -> CgBreakInfo +dehydrateCgBreakInfo ty_vars idOffSets tick_ty = + CgBreakInfo + { cgb_tyvars = map toIfaceTvBndr ty_vars + , cgb_vars = map (fmap (\(i, offset) -> (toIfaceIdBndr i, offset))) idOffSets + , cgb_resty = toIfaceType tick_ty + } + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -1073,7 +1073,8 @@ tidyTopName mod name_cache maybe_ref occ_env id -- we have to update the name cache in a nice atomic fashion | local && internal = do uniq <- takeUniqFromNameCache name_cache - let new_local_name = mkInternalName uniq occ' loc + -- See #19619 + let new_local_name = occ' `seq` mkInternalName uniq occ' loc return (occ_env', new_local_name) -- Even local, internal names must get a unique occurrence, because -- if we do -split-objs we externalise the name later, in the code generator ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -11,6 +11,7 @@ Type checking of type signatures in interface files {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} +{-# LANGUAGE RecordWildCards #-} module GHC.IfaceToCore ( tcLookupImported_maybe, @@ -22,11 +23,16 @@ module GHC.IfaceToCore ( tcIfaceAnnotations, tcIfaceCompleteMatches, tcIfaceExpr, -- Desired by HERMIT (#7683) tcIfaceGlobal, - tcIfaceOneShot + tcIfaceOneShot, + hydrateCgBreakInfo ) where import GHC.Prelude +import GHC.ByteCode.Types + +import Data.Word + import GHC.Driver.Env import GHC.Driver.Session @@ -2069,3 +2075,12 @@ bindIfaceTyConBinderX :: (IfaceBndr -> (TyCoVar -> IfL a) -> IfL a) bindIfaceTyConBinderX bind_tv (Bndr tv vis) thing_inside = bind_tv tv $ \tv' -> thing_inside (Bndr tv' vis) + +-- CgBreakInfo + +hydrateCgBreakInfo :: CgBreakInfo -> IfL ([Maybe (Id, Word16)], Type) +hydrateCgBreakInfo CgBreakInfo{..} = do + bindIfaceTyVars cgb_tyvars $ \_ -> do + result_ty <- tcIfaceType cgb_resty + mbVars <- mapM (traverse (\(if_gbl, offset) -> (,offset) <$> bindIfaceId if_gbl return)) cgb_vars + return (mbVars, result_ty) ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -136,6 +136,7 @@ import GHC.Tc.Solver (simplifyWantedsTcM) import GHC.Tc.Utils.Monad import GHC.Core.Class (classTyCon) import GHC.Unit.Env +import GHC.IfaceToCore -- ----------------------------------------------------------------------------- -- running a statement interactively @@ -562,12 +563,19 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv (Just BreakInfo{..}) = do breaks = getModBreaks hmi info = expectJust "bindLocalsAtBreakpoint2" $ IntMap.lookup breakInfo_number (modBreaks_breakInfo breaks) - mbVars = cgb_vars info - result_ty = cgb_resty info occs = modBreaks_vars breaks ! breakInfo_number span = modBreaks_locs breaks ! breakInfo_number decl = intercalate "." $ modBreaks_decls breaks ! breakInfo_number + -- Rehydrate to understand the breakpoint info relative to the current environment. + -- This design is critical to preventing leaks (#22530) + (mbVars, result_ty) <- initIfaceLoad hsc_env + $ initIfaceLcl breakInfo_module (text "debugger") NotBoot + $ hydrateCgBreakInfo info + + + let + -- Filter out any unboxed ids by changing them to Nothings; -- we can't bind these at the prompt mbPointers = nullUnboxed <$> mbVars ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -90,6 +90,7 @@ import Data.Either ( partitionEithers ) import GHC.Stg.Syntax import qualified Data.IntSet as IntSet +import GHC.CoreToIface -- ----------------------------------------------------------------------------- -- Generating byte code for a complete module @@ -371,10 +372,8 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs) rhs) this_mod <- moduleName <$> getCurrentModule platform <- profilePlatform <$> getProfile let idOffSets = getVarOffSets platform d p fvs - let breakInfo = CgBreakInfo - { cgb_vars = idOffSets - , cgb_resty = tick_ty - } + ty_vars = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs) + let breakInfo = dehydrateCgBreakInfo ty_vars idOffSets tick_ty newBreakInfo tick_no breakInfo hsc_env <- getHscEnv let cc | Just interp <- hsc_interp hsc_env ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -151,7 +151,7 @@ instance Outputable NameSort where ppr System = text "system" instance NFData Name where - rnf Name{..} = rnf n_sort + rnf Name{..} = rnf n_sort `seq` rnf n_occ `seq` n_uniq `seq` rnf n_loc instance NFData NameSort where rnf (External m) = rnf m ===================================== compiler/GHC/Unit/Module/Graph.hs ===================================== @@ -126,8 +126,8 @@ nodeKeyUnitId (NodeKey_Unit iu) = instUnitInstanceOf iu nodeKeyUnitId (NodeKey_Module mk) = mnkUnitId mk nodeKeyUnitId (NodeKey_Link uid) = uid -data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: ModuleNameWithIsBoot - , mnkUnitId :: UnitId } deriving (Eq, Ord) +data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: !ModuleNameWithIsBoot + , mnkUnitId :: !UnitId } deriving (Eq, Ord) instance Outputable ModNodeKeyWithUid where ppr (ModNodeKeyWithUid mnwib uid) = ppr uid <> colon <> ppr mnwib View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2838d3c7741d58f0c30729e34b0d2c776a2de985...2f6b954dc4a660a4b28ef41d66302bc6c854f81f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2838d3c7741d58f0c30729e34b0d2c776a2de985...2f6b954dc4a660a4b28ef41d66302bc6c854f81f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 13:26:39 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 10 Apr 2023 09:26:39 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 50 commits: Only gc sparks locally when we can ensure marking is done. Message-ID: <64340e8f752bf_3b00558df849948913cd@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 4909bb4b by Andreas Klebinger at 2023-04-10T18:56:16+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 38dfa83d by Simon Peyton Jones at 2023-04-10T18:56:16+05:30 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 (cherry picked from commit 317f45c154f6fe25d50ef2f3febcc5883ff1b1ca) - - - - - 359da777 by Matthew Pickering at 2023-04-10T18:56:16+05:30 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s (cherry picked from commit a960ca817d6ad0109ea6edda50da3902cc538e86) - - - - - 9e2a51ef by Matthew Pickering at 2023-04-10T18:56:16+05:30 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. (cherry picked from commit 734847108420cf826a807c30ad54651659cf3a08) - - - - - 293b441d by Matthew Pickering at 2023-04-10T18:56:16+05:30 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes (cherry picked from commit 8c0ea25fb4a27d4729aabf73f4c00b912bb0c58d) - - - - - 9fdc6e61 by Sebastian Graf at 2023-04-10T18:56:16+05:30 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite (cherry picked from commit e3fff7512bbf989386faaa1dccafdad1deabde84) - - - - - 297632b4 by Oleg Grenrus at 2023-04-10T18:56:17+05:30 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general (cherry picked from commit 1b812b6973a25cb1962e2fc543d2c4ed3cf31f3c) - - - - - 3945cac1 by Viktor Dukhovni at 2023-04-10T18:56:17+05:30 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 (cherry picked from commit fc02f3bbb5f47f880465e22999ba9794f658d8f6) - - - - - dd9f177e by Ryan Scott at 2023-04-10T18:56:17+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - fd17beb5 by Cheng Shao at 2023-04-10T18:56:17+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - efa24a96 by Ben Gamari at 2023-04-10T18:56:17+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - 7af9eda7 by Ben Gamari at 2023-04-10T18:56:17+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - 890b9c02 by Ben Gamari at 2023-04-10T18:56:17+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - aef73e13 by Ben Gamari at 2023-04-10T18:56:17+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - 7551b099 by Zubin Duggal at 2023-04-10T18:56:17+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 8327b6ca by Ben Gamari at 2023-04-10T18:56:17+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - 403b30d6 by Zubin Duggal at 2023-04-10T18:56:17+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - a5cd01b7 by Ben Gamari at 2023-04-10T18:56:17+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - d8a750ce by sheaf at 2023-04-10T18:56:17+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - ec4b4179 by Ben Gamari at 2023-04-10T18:56:17+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - b8da0933 by Ben Gamari at 2023-04-10T18:56:17+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - ebc6ea53 by Ben Gamari at 2023-04-10T18:56:17+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 23289b08 by Ben Gamari at 2023-04-10T18:56:17+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 8b800699 by Ben Gamari at 2023-04-10T18:56:17+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - 09c3d027 by Andreas Klebinger at 2023-04-10T18:56:17+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - 48ec4a45 by Matthew Pickering at 2023-04-10T18:56:17+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - 44075bd2 by Sylvain Henry at 2023-04-10T18:56:18+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - 40ad01d8 by Ben Gamari at 2023-04-10T18:56:18+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - 50a42c5b by Matthew Pickering at 2023-04-10T18:56:18+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - ae3f5c6a by Matthew Pickering at 2023-04-10T18:56:18+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - 0e7cf6b5 by Matthew Pickering at 2023-04-10T18:56:18+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - c7f2cf3d by Matthew Pickering at 2023-04-10T18:56:18+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - de69d180 by Matthew Pickering at 2023-04-10T18:56:18+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 19c5be74 by Matthew Pickering at 2023-04-10T18:56:18+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - 75a638f2 by Matthew Pickering at 2023-04-10T18:56:18+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - 0f36709d by Matthew Pickering at 2023-04-10T18:56:18+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - de55bb54 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - 0e556078 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 2ed4b76b by Matthew Pickering at 2023-04-10T18:56:18+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 33a5f0f0 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 583e2b93 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - ea8a0a68 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 073d846a by Matthew Pickering at 2023-04-10T18:56:18+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 2cfab9f1 by Matthew Pickering at 2023-04-10T18:56:18+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - bd951748 by Simon Peyton Jones at 2023-04-10T18:56:18+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 88c4897c by Matthew Pickering at 2023-04-10T18:56:19+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - b846f949 by Matthew Pickering at 2023-04-10T18:56:19+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - fd263119 by Matthew Pickering at 2023-04-10T18:56:19+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - d6694086 by Matthew Pickering at 2023-04-10T18:56:19+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 39106ac3 by Matthew Pickering at 2023-04-10T18:56:19+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Eval.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f6b954dc4a660a4b28ef41d66302bc6c854f81f...39106ac3493a2c599da0748780ca054a0bf80068 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2f6b954dc4a660a4b28ef41d66302bc6c854f81f...39106ac3493a2c599da0748780ca054a0bf80068 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 13:52:29 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 10 Apr 2023 09:52:29 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Add flag -fno-empty-fasm Message-ID: <6434149daf430_3b00558e675a508917ee@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: 1df55c28 by Sven Tennie at 2023-04-10T13:50:14+00:00 Add flag -fno-empty-fasm This makes it possible to incrementally implement the NCG. Instead of heaving to be able to compile all .cmm files in GHC. - - - - - 7 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/RISCV64.hs - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -148,10 +148,10 @@ import System.IO import System.Directory ( getCurrentDirectory ) -------------------- -nativeCodeGen :: forall a . Logger -> ToolSettings -> NCGConfig -> ModLocation -> Handle -> UniqSupply +nativeCodeGen :: forall a . Bool -> Logger -> ToolSettings -> NCGConfig -> ModLocation -> Handle -> UniqSupply -> Stream IO RawCmmGroup a -> IO a -nativeCodeGen logger ts config modLoc h us cmms +nativeCodeGen no_empty_asm logger ts config modLoc h us cmms = let platform = ncgPlatform config nCG' :: ( OutputableP Platform statics, Outputable jumpDest, Instruction instr) => NcgImpl statics instr jumpDest -> IO a @@ -167,7 +167,7 @@ nativeCodeGen logger ts config modLoc h us cmms ArchAlpha -> panic "nativeCodeGen: No NCG for Alpha" ArchMipseb -> panic "nativeCodeGen: No NCG for mipseb" ArchMipsel -> panic "nativeCodeGen: No NCG for mipsel" - ArchRISCV64 -> nCG' (RISCV64.ncgRISCV64 config) + ArchRISCV64 -> nCG' (RISCV64.ncgRISCV64 no_empty_asm config) ArchLoongArch64->panic "nativeCodeGen: No NCG for LoongArch64" ArchUnknown -> panic "nativeCodeGen: No NCG for unknown arch" ArchJavaScript-> panic "nativeCodeGen: No NCG for JavaScript" ===================================== compiler/GHC/CmmToAsm/RISCV64.hs ===================================== @@ -19,10 +19,10 @@ import qualified GHC.CmmToAsm.RISCV64.CodeGen as RISCV64 import qualified GHC.CmmToAsm.RISCV64.Regs as RISCV64 import qualified GHC.CmmToAsm.RISCV64.RegInfo as RISCV64 -ncgRISCV64 :: NCGConfig -> NcgImpl RawCmmStatics RISCV64.Instr RISCV64.JumpDest -ncgRISCV64 config = NcgImpl +ncgRISCV64 :: Bool -> NCGConfig -> NcgImpl RawCmmStatics RISCV64.Instr RISCV64.JumpDest +ncgRISCV64 no_empty_asm config = NcgImpl { ncgConfig = config - , cmmTopCodeGen = RISCV64.cmmTopCodeGen + , cmmTopCodeGen = if no_empty_asm then RISCV64.cmmTopCodeGen else RISCV64.emptyCmmTopCodeGen , generateJumpTableForInstr = RISCV64.generateJumpTableForInstr , getJumpDestBlockId = RISCV64.getJumpDestBlockId , canShortcut = RISCV64.canShortcut ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -1,15 +1,79 @@ +{-# LANGUAGE GADTs #-} module GHC.CmmToAsm.RISCV64.CodeGen where import GHC.CmmToAsm.Types import GHC.CmmToAsm.Monad import GHC.CmmToAsm.RISCV64.Instr import Prelude +import GHC.Cmm +import GHC.Cmm.Utils +import Control.Monad +import GHC.Cmm.Dataflow.Block +import GHC.Data.OrdList +import GHC.Cmm.Dataflow +import GHC.Driver.Ppr (showPprUnsafe) +import GHC.Plugins (Outputable) +import GHC.Driver.Ppr (showSDocUnsafe) +import GHC.Utils.Outputable + +-- | Don't try to compile all GHC Cmm files in the beginning. +-- Ignore them. There's a flag to decide we really want to emit something. +emptyCmmTopCodeGen + :: RawCmmDecl + -> NatM [NatCmmDecl RawCmmStatics Instr] +-- "TODO: cmmTopCodeGen" +emptyCmmTopCodeGen _ = return [] cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr] -- "TODO: cmmTopCodeGen" -cmmTopCodeGen _ = pure [] +cmmTopCodeGen (CmmProc info lab live graph) = do + let blocks = toBlockListEntryFirst graph + (nat_blocks,statics) <- mapAndUnzipM basicBlockCodeGen blocks + let proc = CmmProc info lab live (ListGraph $ concat nat_blocks) + tops = proc : concat statics + return tops +cmmTopCodeGen (CmmData sec dat) = + return [CmmData sec dat] -- no translation, we just use CmmStatic + +basicBlockCodeGen + :: Block CmmNode C C + -> NatM ( [NatBasicBlock Instr] + , [NatCmmDecl RawCmmStatics Instr]) +basicBlockCodeGen block = do + let (_, nodes, tail) = blockSplit block + id = entryLabel block + stmts = blockToList nodes + loc_instrs = nilOL + mid_instrs <- stmtsToInstrs stmts + tail_instrs <- stmtToInstrs tail + let instrs = loc_instrs `appOL` mid_instrs `appOL` tail_instrs + let + (top,other_blocks,statics) = foldrOL mkBlocks ([],[],[]) instrs + + mkBlocks (NEWBLOCK id) (instrs,blocks,statics) + = ([], BasicBlock id instrs : blocks, statics) + mkBlocks (LDATA sec dat) (instrs,blocks,statics) + = error "TODO: basicBlockCodeGen" -- (instrs, blocks, CmmData sec dat:statics) + mkBlocks instr (instrs,blocks,statics) + = (instr:instrs, blocks, statics) + return (BasicBlock id top : other_blocks, statics) + +type InstrBlock + = OrdList Instr + +stmtsToInstrs :: [CmmNode e x] -> NatM InstrBlock +stmtsToInstrs stmts + = do instrss <- mapM stmtToInstrs stmts + return (concatOL instrss) + +stmtToInstrs :: CmmNode e x -> NatM InstrBlock +stmtToInstrs stmt = do + platform <- getPlatform + case stmt of + CmmComment s -> return (unitOL (COMMENT s)) + a -> error $ "TODO: stmtToInstrs" ++ (showSDocUnsafe . pdoc platform) a generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -10,10 +10,22 @@ import GHC.Utils.Outputable import GHC.Platform.Reg import GHC.CmmToAsm.Config import GHC.CmmToAsm.Instr +import GHC.Cmm data Instr -- comment pseudo-op = COMMENT FastString + -- some static data spat out during code + -- generation. Will be extracted before + -- pretty-printing. + | LDATA Section RawCmmStatics + + -- start a new basic block. Useful during + -- codegen, removed later. Preceding + -- instruction should be a jump, as per the + -- invariants for a BasicBlock (see Cmm). + | NEWBLOCK BlockId + allocMoreStack :: Int ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -63,6 +63,8 @@ import System.IO import Data.Set (Set) import qualified Data.Set as Set +import GHC.Data.EnumSet as EnumSet + {- ************************************************************************ * * @@ -199,9 +201,10 @@ outputAsm logger dflags this_mod location filenm cmm_stream = do ncg_uniqs <- mkSplitUniqSupply 'n' debugTraceMsg logger 4 (text "Outputing asm to" <+> text filenm) let ncg_config = initNCGConfig dflags this_mod + no_empty_asm = EnumSet.member Opt_NoEmptyAsm (generalFlags dflags) {-# SCC "OutputAsm" #-} doOutput filenm $ \h -> {-# SCC "NativeCodeGen" #-} - nativeCodeGen logger (toolSettings dflags) ncg_config location h ncg_uniqs cmm_stream + nativeCodeGen no_empty_asm logger (toolSettings dflags) ncg_config location h ncg_uniqs cmm_stream {- ************************************************************************ ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -217,6 +217,7 @@ data GeneralFlag | Opt_DistinctConstructorTables | Opt_InfoTableMap + | Opt_NoEmptyAsm | Opt_WarnIsError -- -Werror; makes warnings fatal | Opt_ShowWarnGroups -- Show the group a warning belongs to ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -297,6 +297,7 @@ import qualified GHC.Data.EnumSet as EnumSet import GHC.Foreign (withCString, peekCString) import qualified GHC.LanguageExtensions as LangExt +import GHC.Driver.Flags (GeneralFlag(Opt_NoEmptyAsm)) -- Note [Updating flag description in the User's Guide] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2913,6 +2914,8 @@ dynamic_flags_deps = [ (NoArg (setGeneralFlag Opt_DistinctConstructorTables)) , make_ord_flag defGhcFlag "finfo-table-map" (NoArg (setGeneralFlag Opt_InfoTableMap)) + , make_ord_flag defGhcFlag "fno-empty-fasm" + (NoArg (setGeneralFlag Opt_NoEmptyAsm)) ------ Compiler flags ----------------------------------------------- , make_ord_flag defGhcFlag "fasm" (NoArg (setObjBackend ncgBackend)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1df55c28d4fbbf3139621aca638dc7453035491b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1df55c28d4fbbf3139621aca638dc7453035491b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 15:59:18 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Mon, 10 Apr 2023 11:59:18 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 4 commits: Store dehydrated data structures in CgModBreaks Message-ID: <643432562c3ec_3b005590b9013c902643@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 4a393970 by Matthew Pickering at 2023-04-10T21:28:59+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - ff23d28e by Matthew Pickering at 2023-04-10T21:28:59+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - 6da12da8 by Matthew Pickering at 2023-04-10T21:28:59+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 08563ba7 by Matthew Pickering at 2023-04-10T21:29:00+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 8 changed files: - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Unit/Module/Graph.hs Changes: ===================================== compiler/GHC/ByteCode/Types.hs ===================================== @@ -22,12 +22,10 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Data.SizedSeq -import GHC.Types.Id import GHC.Types.Name import GHC.Types.Name.Env import GHC.Utils.Outputable import GHC.Builtin.PrimOps -import GHC.Core.Type import GHC.Types.SrcLoc import GHCi.BreakArray import GHCi.RemoteTypes @@ -40,10 +38,10 @@ import Data.Array.Base ( UArray(..) ) import Data.ByteString (ByteString) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap -import Data.Maybe (catMaybes) import qualified GHC.Exts.Heap as Heap import GHC.Stack.CCS import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList ) +import GHC.Iface.Syntax -- ----------------------------------------------------------------------------- -- Compiled Byte Code @@ -163,18 +161,22 @@ instance NFData BCONPtr where rnf x = x `seq` () -- | Information about a breakpoint that we know at code-generation time +-- In order to be used, this needs to be hydrated relative to the current HscEnv by +-- 'hydrateCgBreakInfo'. Everything here can be fully forced and that's critical for +-- preventing space leaks (see #22530) data CgBreakInfo = CgBreakInfo - { cgb_vars :: [Maybe (Id,Word16)] - , cgb_resty :: Type + { cgb_tyvars :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint + , cgb_vars :: ![Maybe (IfaceIdBndr, Word16)] + , cgb_resty :: !IfaceType } -- See Note [Syncing breakpoint info] in GHC.Runtime.Eval --- Not a real NFData instance because we can't rnf Id or Type seqCgBreakInfo :: CgBreakInfo -> () seqCgBreakInfo CgBreakInfo{..} = - rnf (map snd (catMaybes (cgb_vars))) `seq` - seqType cgb_resty + rnf cgb_tyvars `seq` + rnf cgb_vars `seq` + rnf cgb_resty instance Outputable UnlinkedBCO where ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs) ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -42,12 +42,18 @@ module GHC.CoreToIface , toIfaceVar -- * Other stuff , toIfaceLFInfo + -- * CgBreakInfo + , dehydrateCgBreakInfo ) where import GHC.Prelude +import Data.Word + import GHC.StgToCmm.Types +import GHC.ByteCode.Types + import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -658,6 +664,16 @@ toIfaceLFInfo nm lfi = case lfi of LFLetNoEscape -> panic "toIfaceLFInfo: LFLetNoEscape" +-- Dehydrating CgBreakInfo + +dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word16)] -> Type -> CgBreakInfo +dehydrateCgBreakInfo ty_vars idOffSets tick_ty = + CgBreakInfo + { cgb_tyvars = map toIfaceTvBndr ty_vars + , cgb_vars = map (fmap (\(i, offset) -> (toIfaceIdBndr i, offset))) idOffSets + , cgb_resty = toIfaceType tick_ty + } + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Iface/Tidy.hs ===================================== @@ -1073,7 +1073,8 @@ tidyTopName mod name_cache maybe_ref occ_env id -- we have to update the name cache in a nice atomic fashion | local && internal = do uniq <- takeUniqFromNameCache name_cache - let new_local_name = mkInternalName uniq occ' loc + -- See #19619 + let new_local_name = occ' `seq` mkInternalName uniq occ' loc return (occ_env', new_local_name) -- Even local, internal names must get a unique occurrence, because -- if we do -split-objs we externalise the name later, in the code generator ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -11,6 +11,8 @@ Type checking of type signatures in interface files {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} module GHC.IfaceToCore ( tcLookupImported_maybe, @@ -22,11 +24,16 @@ module GHC.IfaceToCore ( tcIfaceAnnotations, tcIfaceCompleteMatches, tcIfaceExpr, -- Desired by HERMIT (#7683) tcIfaceGlobal, - tcIfaceOneShot + tcIfaceOneShot, + hydrateCgBreakInfo ) where import GHC.Prelude +import GHC.ByteCode.Types + +import Data.Word + import GHC.Driver.Env import GHC.Driver.Session @@ -2069,3 +2076,12 @@ bindIfaceTyConBinderX :: (IfaceBndr -> (TyCoVar -> IfL a) -> IfL a) bindIfaceTyConBinderX bind_tv (Bndr tv vis) thing_inside = bind_tv tv $ \tv' -> thing_inside (Bndr tv' vis) + +-- CgBreakInfo + +hydrateCgBreakInfo :: CgBreakInfo -> IfL ([Maybe (Id, Word16)], Type) +hydrateCgBreakInfo CgBreakInfo{..} = do + bindIfaceTyVars cgb_tyvars $ \_ -> do + result_ty <- tcIfaceType cgb_resty + mbVars <- mapM (traverse (\(if_gbl, offset) -> (,offset) <$> bindIfaceId if_gbl return)) cgb_vars + return (mbVars, result_ty) ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -136,6 +136,7 @@ import GHC.Tc.Solver (simplifyWantedsTcM) import GHC.Tc.Utils.Monad import GHC.Core.Class (classTyCon) import GHC.Unit.Env +import GHC.IfaceToCore -- ----------------------------------------------------------------------------- -- running a statement interactively @@ -562,12 +563,19 @@ bindLocalsAtBreakpoint hsc_env apStack_fhv (Just BreakInfo{..}) = do breaks = getModBreaks hmi info = expectJust "bindLocalsAtBreakpoint2" $ IntMap.lookup breakInfo_number (modBreaks_breakInfo breaks) - mbVars = cgb_vars info - result_ty = cgb_resty info occs = modBreaks_vars breaks ! breakInfo_number span = modBreaks_locs breaks ! breakInfo_number decl = intercalate "." $ modBreaks_decls breaks ! breakInfo_number + -- Rehydrate to understand the breakpoint info relative to the current environment. + -- This design is critical to preventing leaks (#22530) + (mbVars, result_ty) <- initIfaceLoad hsc_env + $ initIfaceLcl breakInfo_module (text "debugger") NotBoot + $ hydrateCgBreakInfo info + + + let + -- Filter out any unboxed ids by changing them to Nothings; -- we can't bind these at the prompt mbPointers = nullUnboxed <$> mbVars ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -90,6 +90,7 @@ import Data.Either ( partitionEithers ) import GHC.Stg.Syntax import qualified Data.IntSet as IntSet +import GHC.CoreToIface -- ----------------------------------------------------------------------------- -- Generating byte code for a complete module @@ -371,10 +372,8 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs) rhs) this_mod <- moduleName <$> getCurrentModule platform <- profilePlatform <$> getProfile let idOffSets = getVarOffSets platform d p fvs - let breakInfo = CgBreakInfo - { cgb_vars = idOffSets - , cgb_resty = tick_ty - } + ty_vars = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs) + let breakInfo = dehydrateCgBreakInfo ty_vars idOffSets tick_ty newBreakInfo tick_no breakInfo hsc_env <- getHscEnv let cc | Just interp <- hsc_interp hsc_env ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -151,7 +151,7 @@ instance Outputable NameSort where ppr System = text "system" instance NFData Name where - rnf Name{..} = rnf n_sort + rnf Name{..} = rnf n_sort `seq` rnf n_occ `seq` n_uniq `seq` rnf n_loc instance NFData NameSort where rnf (External m) = rnf m ===================================== compiler/GHC/Unit/Module/Graph.hs ===================================== @@ -126,8 +126,8 @@ nodeKeyUnitId (NodeKey_Unit iu) = instUnitInstanceOf iu nodeKeyUnitId (NodeKey_Module mk) = mnkUnitId mk nodeKeyUnitId (NodeKey_Link uid) = uid -data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: ModuleNameWithIsBoot - , mnkUnitId :: UnitId } deriving (Eq, Ord) +data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: !ModuleNameWithIsBoot + , mnkUnitId :: !UnitId } deriving (Eq, Ord) instance Outputable ModNodeKeyWithUid where ppr (ModNodeKeyWithUid mnwib uid) = ppr uid <> colon <> ppr mnwib View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39106ac3493a2c599da0748780ca054a0bf80068...08563ba7e09ec48ffac9dca4a363d61f1187700f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39106ac3493a2c599da0748780ca054a0bf80068...08563ba7e09ec48ffac9dca4a363d61f1187700f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 19:30:10 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Apr 2023 15:30:10 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Wibbles Message-ID: <643463c27461a_3b005593f4f270909339@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: be54e3dc by Simon Peyton Jones at 2023-04-10T20:31:40+01:00 Wibbles - - - - - 18 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/typecheck/should_compile/T13651.stderr - testsuite/tests/typecheck/should_fail/AmbigFDs.stderr - testsuite/tests/typecheck/should_fail/T16512a.stderr - testsuite/tests/typecheck/should_fail/T17139.hs - testsuite/tests/typecheck/should_fail/T17139.stderr - testsuite/tests/typecheck/should_fail/T18851c.stderr - testsuite/tests/typecheck/should_fail/T21530a.stderr - testsuite/tests/typecheck/should_fail/T7696.stderr - testsuite/tests/typecheck/should_fail/T7869.stderr - testsuite/tests/typecheck/should_fail/tcfail122.stderr Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -51,7 +51,7 @@ module GHC.Core.Coercion ( castCoercionKind, castCoercionKind1, castCoercionKind2, mkPrimEqPred, mkReprPrimEqPred, mkPrimEqPredRole, - mkHeteroPrimEqPred, mkHeteroReprPrimEqPred, + mkNomPrimEqPred, -- ** Decomposition instNewTyCon_maybe, @@ -2597,7 +2597,8 @@ mkCoercionType Phantom = \ty1 ty2 -> in TyConApp eqPhantPrimTyCon [ki1, ki2, ty1, ty2] --- | Creates a primitive type equality predicate. +-- | Creates a primitive nominal type equality predicate. +-- t1 ~# t2 -- Invariant: the types are not Coercions mkPrimEqPred :: Type -> Type -> Type mkPrimEqPred ty1 ty2 @@ -2606,22 +2607,9 @@ mkPrimEqPred ty1 ty2 k1 = typeKind ty1 k2 = typeKind ty2 --- | Makes a lifted equality predicate at the given role -mkPrimEqPredRole :: Role -> Type -> Type -> PredType -mkPrimEqPredRole Nominal = mkPrimEqPred -mkPrimEqPredRole Representational = mkReprPrimEqPred -mkPrimEqPredRole Phantom = panic "mkPrimEqPredRole phantom" - --- | Creates a primitive type equality predicate with explicit kinds -mkHeteroPrimEqPred :: Kind -> Kind -> Type -> Type -> Type -mkHeteroPrimEqPred k1 k2 ty1 ty2 = mkTyConApp eqPrimTyCon [k1, k2, ty1, ty2] - --- | Creates a primitive representational type equality predicate --- with explicit kinds -mkHeteroReprPrimEqPred :: Kind -> Kind -> Type -> Type -> Type -mkHeteroReprPrimEqPred k1 k2 ty1 ty2 - = mkTyConApp eqReprPrimTyCon [k1, k2, ty1, ty2] - +-- | Creates a primitive representational type equality predicate. +-- t1 ~R# t2 +-- Invariant: the types are not Coercions mkReprPrimEqPred :: Type -> Type -> Type mkReprPrimEqPred ty1 ty2 = mkTyConApp eqReprPrimTyCon [k1, k2, ty1, ty2] @@ -2629,6 +2617,17 @@ mkReprPrimEqPred ty1 ty2 k1 = typeKind ty1 k2 = typeKind ty2 +-- | Makes a lifted equality predicate at the given role +mkPrimEqPredRole :: Role -> Type -> Type -> PredType +mkPrimEqPredRole Nominal = mkPrimEqPred +mkPrimEqPredRole Representational = mkReprPrimEqPred +mkPrimEqPredRole Phantom = panic "mkPrimEqPredRole phantom" + +-- | Creates a primitive nominal type equality predicate with an explicit +-- (but homogeneous) kind: (~#) k k ty1 ty2 +mkNomPrimEqPred :: Kind -> Type -> Type -> Type +mkNomPrimEqPred k ty1 ty2 = mkTyConApp eqPrimTyCon [k, k, ty1, ty2] + -- | Assuming that two types are the same, ignoring coercions, find -- a nominal coercion between the types. This is useful when optimizing -- transitivity over coercion applications, where splitting two ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -16,7 +16,7 @@ module GHC.Core.Predicate ( getEqPredTys, getEqPredTys_maybe, getEqPredRole, predTypeEqRel, mkPrimEqPred, mkReprPrimEqPred, mkPrimEqPredRole, - mkHeteroPrimEqPred, mkHeteroReprPrimEqPred, + mkNomPrimEqPred, -- Class predicates mkClassPred, isDictTy, typeDeterminesValue, ===================================== compiler/GHC/HsToCore.hs ===================================== @@ -764,7 +764,7 @@ mkUnsafeCoercePrimPair _old_id old_expr unsafe_equality k a b = ( mkTyApps (Var unsafe_equality_proof_id) [k,b,a] , mkTyConApp unsafe_equality_tc [k,b,a] - , mkHeteroPrimEqPred k k a b + , mkNomPrimEqPred k a b ) -- NB: UnsafeRefl :: (b ~# a) -> UnsafeEquality a b, so we have to -- carefully swap the arguments above ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -2921,6 +2921,18 @@ neededEvVars implic@(Implic { ic_given = givens ------------------------------------------------- simplifyDelayedErrors :: Bag DelayedError -> TcS (Bag DelayedError) +-- Simplify any delayed errors: e.g. type and term holes +-- NB: At this point we have finished with all the simple +-- constraints; they are in wc_simple, not in the inert set. +-- So those Wanteds will not rewrite these delayed errors. +-- That's probably no bad thing. +-- +-- However if we have [W] alpha ~ Maybe a, [W] alpha ~ Int +-- and _ : alpha, then we'll /unify/ alpha with the first of +-- the Wanteds we get, and thereby report (_ : Maybe a) or +-- (_ : Int) unpredictably, depending on which we happen to see +-- first. Doesn't matter much; there is a type error anyhow. +-- T17139 is a case in point. simplifyDelayedErrors = mapBagM simpl_err where simpl_err :: DelayedError -> TcS DelayedError @@ -2937,6 +2949,7 @@ simplifyDelayedErrors = mapBagM simpl_err -- code, because we have all the givens already set up simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) = do { ty' <- rewriteType loc ty + ; traceTcS "simpl_hole" (ppr ty $$ ppr ty') ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -253,10 +253,12 @@ can_eq_nc' False rdr_env envs ev eq_rel _ ps_ty1 _ ps_ty2 -- See also Note [No top-level newtypes on RHS of representational equalities] can_eq_nc' True _rdr_env _envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2 | Just can_eq_lhs1 <- canEqLHS_maybe ty1 - = canEqCanLHS ev eq_rel NotSwapped can_eq_lhs1 ps_ty1 ty2 ps_ty2 + = do { traceTcS "can_eq1" (ppr ty1 $$ ppr ty2) + ; canEqCanLHS ev eq_rel NotSwapped can_eq_lhs1 ps_ty1 ty2 ps_ty2 } | Just can_eq_lhs2 <- canEqLHS_maybe ty2 - = canEqCanLHS ev eq_rel IsSwapped can_eq_lhs2 ps_ty2 ty1 ps_ty1 + = do { traceTcS "can_eq2" (ppr ty1 $$ ppr ty2) + ; canEqCanLHS ev eq_rel IsSwapped can_eq_lhs2 ps_ty2 ty1 ps_ty1 } -- If the type is TyConApp tc1 args1, then args1 really can't be less -- than tyConArity tc1. It could be *more* than tyConArity, but then we @@ -1414,7 +1416,7 @@ canEqCanLHS ev eq_rel swapped lhs1 ps_xi1 xi2 ps_xi2 = canEqCanLHSHomo ev eq_rel swapped lhs1 ps_xi1 xi2 ps_xi2 | otherwise - = canEqCanLHSHetero ev eq_rel swapped lhs1 k1 xi2 k2 + = canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 k1 xi2 ps_xi2 k2 where k1 = canEqLHSKind lhs1 @@ -1450,23 +1452,37 @@ But this sent solver in an infinite loop (see #19415). -} canEqCanLHSHetero :: CtEvidence -- :: (xi1 :: ki1) ~ (xi2 :: ki2) + -- (or reversed if SwapFlag=IsSwapped) -> EqRel -> SwapFlag - -> CanEqLHS -- xi1 + -> CanEqLHS -> TcType -- xi1 -> TcKind -- ki1 - -> TcType -- xi2 + -> TcType -> TcType -- xi2 -> TcKind -- ki2 -> TcS (StopOrContinue Ct) -canEqCanLHSHetero ev eq_rel swapped lhs1 ki1 xi2 ki2 - -- See Note [Equalities with incompatible kinds] - -- See Note [Kind Equality Orientation] - -- NB: preserve left-to-right orientation!! - -- See Note [Fundeps with instances, and equality orientation] - -- wrinkle (W2) in GHC.Tc.Solver.Interact - = do { (kind_ev, kind_co) <- mk_kind_eq -- :: ki1 ~N ki2 - - ; let -- kind_co :: (ki1 :: *) ~N (ki2 :: *) (whether swapped or not) - lhs_redn = mkReflRedn role xi1 - rhs_redn = mkGReflRightRedn role xi2 (mkSymCo kind_co) +canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 +-- See Note [Equalities with incompatible kinds] +-- See Note [Kind Equality Orientation] + +-- NB: preserve left-to-right orientation!! See wrinkle (W2) in +-- Note [Fundeps with instances, and equality orientation] in GHC.Tc.Solver.Interact +-- NotSwapped: +-- ev :: (lhs1:ki1) ~r# (xi2:ki2) +-- kind_co :: k11 ~# ki2 -- Same orientiation as ev +-- type_ev :: lhs1 ~r# (xi2 |> sym kind_co) +-- Swapped +-- ev :: (xi2:ki2) ~r# (lhs1:ki1) +-- kind_co :: ki2 ~# ki1 -- Same orientiation as ev +-- type_ev :: (xi2 |> kind_co) ~r# lhs1 + + = do { (kind_co, start_again) <- mk_kind_eq -- :: ki1 ~N ki2 + ; if start_again -- Successful unification, have another go + then startAgainWith (mkNonCanonical ev) + else + do { let lhs_redn = mkReflRedn role ps_xi1 + rhs_redn = mkGReflRightRedn role xi2 mb_sym_kind_co + mb_sym_kind_co = case swapped of + NotSwapped -> mkSymCo kind_co + IsSwapped -> kind_co -- See Note [Equalities with incompatible kinds], Wrinkle (1) -- This will be ignored in rewriteEqEvidence if the work item is a Given @@ -1476,38 +1492,36 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ki1 xi2 ki2 (ppr kind_co <+> dcolon <+> sep [ ppr ki1, text "~#", ppr ki2 ]) ; type_ev <- rewriteEqEvidence rewriters ev swapped lhs_redn rhs_redn - ; emitWorkNC [type_ev] -- delay the type equality until after we've finished - -- the kind equality, which may unlock things - -- See Note [Equalities with incompatible kinds] + ; let new_xi2 = mkCastTy ps_xi2 mb_sym_kind_co + ; canEqCanLHSHomo type_ev eq_rel swapped lhs1 ps_xi1 new_xi2 new_xi2 }} - ; solveNonCanonicalEquality kind_ev NomEq ki1 ki2 } where - mk_kind_eq :: TcS (CtEvidence, CoercionN) + mk_kind_eq :: TcS (CoercionN, Bool) + -- Returned kind_co has kind (k1 ~ k2) if NotSwapped, (k2 ~ k1) if Swapped + -- Returned Bool = True if unifications happened, so we should retry mk_kind_eq = case ev of CtGiven { ctev_evar = evar } - -> do { let kind_co = maybe_sym $ mkKindCo (mkCoVarCo evar) -- :: k1 ~ k2 - ; kind_ev <- newGivenEvVar kind_loc (kind_pty, evCoercion kind_co) - ; return (kind_ev, ctEvCoercion kind_ev) } - - CtWanted { ctev_rewriters = rewriters } - -> newWantedEq kind_loc rewriters Nominal ki1 ki2 - - xi1 = canEqLHSType lhs1 - loc = ctev_loc ev - role = eqRelRole eq_rel - kind_loc = mkKindLoc xi1 xi2 loc - kind_pty = mkHeteroPrimEqPred liftedTypeKind liftedTypeKind ki1 ki2 - - maybe_sym = case swapped of - IsSwapped -> mkSymCo -- if the input is swapped, then we - -- will have k2 ~ k1, so flip it to k1 ~ k2 - NotSwapped -> id + -> do { let kind_co = mkKindCo (mkCoVarCo evar) + pred_ty = unSwap swapped (mkNomPrimEqPred liftedTypeKind) ki1 ki2 + kind_loc = mkKindLoc xi1 xi2 (ctev_loc ev) + ; kind_ev <- newGivenEvVar kind_loc (pred_ty, evCoercion kind_co) + ; emitWorkNC [kind_ev] + ; return (ctEvCoercion kind_ev, False) } + + CtWanted {} + -> do { (kind_co, unified) <- unifyWanteds ev Nominal $ \uenv -> + let uenv' = updUEnvLoc uenv (mkKindLoc xi1 xi2) + in unSwap swapped (uType uenv') ki1 ki2 + ; return (kind_co, not (null unified)) } + + xi1 = canEqLHSType lhs1 + role = eqRelRole eq_rel -canEqCanLHSHomo :: CtEvidence +canEqCanLHSHomo :: CtEvidence -- lhs ~ rhs + -- or, if swapped: rhs ~ lhs -> EqRel -> SwapFlag - -> CanEqLHS -- lhs (or, if swapped, rhs) - -> TcType -- pretty lhs - -> TcType -> TcType -- rhs, pretty rhs + -> CanEqLHS -> TcType -- lhs, pretty lhs + -> TcType -> TcType -- rhs, pretty rhs -> TcS (StopOrContinue Ct) -- Guaranteed that typeKind lhs == typeKind rhs canEqCanLHSHomo ev eq_rel swapped lhs1 ps_xi1 xi2 ps_xi2 ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -1988,7 +1988,7 @@ unifyFunDeps ev role do_unifications fvs = tyCoVarsOfType (ctEvPred ev) unifyWanteds :: CtEvidence -> Role - -> (UnifyEnv -> TcM a) + -> (UnifyEnv -> TcM a) -- Some calls to uType -> TcS (a, [TcTyVar]) -- Return coercions witnessing the equality of the two types, -- emitting new work equalities where necessary to achieve that ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -205,7 +205,7 @@ module GHC.Tc.Utils.TcType ( --------------------------------- -- argument visibility - tcTyConVisibilities, isNextTyConArgVisible, isNextArgVisible + tyConVisibilities, isNextTyConArgVisible, isNextArgVisible ) where @@ -2309,8 +2309,8 @@ Reason: the back end falls over with panic "primRepHint:VoidRep"; -- | For every arg a tycon can take, the returned list says True if the argument -- is taken visibly, and False otherwise. Ends with an infinite tail of Trues to -- allow for oversaturation. -tcTyConVisibilities :: TyCon -> [Bool] -tcTyConVisibilities tc = tc_binder_viss ++ tc_return_kind_viss ++ repeat True +tyConVisibilities :: TyCon -> [Bool] +tyConVisibilities tc = tc_binder_viss ++ tc_return_kind_viss ++ repeat True where tc_binder_viss = map isVisibleTyConBinder (tyConBinders tc) tc_return_kind_viss = map isVisiblePiTyBinder (fst $ tcSplitPiTys (tyConResKind tc)) @@ -2318,7 +2318,7 @@ tcTyConVisibilities tc = tc_binder_viss ++ tc_return_kind_viss ++ repeat True -- | If the tycon is applied to the types, is the next argument visible? isNextTyConArgVisible :: TyCon -> [Type] -> Bool isNextTyConArgVisible tc tys - = tcTyConVisibilities tc `getNth` length tys + = tyConVisibilities tc `getNth` length tys -- | Should this type be applied to a visible argument? -- E.g. (s t): is `t` a visible argument of `s`? ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1922,8 +1922,9 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 | tc1 == tc2, equalLength tys1 tys2 , isInjectiveTyCon tc1 role -- don't look under newtypes at Rep equality = assertPpr (isGenerativeTyCon tc1 role) (ppr tc1) $ - do { cos <- zipWith4M u_tc_arg (tyConBinders tc1) - (tyConRoleListX role tc1) + do { traceTc "go-tycon" (ppr tc1 $$ ppr tys1 $$ ppr tys2 $$ ppr (take 10 (tyConRoleListX role tc1))) + ; cos <- zipWith4M u_tc_arg (tyConVisibilities tc1) -- Infinite + (tyConRoleListX role tc1) -- Infinite tys1 tys2 ; return $ mkTyConAppCo role tc1 cos } @@ -1965,10 +1966,11 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 ------------------ - u_tc_arg tc_bndr role ty1 ty2 - = uType env_arg ty1 ty2 + u_tc_arg is_vis role ty1 ty2 + = do { traceTc "u_tc_arg" (ppr role $$ ppr ty1 $$ ppr ty2) + ; uType env_arg ty1 ty2 } where - env_arg = env { u_loc = adjustCtLocTyConBinder tc_bndr (u_loc env) + env_arg = env { u_loc = adjustCtLoc is_vis False (u_loc env) , u_role = role } ------------------ ===================================== testsuite/tests/typecheck/should_compile/T13651.stderr ===================================== @@ -1,6 +1,6 @@ T13651.hs:12:8: error: [GHC-25897] - • Could not deduce ‘cs ~ Bar (Foo h) (Foo s)’ + • Could not deduce ‘cr ~ Bar h (Foo r)’ from the context: (F cr cu ~ Bar h (Bar r u), F cu cs ~ Bar (Foo h) (Bar u s)) bound by the type signature for: @@ -8,7 +8,7 @@ T13651.hs:12:8: error: [GHC-25897] (F cr cu ~ Bar h (Bar r u), F cu cs ~ Bar (Foo h) (Bar u s)) => Bar h (Bar r u) -> Bar (Foo h) (Bar u s) -> Foo (cr -> cs) at T13651.hs:(12,8)-(14,65) - ‘cs’ is a rigid type variable bound by + ‘cr’ is a rigid type variable bound by the type signature for: foo :: forall cr cu h r u cs s. (F cr cu ~ Bar h (Bar r u), F cu cs ~ Bar (Foo h) (Bar u s)) => ===================================== testsuite/tests/typecheck/should_fail/AmbigFDs.stderr ===================================== @@ -1,20 +1,20 @@ AmbigFDs.hs:10:8: error: [GHC-25897] - • Couldn't match type ‘b1’ with ‘b2’ + • Couldn't match type ‘b2’ with ‘b1’ arising from a functional dependency between constraints: - ‘C a b2’ + ‘C a b1’ arising from a type ambiguity check for the type signature for ‘foo’ at AmbigFDs.hs:10:8-35 - ‘C a b1’ + ‘C a b2’ arising from the type signature for: foo :: forall a b1 b2. (C a b1, C a b2) => a -> Int at AmbigFDs.hs:10:8-35 - ‘b1’ is a rigid type variable bound by + ‘b2’ is a rigid type variable bound by the type signature for: foo :: forall a b1 b2. (C a b1, C a b2) => a -> Int at AmbigFDs.hs:10:8-35 - ‘b2’ is a rigid type variable bound by + ‘b1’ is a rigid type variable bound by the type signature for: foo :: forall a b1 b2. (C a b1, C a b2) => a -> Int at AmbigFDs.hs:10:8-35 ===================================== testsuite/tests/typecheck/should_fail/T16512a.stderr ===================================== @@ -1,20 +1,18 @@ T16512a.hs:41:25: error: [GHC-25897] - • Couldn't match type ‘as’ with ‘a : as’ + • Couldn't match type ‘b’ with ‘a -> b’ Expected: AST (ListVariadic (a : as) b) Actual: AST (ListVariadic as (a -> b)) - ‘as’ is a rigid type variable bound by - a pattern with constructor: - AnApplication :: forall (as :: [*]) b. - AST (ListVariadic as b) -> ASTs as -> AnApplication b, - in a case alternative - at T16512a.hs:40:9-26 + ‘b’ is a rigid type variable bound by + the type signature for: + unapply :: forall b. AST b -> AnApplication b + at T16512a.hs:37:1-35 • In the first argument of ‘AnApplication’, namely ‘g’ In the expression: AnApplication g (a `ConsAST` as) In a case alternative: AnApplication g as -> AnApplication g (a `ConsAST` as) • Relevant bindings include - as :: ASTs as (bound at T16512a.hs:40:25) g :: AST (ListVariadic as (a -> b)) (bound at T16512a.hs:40:23) a :: AST a (bound at T16512a.hs:38:15) f :: AST (a -> b) (bound at T16512a.hs:38:10) + unapply :: AST b -> AnApplication b (bound at T16512a.hs:38:1) ===================================== testsuite/tests/typecheck/should_fail/T17139.hs ===================================== @@ -13,3 +13,46 @@ type family TypeFam f fun where lift :: (a -> b) -> TypeFam f (a -> b) lift f = \x -> _ (f <*> x) + + +{- +x :: alpha +body of lambda :: beta + +[W] TypeFam f (a->b) ~ (alpha -> beta) +--> +[W] (f a -> TypeFam f b) ~ (alpha -> beta) +--> + alpha := f a + beta := TypeFam f b + +(<*>) :: Applicative g => g (p -> q) -> g p -> g q + +f <*> x + +arg1 + (a->b) ~ g0 (p0->q0) + g0 := ((->) a) + (p0 -> q0) ~ b <--------- +arg2 + alpha ~ g0 p0 + g0 ~ f <---------- + p0 := a +res + g0 q0 + +Finish with + [W] f ~ (->) a + [W] b ~ (a -> q0) + --> rewrite b + [W] (a -> q0) ~ a -> ( + +_ :: g0 q0 -> beta + :: (a -> q0) -> TypeFam f b + :: (a -> q0) -> TypeFam ((->) a) (a -> q0) + :: (a -> q0) -> (a->a) -> TypeFam (-> a) q0 + +BUT we would get different error messages if we did + g0 := f +and then encountered [W] g0 ~ ((->) a) +-} \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/T17139.stderr ===================================== @@ -1,8 +1,8 @@ T17139.hs:15:16: error: [GHC-88464] - • Found hole: _ :: (a -> b0) -> f a -> TypeFam f b0 + • Found hole: _ :: (a -> b0) -> (a -> a) -> TypeFam ((->) a) b0 Where: ‘b0’ is an ambiguous type variable - ‘a’, ‘f’ are rigid type variables bound by + ‘a’ is a rigid type variable bound by the type signature for: lift :: forall a b (f :: * -> *). (a -> b) -> TypeFam f (a -> b) at T17139.hs:14:1-38 ===================================== testsuite/tests/typecheck/should_fail/T18851c.stderr ===================================== @@ -2,13 +2,13 @@ T18851c.hs:25:27: error: [GHC-25897] • Could not deduce ‘n2 ~ n1’ arising from reasoning about an injective type family using constraints: - ‘Plus1 n2 ~ n’ - arising from a type equality - VSucc (Plus1 n2) ~ VSucc n at T18851c.hs:25:27-33 ‘Plus1 n1 ~ n’ + arising from a type equality + VSucc (Plus1 n1) ~ VSucc n at T18851c.hs:25:27-33 + ‘Plus1 n2 ~ n’ arising from a pattern with constructor: VSucc :: forall (n :: Nat). V n -> VSucc (Plus1 n), - in an equation for ‘foo’ at T18851c.hs:25:6-12 + in an equation for ‘foo’ at T18851c.hs:25:16-22 from the context: n ~ Plus1 n1 bound by a pattern with constructor: VSucc :: forall (n :: Nat). V n -> VSucc (Plus1 n), ===================================== testsuite/tests/typecheck/should_fail/T21530a.stderr ===================================== @@ -1,6 +1,6 @@ T21530a.hs:14:7: error: [GHC-18872] - • Couldn't match kind ‘Constraint’ with ‘*’ + • Couldn't match kind ‘*’ with ‘Constraint’ When matching types a0 :: * Eq Int :: Constraint ===================================== testsuite/tests/typecheck/should_fail/T7696.stderr ===================================== @@ -1,6 +1,6 @@ T7696.hs:9:6: error: [GHC-18872] - • Couldn't match kind ‘*’ with ‘* -> *’ + • Couldn't match kind ‘* -> *’ with ‘*’ When matching types t0 :: (* -> *) -> * w :: * -> * ===================================== testsuite/tests/typecheck/should_fail/T7869.stderr ===================================== @@ -1,16 +1,18 @@ T7869.hs:3:12: error: [GHC-25897] - • Couldn't match type ‘b1’ with ‘b’ + • Couldn't match type ‘a1’ with ‘a’ Expected: [a1] -> b1 Actual: [a] -> b - ‘b1’ is a rigid type variable bound by + ‘a1’ is a rigid type variable bound by an expression type signature: forall a1 b1. [a1] -> b1 at T7869.hs:3:20-27 - ‘b’ is a rigid type variable bound by + ‘a’ is a rigid type variable bound by the inferred type of f :: [a] -> b at T7869.hs:3:1-27 • In the expression: f x In the expression: (\ x -> f x) :: [a] -> b In an equation for ‘f’: f = (\ x -> f x) :: [a] -> b - • Relevant bindings include f :: [a] -> b (bound at T7869.hs:3:1) + • Relevant bindings include + x :: [a1] (bound at T7869.hs:3:7) + f :: [a] -> b (bound at T7869.hs:3:1) ===================================== testsuite/tests/typecheck/should_fail/tcfail122.stderr ===================================== @@ -1,6 +1,6 @@ tcfail122.hs:9:9: error: [GHC-18872] - • Couldn't match kind ‘*’ with ‘* -> *’ + • Couldn't match kind ‘* -> *’ with ‘*’ When matching types c0 :: (* -> *) -> * a :: * -> * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be54e3dc369608143af483809271017749da6d14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be54e3dc369608143af483809271017749da6d14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 10 22:43:35 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 10 Apr 2023 18:43:35 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] More wibbles Message-ID: <643491171ade5_3b0055973d03a0912845@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: c7ebcaba by Simon Peyton Jones at 2023-04-10T23:45:05+01:00 More wibbles - - - - - 11 changed files: - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Interact.hs - libraries/base/GHC/Bits.hs - testsuite/tests/impredicative/icfp20-fail.stderr - testsuite/tests/indexed-types/should_fail/T4179.stderr - testsuite/tests/indexed-types/should_fail/T4254b.hs - − testsuite/tests/indexed-types/should_fail/T4254b.stderr - testsuite/tests/indexed-types/should_fail/T9662.stderr - testsuite/tests/indexed-types/should_fail/all.T - testsuite/tests/partial-sigs/should_fail/T14584a.stderr Changes: ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -16,6 +16,7 @@ import GHC.Tc.Types.Constraint import GHC.Tc.Types.Origin import GHC.Tc.Solver.InertSet import GHC.Tc.Solver.Monad +import GHC.Tc.Solver.Types import GHC.Builtin.Names ( coercibleTyConKey, heqTyConKey, eqTyConKey ) @@ -31,6 +32,7 @@ import GHC.Types.SrcLoc import GHC.Types.Var.Env import GHC.Types.Unique( hasKey ) +import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Misc @@ -69,24 +71,33 @@ doTopReactDict inerts work_item@(CDictCan { cc_ev = ev, cc_class = cls ; addSolvedDict what ev cls xis ; chooseInstance work_item lkup_res } _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies with - -- the instance environment - do { improved <- doTopFundepImprovement work_item - ; if improved - then startAgainWith work_item - else tryLastResortProhibitedSuperclass inerts work_item } } + -- We didn't solve it; so try functional dependencies + tryFunDeps work_item } where dict_loc = ctEvLoc ev - doTopReactDict _ w = pprPanic "doTopReactDict" (ppr w) --- | As a last resort, we TEMPORARILY allow a prohibited superclass solve, +tryFunDeps :: Ct -> TcS (StopOrContinue Ct) +-- Try functional dependencies +-- We do local improvement, then try top level; and we do all this last +-- See Note [Do fundeps last] +tryFunDeps work_item + = do { improved <- doLocalFunDepImprovement work_item + ; if improved then startAgainWith work_item else + + do { improved <- doTopFunDepImprovement work_item + ; if improved then startAgainWith work_item else + + do { inerts <- getTcSInerts + ; tryLastResortProhibitedSuperclass inerts work_item } } } + +tryLastResortProhibitedSuperclass :: InertSet -> Ct -> TcS (StopOrContinue Ct) +-- ^ As a last resort, we TEMPORARILY allow a prohibited superclass solve, -- emitting a loud warning when doing so: we might be creating non-terminating -- evidence (as we are in T22912 for example). -- -- See Note [Migrating away from loopy superclass solving] in GHC.Tc.TyCl.Instance. -tryLastResortProhibitedSuperclass :: InertSet -> Ct -> TcS (StopOrContinue Ct) tryLastResortProhibitedSuperclass inerts work_item@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs = xis }) | let loc_w = ctEvLoc ev_w @@ -681,7 +692,7 @@ This Note describes a delicate interaction that constrains the orientation of equalities. This one is about fundeps, but the /exact/ same thing arises for type-family injectivity constraints: see Note [Improvement orientation]. -doTopFundepImprovement compares the constraint with all the instance +doTopFunDepImprovement compares the constraint with all the instance declarations, to see if we can produce any equalities. E.g class C2 a b | a -> b instance C Int Bool @@ -695,7 +706,7 @@ There is a nasty corner in #19415 which led to the typechecker looping: work_item: dwrk :: C (T @ka (a::ka)) (T @kb0 (b0::kb0)) Char where kb0, b0 are unification vars - ==> {doTopFundepImprovement: compare work_item with instance, + ==> {doTopFunDepImprovement: compare work_item with instance, generate /fresh/ unification variables kfresh0, yfresh0, emit a new Wanted, and add dwrk to inert set} @@ -811,6 +822,29 @@ wanteds. This solution was not complete, and caused a failures while trying to solve for transitive functional dependencies (test case: T21703) -- End of Historical note: Failed Alternative Plan (3) -- +Note [Do fundeps last] +~~~~~~~~~~~~~~~~~~~~~~ +Consider T4254b: + class FD a b | a -> b where { op :: a -> b } + + instance FD Int Bool + + foo :: forall a b. (a~Int,FD a b) => a -> Bool + foo = op + +From the ambiguity check on the type signature we get + [G] FD Int b + [W] FD Int beta +Interacting these gives beta:=b; then we start again and solve without +trying fundeps between the new [W] FD Int b and the top-level instance. +If we did, we'd generate [W] b ~ Bool, which fails. + +From the definition `foo = op` we get + [G] FD Int b + [W] FD Int Bool +We solve this from the top level instance before even trying fundeps. +If we did try fundeps, we'd generate [W] b ~ Bool, which fails. + Note [Weird fundeps] ~~~~~~~~~~~~~~~~~~~~ Consider class Het a b | a -> b where @@ -833,13 +867,60 @@ as the fundeps. #7875 is a case in point. -} -doTopFundepImprovement :: Ct -> TcS Bool +doLocalFunDepImprovement :: Ct -> TcS Bool +-- Add wanted constraints from type-class functional dependencies. +doLocalFunDepImprovement (CDictCan { cc_ev = work_ev, cc_class = cls }) + = do { inerts <- getInertCans + ; foldlM add_fds False (findDictsByClass (inert_dicts inerts) cls) } + -- No need to check flavour; fundeps work between + -- any pair of constraints, regardless of flavour + -- Importantly we don't throw workitem back in the + -- worklist because this can cause loops (see #5236) + where + work_pred = ctEvPred work_ev + work_loc = ctEvLoc work_ev + + add_fds :: Bool -> Ct -> TcS Bool + add_fds so_far inert_ct + | isGiven work_ev && isGiven inert_ev + -- Do not create FDs from Given/Given interactions: See Note [No Given/Given fundeps] + = return so_far + | otherwise + = do { traceTcS "doLocalFunDepImprovement" (vcat + [ ppr work_ev + , pprCtLoc work_loc, ppr (isGivenLoc work_loc) + , pprCtLoc inert_loc, ppr (isGivenLoc inert_loc) + , pprCtLoc derived_loc, ppr (isGivenLoc derived_loc) ]) + + ; unifs <- emitFunDepWanteds work_ev $ + improveFromAnother (derived_loc, inert_rewriters) + inert_pred work_pred + -- We don't really rewrite tys2, see below + -- _rewritten_tys2, so that's ok + ; return (so_far || unifs) + } + where + inert_ev = ctEvidence inert_ct + inert_pred = ctEvPred inert_ev + inert_loc = ctEvLoc inert_ev + inert_rewriters = ctRewriters inert_ct + derived_loc = work_loc { ctl_depth = ctl_depth work_loc `maxSubGoalDepth` + ctl_depth inert_loc + , ctl_origin = FunDepOrigin1 work_pred + (ctLocOrigin work_loc) + (ctLocSpan work_loc) + inert_pred + (ctLocOrigin inert_loc) + (ctLocSpan inert_loc) } + +doLocalFunDepImprovement work_item = pprPanic "doLocalFunDepImprovement" (ppr work_item) + +doTopFunDepImprovement :: Ct -> TcS Bool -- Try to functional-dependency improvement between the constraint -- and the top-level instance declarations -- See Note [Fundeps with instances, and equality orientation] -- See also Note [Weird fundeps] -doTopFundepImprovement work_item@(CDictCan { cc_ev = ev, cc_class = cls - , cc_tyargs = xis }) +doTopFunDepImprovement work_item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = xis }) = do { traceTcS "try_fundeps" (ppr work_item) ; instEnvs <- getInstEnvs ; let fundep_eqns = improveFromInstEnv instEnvs mk_ct_loc cls xis @@ -857,5 +938,4 @@ doTopFundepImprovement work_item@(CDictCan { cc_ev = ev, cc_class = cls inst_pred inst_loc } , emptyRewriterSet ) -doTopFundepImprovement work_item = pprPanic "doTopFundepImprovement" (ppr work_item) - +doTopFunDepImprovement work_item = pprPanic "doTopFunDepImprovement" (ppr work_item) ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -1489,11 +1489,12 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 rewriters = rewriterSetFromCo kind_co ; traceTcS "Hetero equality gives rise to kind equality" - (ppr kind_co <+> dcolon <+> sep [ ppr ki1, text "~#", ppr ki2 ]) + (ppr swapped $$ + ppr kind_co <+> dcolon <+> sep [ ppr ki1, text "~#", ppr ki2 ]) ; type_ev <- rewriteEqEvidence rewriters ev swapped lhs_redn rhs_redn ; let new_xi2 = mkCastTy ps_xi2 mb_sym_kind_co - ; canEqCanLHSHomo type_ev eq_rel swapped lhs1 ps_xi1 new_xi2 new_xi2 }} + ; canEqCanLHSHomo type_ev eq_rel NotSwapped lhs1 ps_xi1 new_xi2 new_xi2 }} where mk_kind_eq :: TcS (CoercionN, Bool) ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -11,7 +11,6 @@ import GHC.Tc.Solver.Canonical import GHC.Tc.Solver.Dict import GHC.Tc.Errors.Types import GHC.Tc.Utils.TcType -import GHC.Tc.Instance.FunDeps import GHC.Tc.Instance.Class ( safeOverlap ) import GHC.Tc.Types.Evidence import GHC.Tc.Types @@ -22,7 +21,6 @@ import GHC.Tc.Solver.InertSet import GHC.Tc.Solver.Monad import GHC.Core.InstEnv ( Coherence(..) ) -import GHC.Core.Class import GHC.Core.Predicate import GHC.Core.Coercion @@ -1028,10 +1026,7 @@ interactDict inerts ct_w@(CDictCan { cc_ev = ev_w, cc_class = cls, cc_tyargs = t = interactGivenIP inerts ct_w | otherwise - = do { unif_happened <- addFunDepWork inerts ev_w cls - ; if unif_happened - then startAgainWith ct_w - else continueWith ct_w } + = continueWith ct_w interactDict _ wi = pprPanic "interactDict" (ppr wi) @@ -1136,50 +1131,6 @@ shortCutSolver dflags ev_w ev_i Nothing -> Fresh <$> newWantedNC loc (ctEvRewriters ev_w) pty | otherwise = mzero -addFunDepWork :: InertCans -> CtEvidence -> Class -> TcS Bool --- Add wanted constraints from type-class functional dependencies. -addFunDepWork inerts work_ev cls - = foldlM add_fds False (findDictsByClass (inert_dicts inerts) cls) - -- No need to check flavour; fundeps work between - -- any pair of constraints, regardless of flavour - -- Importantly we don't throw workitem back in the - -- worklist because this can cause loops (see #5236) - where - work_pred = ctEvPred work_ev - work_loc = ctEvLoc work_ev - - add_fds :: Bool -> Ct -> TcS Bool - add_fds so_far inert_ct - | isGiven work_ev && isGiven inert_ev - -- Do not create FDs from Given/Given interactions: See Note [No Given/Given fundeps] - = return so_far - | otherwise - = do { traceTcS "addFunDepWork" (vcat - [ ppr work_ev - , pprCtLoc work_loc, ppr (isGivenLoc work_loc) - , pprCtLoc inert_loc, ppr (isGivenLoc inert_loc) - , pprCtLoc derived_loc, ppr (isGivenLoc derived_loc) ]) - - ; unifs <- emitFunDepWanteds work_ev $ - improveFromAnother (derived_loc, inert_rewriters) - inert_pred work_pred - -- We don't really rewrite tys2, see below - -- _rewritten_tys2, so that's ok - ; return (so_far || unifs) - } - where - inert_ev = ctEvidence inert_ct - inert_pred = ctEvPred inert_ev - inert_loc = ctEvLoc inert_ev - inert_rewriters = ctRewriters inert_ct - derived_loc = work_loc { ctl_depth = ctl_depth work_loc `maxSubGoalDepth` - ctl_depth inert_loc - , ctl_origin = FunDepOrigin1 work_pred - (ctLocOrigin work_loc) - (ctLocSpan work_loc) - inert_pred - (ctLocOrigin inert_loc) - (ctLocSpan inert_loc) } {- ********************************************************************** ===================================== libraries/base/GHC/Bits.hs ===================================== @@ -722,3 +722,4 @@ own to enable constant folding; for example 'shift': -- > ; True -> Just (W16# (narrow16Word# (int2Word# b1))) -- > } -- > } +x=y \ No newline at end of file ===================================== testsuite/tests/impredicative/icfp20-fail.stderr ===================================== @@ -1,7 +1,6 @@ icfp20-fail.hs:20:10: error: [GHC-83865] - • Couldn't match type: forall a. a -> a - with: b -> b + • Couldn't match type ‘SId’ with ‘b -> b’ Expected: SId -> b -> b Actual: SId -> SId • In the expression: id ===================================== testsuite/tests/indexed-types/should_fail/T4179.stderr ===================================== @@ -1,13 +1,13 @@ T4179.hs:26:16: error: [GHC-83865] - • Couldn't match type: A3 (x (A2 (FCon x) -> A3 (FCon x))) - with: A3 (FCon x) + • Couldn't match type: A2 (x (A2 (FCon x) -> A3 (FCon x))) + with: A2 (FCon x) Expected: x (A2 (FCon x) -> A3 (FCon x)) -> A2 (FCon x) -> A3 (FCon x) Actual: x (A2 (FCon x) -> A3 (FCon x)) -> A2 (x (A2 (FCon x) -> A3 (FCon x))) -> A3 (x (A2 (FCon x) -> A3 (FCon x))) - NB: ‘A3’ is a non-injective type family + NB: ‘A2’ is a non-injective type family • In the first argument of ‘foldDoC’, namely ‘op’ In the expression: foldDoC op In an equation for ‘fCon’: fCon = foldDoC op ===================================== testsuite/tests/indexed-types/should_fail/T4254b.hs ===================================== @@ -11,3 +11,22 @@ fails :: forall a b. (a~Int,FD a b) => a -> Bool fails = op -- Could fail: no proof that b~Bool -- But can also succeed; it's not a *wanted* constraint + +{- Interestingly, the ambiguity check for the type sig succeeds: + +[G] FD Int b +[W] FD Int beta + +We get [W] beta~b; we unify immediately, and then solve. +All before we interact the [W] FD Int beta with the +top-level instances (which would give rise to [W] beta~Bool). + +One the other hand, from `fails = op` we get + +[G] FD Int b +[W] FD Int Bool + +Interacting those two gives [W] b~Bool; bu this doesn't +happen becase we now solve first. + +-} \ No newline at end of file ===================================== testsuite/tests/indexed-types/should_fail/T4254b.stderr deleted ===================================== @@ -1,20 +0,0 @@ - -T4254b.hs:10:10: error: [GHC-25897] - • Couldn't match type ‘b’ with ‘Bool’ - arising from a functional dependency between constraints: - ‘FD Int Bool’ - arising from a type ambiguity check for - the type signature for ‘fails’ at T4254b.hs:10:10-48 - ‘FD Int b’ - arising from the type signature for: - fails :: forall a b. - (a ~ Int, FD a b) => - a -> Bool at T4254b.hs:10:10-48 - ‘b’ is a rigid type variable bound by - the type signature for: - fails :: forall a b. (a ~ Int, FD a b) => a -> Bool - at T4254b.hs:10:10-48 - • In the ambiguity check for ‘fails’ - To defer the ambiguity check to use sites, enable AllowAmbiguousTypes - In the type signature: - fails :: forall a b. (a ~ Int, FD a b) => a -> Bool ===================================== testsuite/tests/indexed-types/should_fail/T9662.stderr ===================================== @@ -1,13 +1,13 @@ T9662.hs:49:8: error: [GHC-25897] - • Couldn't match type ‘n’ with ‘Int’ + • Couldn't match type ‘k’ with ‘Int’ Expected: Exp (((sh :. k) :. m) :. n) -> Exp (((sh :. m) :. n) :. k) Actual: Exp (Tuple (((Atom a0 :. Atom Int) :. Atom Int) :. Atom Int)) -> Exp (Plain (((Unlifted (Atom a0) :. Exp Int) :. Exp Int) :. Exp Int)) - ‘n’ is a rigid type variable bound by + ‘k’ is a rigid type variable bound by the type signature for: test :: forall sh k m n. Shape (((sh :. k) :. m) :. n) -> Shape (((sh :. m) :. n) :. k) ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -58,7 +58,7 @@ test('T3330a', normal, compile_fail, ['']) test('T3330b', normal, compile_fail, ['']) test('T3330c', normal, compile_fail, ['']) test('T4179', normal, compile_fail, ['']) -test('T4254b', normal, compile_fail, ['']) +test('T4254b', normal, compile, ['']) test('T2239', normal, compile, ['']) test('T3440', expect_broken(19974), compile_fail, ['']) test('T4485', normal, compile_fail, ['']) ===================================== testsuite/tests/partial-sigs/should_fail/T14584a.stderr ===================================== @@ -32,3 +32,11 @@ T14584a.hs:15:17: warning: [GHC-25897] [-Wdeferred-type-errors (in -Wdefault)] In the expression: id @m In an equation for ‘h’: h = id @m • Relevant bindings include h :: m -> m (bound at T14584a.hs:15:9) + +T14584a.hs:16:8: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] + • Couldn't match expected type ‘()’ with actual type ‘m -> m’ + • Probable cause: ‘h’ is applied to too few arguments + In the expression: h + In the expression: let h = id @m in h + In an equation for ‘g’: g = let h = id @m in h + • Relevant bindings include h :: m -> m (bound at T14584a.hs:15:9) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7ebcabad4bb86aad3ffafb38d43b3d2c449ff4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7ebcabad4bb86aad3ffafb38d43b3d2c449ff4d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 04:53:40 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 00:53:40 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 64 commits: Fix an assertion check in addToEqualCtList Message-ID: <6434e7d49fc77_3b00559cddfd00920999@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 7d8cc70a by Simon Peyton Jones at 2023-04-11T10:21:53+05:30 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 (cherry picked from commit 3d55d8ab51ece43c51055c43c9e7aba77cce46c0) - - - - - c85909e5 by Simon Peyton Jones at 2023-04-11T10:21:53+05:30 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. (cherry picked from commit e193e53790dd5886feea3cf4c9c17625d188291b) - - - - - 400bfd26 by Andreas Klebinger at 2023-04-11T10:21:53+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 7dea433c by Simon Peyton Jones at 2023-04-11T10:21:53+05:30 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 (cherry picked from commit 317f45c154f6fe25d50ef2f3febcc5883ff1b1ca) - - - - - 52f583df by Matthew Pickering at 2023-04-11T10:21:53+05:30 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s (cherry picked from commit a960ca817d6ad0109ea6edda50da3902cc538e86) - - - - - a37b41c9 by Matthew Pickering at 2023-04-11T10:21:53+05:30 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. (cherry picked from commit 734847108420cf826a807c30ad54651659cf3a08) - - - - - 7da8d3ea by Matthew Pickering at 2023-04-11T10:21:54+05:30 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes (cherry picked from commit 8c0ea25fb4a27d4729aabf73f4c00b912bb0c58d) - - - - - 0c61c58e by Sebastian Graf at 2023-04-11T10:21:54+05:30 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite (cherry picked from commit e3fff7512bbf989386faaa1dccafdad1deabde84) - - - - - ea6c5315 by Oleg Grenrus at 2023-04-11T10:22:21+05:30 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general (cherry picked from commit 1b812b6973a25cb1962e2fc543d2c4ed3cf31f3c) - - - - - 327b4673 by Viktor Dukhovni at 2023-04-11T10:22:21+05:30 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 (cherry picked from commit fc02f3bbb5f47f880465e22999ba9794f658d8f6) - - - - - 789a806e by Ryan Scott at 2023-04-11T10:22:21+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - 98457ae7 by Cheng Shao at 2023-04-11T10:22:21+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - 07d474f8 by Ben Gamari at 2023-04-11T10:22:21+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - 72d80d8c by Ben Gamari at 2023-04-11T10:22:21+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - 72bb48a1 by Ben Gamari at 2023-04-11T10:22:21+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - 20b78aac by Ben Gamari at 2023-04-11T10:22:21+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - 3f339ee2 by Zubin Duggal at 2023-04-11T10:22:21+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 69e7be1e by Ben Gamari at 2023-04-11T10:22:21+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - 67e80ed7 by Zubin Duggal at 2023-04-11T10:22:21+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - 2a1c7c41 by Ben Gamari at 2023-04-11T10:22:21+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - 5421ed44 by sheaf at 2023-04-11T10:22:22+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - fafdab44 by Ben Gamari at 2023-04-11T10:22:22+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 7be4a1c1 by Ben Gamari at 2023-04-11T10:22:22+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 205c5262 by Ben Gamari at 2023-04-11T10:22:22+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 6851fe04 by Ben Gamari at 2023-04-11T10:22:22+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 56193005 by Ben Gamari at 2023-04-11T10:22:22+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - d78f512f by Andreas Klebinger at 2023-04-11T10:22:22+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - aeeca576 by Matthew Pickering at 2023-04-11T10:22:22+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - a7e2c2de by Sylvain Henry at 2023-04-11T10:22:22+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - d3991596 by Ben Gamari at 2023-04-11T10:22:22+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - d1347f14 by Matthew Pickering at 2023-04-11T10:22:22+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - 0b2f9008 by Matthew Pickering at 2023-04-11T10:22:22+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - beb0ff49 by Matthew Pickering at 2023-04-11T10:22:22+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - 66e66fbd by Matthew Pickering at 2023-04-11T10:22:22+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - 9cd5570f by Matthew Pickering at 2023-04-11T10:22:22+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 30c05354 by Matthew Pickering at 2023-04-11T10:22:22+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - a16f1939 by Matthew Pickering at 2023-04-11T10:22:22+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - cead3152 by Matthew Pickering at 2023-04-11T10:22:22+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 7a6ebfab by Matthew Pickering at 2023-04-11T10:22:23+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - e060ecc9 by Matthew Pickering at 2023-04-11T10:22:23+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - dba55382 by Matthew Pickering at 2023-04-11T10:22:23+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 4b51cc10 by Matthew Pickering at 2023-04-11T10:22:23+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - dcf8123c by Matthew Pickering at 2023-04-11T10:23:05+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 029422f1 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 1426cbaa by Matthew Pickering at 2023-04-11T10:23:05+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 0f9da1b3 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 71e7d3c3 by Simon Peyton Jones at 2023-04-11T10:23:05+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 7e5d6d22 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 2d758a59 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - f4d7bab4 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - aac790ce by Matthew Pickering at 2023-04-11T10:23:05+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 1455c916 by Matthew Pickering at 2023-04-11T10:23:05+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - de1183aa by Krzysztof Gogolewski at 2023-04-11T10:23:05+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - 08f15f84 by Simon Peyton Jones at 2023-04-11T10:23:05+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - 3e4cb19f by sheaf at 2023-04-11T10:23:06+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - 4ce1b920 by Sylvain Henry at 2023-04-11T10:23:06+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - 086daacb by Sylvain Henry at 2023-04-11T10:23:06+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 50903214 by Sylvain Henry at 2023-04-11T10:23:06+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - 30ff6fdd by Sylvain Henry at 2023-04-11T10:23:06+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 37988c96 by Ben Gamari at 2023-04-11T10:23:06+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - edd3307c by Ben Gamari at 2023-04-11T10:23:06+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - f06fb9b5 by Ben Gamari at 2023-04-11T10:23:06+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - 3b121ba7 by Ben Gamari at 2023-04-11T10:23:06+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 6732aabe by Li-yao Xia at 2023-04-11T10:23:06+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Bind.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08563ba7e09ec48ffac9dca4a363d61f1187700f...6732aabec26243a50ad6c3a9b55addcaa079a3a9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08563ba7e09ec48ffac9dca4a363d61f1187700f...6732aabec26243a50ad6c3a9b55addcaa079a3a9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 04:55:51 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 00:55:51 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 54 commits: Add missing parenthesizeHsType in cvtSigTypeKind Message-ID: <6434e8571ab9d_3b00559cddfd3c92148d@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: e745dd7a by Ryan Scott at 2023-04-11T10:25:20+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - 8c888464 by Cheng Shao at 2023-04-11T10:25:20+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - 710f9c26 by Ben Gamari at 2023-04-11T10:25:20+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - 6ab22d43 by Ben Gamari at 2023-04-11T10:25:20+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - b813498b by Ben Gamari at 2023-04-11T10:25:21+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - ca94c890 by Ben Gamari at 2023-04-11T10:25:21+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - 0f52a00a by Zubin Duggal at 2023-04-11T10:25:21+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 4363dfbb by Ben Gamari at 2023-04-11T10:25:21+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - a3dc6493 by Zubin Duggal at 2023-04-11T10:25:21+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - a48e7d22 by Ben Gamari at 2023-04-11T10:25:21+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - e54ea044 by sheaf at 2023-04-11T10:25:21+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - fc25c7d9 by Ben Gamari at 2023-04-11T10:25:21+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 71e0e737 by Ben Gamari at 2023-04-11T10:25:21+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 96ad9eca by Ben Gamari at 2023-04-11T10:25:21+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 80442dbc by Ben Gamari at 2023-04-11T10:25:21+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 1e81391f by Ben Gamari at 2023-04-11T10:25:21+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - d30eb293 by Andreas Klebinger at 2023-04-11T10:25:21+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - 13f5c21a by Matthew Pickering at 2023-04-11T10:25:21+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - bdeed7ce by Sylvain Henry at 2023-04-11T10:25:21+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - b23d34bc by Ben Gamari at 2023-04-11T10:25:21+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - 1f06ac89 by Matthew Pickering at 2023-04-11T10:25:21+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - 9d3c2637 by Matthew Pickering at 2023-04-11T10:25:21+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - c814672c by Matthew Pickering at 2023-04-11T10:25:21+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - 66910db2 by Matthew Pickering at 2023-04-11T10:25:21+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - b54a606b by Matthew Pickering at 2023-04-11T10:25:22+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 690d4496 by Matthew Pickering at 2023-04-11T10:25:22+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - 3ac79fd5 by Matthew Pickering at 2023-04-11T10:25:22+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - 7cde34db by Matthew Pickering at 2023-04-11T10:25:22+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 64f36e9a by Matthew Pickering at 2023-04-11T10:25:22+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - d8dde0c9 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 5a36d3c7 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 88ec30d7 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 3644ad46 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - ee6c2611 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 76975c78 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 245c0393 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - a1d6453b by Simon Peyton Jones at 2023-04-11T10:25:22+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 67624a36 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 45378246 by Matthew Pickering at 2023-04-11T10:25:22+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - e539b84f by Matthew Pickering at 2023-04-11T10:25:22+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - bdf921ff by Matthew Pickering at 2023-04-11T10:25:22+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 0c776daf by Matthew Pickering at 2023-04-11T10:25:22+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - c266c03f by Krzysztof Gogolewski at 2023-04-11T10:25:23+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - f7bcfb63 by Simon Peyton Jones at 2023-04-11T10:25:23+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - 76f6cbde by sheaf at 2023-04-11T10:25:23+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - b3c26479 by Sylvain Henry at 2023-04-11T10:25:23+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - a305fcc0 by Sylvain Henry at 2023-04-11T10:25:23+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 327eb579 by Sylvain Henry at 2023-04-11T10:25:23+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - fc65f7a2 by Sylvain Henry at 2023-04-11T10:25:23+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 70837db9 by Ben Gamari at 2023-04-11T10:25:23+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - 09207fa3 by Ben Gamari at 2023-04-11T10:25:23+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - 5050bec0 by Ben Gamari at 2023-04-11T10:25:23+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - 642e8667 by Ben Gamari at 2023-04-11T10:25:23+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 738f68e3 by Li-yao Xia at 2023-04-11T10:25:23+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6732aabec26243a50ad6c3a9b55addcaa079a3a9...738f68e3aa5a45d5d374d343f8b43a65779fe558 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6732aabec26243a50ad6c3a9b55addcaa079a3a9...738f68e3aa5a45d5d374d343f8b43a65779fe558 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 05:25:10 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 01:25:10 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 62 commits: Fix unifier bug: failing to decompose over-saturated type family Message-ID: <6434ef36c33ad_3b00559d6904cc9221f@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: fdb6437f by Simon Peyton Jones at 2023-04-11T10:52:18+05:30 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 (cherry picked from commit 317f45c154f6fe25d50ef2f3febcc5883ff1b1ca) - - - - - 8cedbeb4 by Matthew Pickering at 2023-04-11T10:52:18+05:30 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s (cherry picked from commit a960ca817d6ad0109ea6edda50da3902cc538e86) - - - - - f0a2bbfb by Matthew Pickering at 2023-04-11T10:52:18+05:30 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. (cherry picked from commit 734847108420cf826a807c30ad54651659cf3a08) - - - - - 58250d83 by Matthew Pickering at 2023-04-11T10:52:18+05:30 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes (cherry picked from commit 8c0ea25fb4a27d4729aabf73f4c00b912bb0c58d) - - - - - 7d4d5b55 by Sebastian Graf at 2023-04-11T10:52:18+05:30 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite (cherry picked from commit e3fff7512bbf989386faaa1dccafdad1deabde84) - - - - - 76c31152 by Oleg Grenrus at 2023-04-11T10:52:18+05:30 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general (cherry picked from commit 1b812b6973a25cb1962e2fc543d2c4ed3cf31f3c) - - - - - a8eb6148 by Viktor Dukhovni at 2023-04-11T10:52:18+05:30 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 (cherry picked from commit fc02f3bbb5f47f880465e22999ba9794f658d8f6) - - - - - 52661e3d by Ryan Scott at 2023-04-11T10:52:18+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - dc916697 by Cheng Shao at 2023-04-11T10:52:18+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - 1f8747ca by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - b72cb3ac by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - a15b863c by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - 71e7be37 by Ben Gamari at 2023-04-11T10:52:18+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - de3491f7 by Zubin Duggal at 2023-04-11T10:52:19+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 770a9a00 by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - d6a51cd1 by Zubin Duggal at 2023-04-11T10:52:19+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - 4419309d by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - ea9ecc40 by sheaf at 2023-04-11T10:52:19+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - 12b45b4a by Andreas Klebinger at 2023-04-11T10:52:19+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - 4e5fd92b by Matthew Pickering at 2023-04-11T10:52:19+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - 8f819453 by Sylvain Henry at 2023-04-11T10:52:19+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - 82637685 by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - 443d6c99 by Matthew Pickering at 2023-04-11T10:52:19+05:30 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. (cherry picked from commit 32255d055b768d51deb9d1f49681164cf7492011) - - - - - 099476b9 by Matthew Pickering at 2023-04-11T10:52:19+05:30 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 (cherry picked from commit 15bee1239877a4629a245fe457f06e5f96668423) - - - - - e0389248 by Matthew Pickering at 2023-04-11T10:52:19+05:30 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. (cherry picked from commit fec6638e2468c78f136f2363d8b3239a9bfd4f91) - - - - - 03dd5154 by Matthew Pickering at 2023-04-11T10:52:19+05:30 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 (cherry picked from commit 53a6ae7a8f819d1105aa190dc9cce215cdbcc6dc) - - - - - cdc7fe41 by Matthew Pickering at 2023-04-11T10:52:19+05:30 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 (cherry picked from commit 32e264c1a11e6356bb045371b87a3736df19e792) - - - - - 9e1f3001 by Matthew Pickering at 2023-04-11T10:52:19+05:30 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 (cherry picked from commit be9dd9b03479070ba6387c251541f4569392c4bb) - - - - - 91b1b452 by Matthew Pickering at 2023-04-11T10:52:19+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - 0ca0906e by Matthew Pickering at 2023-04-11T10:52:19+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 3a3bad1e by Matthew Pickering at 2023-04-11T10:52:19+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - cd175a13 by Matthew Pickering at 2023-04-11T10:52:19+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 11c5d8a7 by Matthew Pickering at 2023-04-11T10:52:20+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - d5f3868a by Matthew Pickering at 2023-04-11T10:52:20+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 4b21b8b4 by Matthew Pickering at 2023-04-11T10:52:20+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 45549cb5 by Matthew Pickering at 2023-04-11T10:52:20+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - afc2e91d by Matthew Pickering at 2023-04-11T10:52:20+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 69e5e1bf by Matthew Pickering at 2023-04-11T10:52:20+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 8e823996 by Simon Peyton Jones at 2023-04-11T10:52:20+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 8eb86bb1 by Matthew Pickering at 2023-04-11T10:52:20+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 015c36cf by Matthew Pickering at 2023-04-11T10:52:20+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - ecada91d by Matthew Pickering at 2023-04-11T10:52:20+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - 14e02acb by Matthew Pickering at 2023-04-11T10:52:20+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 05da1e5b by Matthew Pickering at 2023-04-11T10:52:20+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - fb88b786 by Krzysztof Gogolewski at 2023-04-11T10:52:20+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - 0f2d9353 by Simon Peyton Jones at 2023-04-11T10:52:20+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - 18735146 by sheaf at 2023-04-11T10:52:20+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - 2755bfb8 by Sylvain Henry at 2023-04-11T10:52:20+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - a670baec by Sylvain Henry at 2023-04-11T10:52:20+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 74caa309 by Sylvain Henry at 2023-04-11T10:52:20+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - 093cacb1 by Sylvain Henry at 2023-04-11T10:52:21+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 4a7b6b09 by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - cec4823c by Ben Gamari at 2023-04-11T10:52:21+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - c288654c by Ben Gamari at 2023-04-11T10:52:21+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - e9eb9f5f by Ben Gamari at 2023-04-11T10:52:21+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - f453a590 by Li-yao Xia at 2023-04-11T10:52:21+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - dba377fe by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 3ee26290 by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 133d4271 by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - cd0ce279 by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 3e4420f2 by Ben Gamari at 2023-04-11T10:52:21+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - ccc435ed by Andreas Klebinger at 2023-04-11T10:54:51+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Eval.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/738f68e3aa5a45d5d374d343f8b43a65779fe558...ccc435edf331aa625e5db3714d0951bd527372dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/738f68e3aa5a45d5d374d343f8b43a65779fe558...ccc435edf331aa625e5db3714d0951bd527372dd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 05:41:51 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 01:41:51 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 5 commits: Add test for T23184 Message-ID: <6434f31f44267_3b00559de06bc09228e3@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: ec4ea457 by Matthew Pickering at 2023-04-11T10:57:41+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - a1f87248 by Matthew Pickering at 2023-04-11T11:00:03+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - cadf80f6 by Ben Gamari at 2023-04-11T11:04:08+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - bf8cec2b by Ben Gamari at 2023-04-11T11:05:19+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - a3ae1e5c by Ben Gamari at 2023-04-11T11:05:29+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - 8 changed files: - compiler/GHC/Core/Opt/Simplify.hs - + rts/ZeroSlop.c - rts/include/Cmm.h - rts/include/rts/storage/ClosureMacros.h - rts/rts.cabal.in - + testsuite/tests/simplCore/should_run/T23184.hs - + testsuite/tests/simplCore/should_run/T23184.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -3557,8 +3557,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ===================================== rts/ZeroSlop.c ===================================== @@ -0,0 +1,27 @@ +/* ---------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2012 + * + * Utilities for zeroing slop callable from Cmm + * + * N.B. If you are in C you should rather using the inlineable utilities + * (e.g. overwritingClosure) defined in ClosureMacros.h. + * + * -------------------------------------------------------------------------- */ + +#include "Rts.h" + +void stg_overwritingClosure (StgClosure *p) +{ + overwritingClosure(p); +} + +void stg_overwritingMutableClosureOfs (StgClosure *p, uint32_t offset) +{ + overwritingMutableClosureOfs(p, offset); +} + +void stg_overwritingClosureSize (StgClosure *p, uint32_t size /* in words */) +{ + overwritingClosureSize(p, size); +} ===================================== rts/include/Cmm.h ===================================== @@ -633,9 +633,9 @@ #define mutArrPtrsCardWords(n) ROUNDUP_BYTES_TO_WDS(mutArrPtrCardUp(n)) #if defined(PROFILING) || defined(DEBUG) -#define OVERWRITING_CLOSURE_SIZE(c, size) foreign "C" overwritingClosureSize(c "ptr", size) -#define OVERWRITING_CLOSURE(c) foreign "C" overwritingClosure(c "ptr") -#define OVERWRITING_CLOSURE_MUTABLE(c, off) foreign "C" overwritingMutableClosureOfs(c "ptr", off) +#define OVERWRITING_CLOSURE_SIZE(c, size) foreign "C" stg_overwritingClosureSize(c "ptr", size) +#define OVERWRITING_CLOSURE(c) foreign "C" stg_overwritingClosure(c "ptr") +#define OVERWRITING_CLOSURE_MUTABLE(c, off) foreign "C" stg_overwritingMutableClosureOfs(c "ptr", off) #else #define OVERWRITING_CLOSURE_SIZE(c, size) /* nothing */ #define OVERWRITING_CLOSURE(c) /* nothing */ @@ -643,7 +643,7 @@ * this whenever profiling is enabled as described in Note [slop on the heap] * in Storage.c. */ #define OVERWRITING_CLOSURE_MUTABLE(c, off) \ - if (TO_W_(RtsFlags_ProfFlags_doHeapProfile(RtsFlags)) != 0) { foreign "C" overwritingMutableClosureOfs(c "ptr", off); } + if (TO_W_(RtsFlags_ProfFlags_doHeapProfile(RtsFlags)) != 0) { foreign "C" stg_overwritingMutableClosureOfs(c "ptr", off); } #endif #define IS_STACK_CLEAN(stack) \ ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -442,11 +442,13 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) memory we're about to zero. Thus, with the THREADED RTS and +RTS -N2 or greater we must not zero - immutable closure's slop. + immutable closure's slop. Similarly, the concurrent GC's mark thread + may race when a mutator during slop-zeroing. Consequently, we also disable + zeroing when the non-moving GC is in use. Hence, an immutable closure's slop is zeroed when either: - - PROFILING && era > 0 (LDV is on) or + - PROFILING && era > 0 (LDV is on) && !nonmoving-gc-enabled or - !THREADED && DEBUG Additionally: @@ -480,16 +482,12 @@ void LDV_recordDead (const StgClosure *c, uint32_t size); RTS_PRIVATE bool isInherentlyUsed ( StgHalfWord closure_type ); #endif -EXTERN_INLINE void -zeroSlop ( - StgClosure *p, - uint32_t offset, /*< offset to start zeroing at, in words */ - uint32_t size, /*< total closure size, in words */ - bool known_mutable /*< is this a closure who's slop we can always zero? */ - ); - -EXTERN_INLINE void -zeroSlop (StgClosure *p, uint32_t offset, uint32_t size, bool known_mutable) +INLINE_HEADER void +zeroSlop (StgClosure *p, + uint32_t offset, /*< offset to start zeroing at, in words */ + uint32_t size, /*< total closure size, in words */ + bool known_mutable /*< is this a closure who's slop we can always zero? */ + ) { // see Note [zeroing slop when overwriting closures], also #8402 @@ -504,7 +502,8 @@ zeroSlop (StgClosure *p, uint32_t offset, uint32_t size, bool known_mutable) const bool can_zero_immutable_slop = // Only if we're running single threaded. - RTS_DEREF(RtsFlags).ParFlags.nCapabilities <= 1; + getNumCapabilities() == 1 + && !RTS_DEREF(RtsFlags).GcFlags.useNonmoving; // see #23170 const bool zero_slop_immutable = want_to_zero_immutable_slop && can_zero_immutable_slop; @@ -537,8 +536,10 @@ zeroSlop (StgClosure *p, uint32_t offset, uint32_t size, bool known_mutable) } } -EXTERN_INLINE void overwritingClosure (StgClosure *p); -EXTERN_INLINE void overwritingClosure (StgClosure *p) +// N.B. the stg_* variants of the utilities below are only for calling from +// Cmm. The INLINE_HEADER functions should be used when in C. +void stg_overwritingClosure (StgClosure *p); +INLINE_HEADER void overwritingClosure (StgClosure *p) { W_ size = closure_sizeW(p); #if defined(PROFILING) @@ -548,15 +549,13 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p) zeroSlop(p, sizeofW(StgThunkHeader), size, /*known_mutable=*/false); } + // Version of 'overwritingClosure' which overwrites only a suffix of a // closure. The offset is expressed in words relative to 'p' and shall // be less than or equal to closure_sizeW(p), and usually at least as // large as the respective thunk header. -EXTERN_INLINE void -overwritingMutableClosureOfs (StgClosure *p, uint32_t offset); - -EXTERN_INLINE void -overwritingMutableClosureOfs (StgClosure *p, uint32_t offset) +void stg_overwritingMutableClosureOfs (StgClosure *p, uint32_t offset); +INLINE_HEADER void overwritingMutableClosureOfs (StgClosure *p, uint32_t offset) { // Since overwritingClosureOfs is only ever called by: // @@ -573,8 +572,8 @@ overwritingMutableClosureOfs (StgClosure *p, uint32_t offset) } // Version of 'overwritingClosure' which takes closure size as argument. -EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size /* in words */); -EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size) +void stg_OverwritingClosureSize (StgClosure *p, uint32_t size /* in words */); +INLINE_HEADER void overwritingClosureSize (StgClosure *p, uint32_t size) { // This function is only called from stg_AP_STACK so we can assume it's not // inherently used. ===================================== rts/rts.cabal.in ===================================== @@ -540,6 +540,7 @@ library TraverseHeapTest.c WSDeque.c Weak.c + ZeroSlop.c eventlog/EventLog.c eventlog/EventLogWriter.c hooks/FlagDefaults.c ===================================== testsuite/tests/simplCore/should_run/T23184.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE BangPatterns #-} +module Main where + +import GHC.Magic + +main :: IO () +main = print $ noinline (\x -> sum $ tardisManual [0..x]) 0 + +tardisManual :: [Int] -> [Int] +tardisManual xs = + let + go [] !acc _ = ([], 0) + go (_:xs) !acc l = + let (xs', _) = go xs acc l + in (l:xs', 0) + (r, l) = go xs True l + in r +{-# INLINE tardisManual #-} ===================================== testsuite/tests/simplCore/should_run/T23184.stdout ===================================== @@ -0,0 +1 @@ +0 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -104,3 +104,4 @@ test('T21575', normal, compile_and_run, ['-O']) test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) +test('T23184', normal, compile_and_run, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ccc435edf331aa625e5db3714d0951bd527372dd...a3ae1e5cce0a15f250ae2bf53232a5e4a573c495 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ccc435edf331aa625e5db3714d0951bd527372dd...a3ae1e5cce0a15f250ae2bf53232a5e4a573c495 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 05:43:12 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 01:43:12 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 35 commits: Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo Message-ID: <6434f370b80a6_3b00559dfd62d492371e@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 1eb4e49c by Matthew Pickering at 2023-04-11T11:12:47+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 50535e25 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 53f7f4f5 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 15c170f7 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 939ce6e9 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 645d9112 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - c28a7b72 by Simon Peyton Jones at 2023-04-11T11:12:47+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - 59d14582 by Matthew Pickering at 2023-04-11T11:12:47+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - 51cc6a05 by Matthew Pickering at 2023-04-11T11:12:48+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - 1fa117fa by Matthew Pickering at 2023-04-11T11:12:48+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - 19b5b2ed by Matthew Pickering at 2023-04-11T11:12:48+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 2b17b50e by Matthew Pickering at 2023-04-11T11:12:48+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 6810fb20 by Krzysztof Gogolewski at 2023-04-11T11:12:48+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - 060dda42 by Simon Peyton Jones at 2023-04-11T11:12:48+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - a9f080b9 by sheaf at 2023-04-11T11:12:48+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - bbc39a35 by Sylvain Henry at 2023-04-11T11:12:48+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - 52d672e9 by Sylvain Henry at 2023-04-11T11:12:48+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - d6773979 by Sylvain Henry at 2023-04-11T11:12:48+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - 1b316ce1 by Sylvain Henry at 2023-04-11T11:12:48+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - b6d3268d by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - abbac8cc by Ben Gamari at 2023-04-11T11:12:48+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - 777250cd by Ben Gamari at 2023-04-11T11:12:48+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - ce7bf1f2 by Ben Gamari at 2023-04-11T11:12:48+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 92a7e4a9 by Li-yao Xia at 2023-04-11T11:12:48+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - b9f9355a by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - b0cda48f by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 87d5c473 by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 42a89585 by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 0103cbb1 by Ben Gamari at 2023-04-11T11:12:48+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - baa34450 by Andreas Klebinger at 2023-04-11T11:12:48+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 2a0b637b by Matthew Pickering at 2023-04-11T11:12:49+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - 0be66e84 by Matthew Pickering at 2023-04-11T11:12:49+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - c1c8ece4 by Ben Gamari at 2023-04-11T11:12:49+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - ea3a1503 by Ben Gamari at 2023-04-11T11:12:49+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - b81dba4b by Ben Gamari at 2023-04-11T11:12:49+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - 30 changed files: - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Match.hs-boot - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/PatSyn.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/Language/Haskell/Syntax/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3ae1e5cce0a15f250ae2bf53232a5e4a573c495...b81dba4bd54c6ec7c1ab73937a9b8c20ed6a3d4f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a3ae1e5cce0a15f250ae2bf53232a5e4a573c495...b81dba4bd54c6ec7c1ab73937a9b8c20ed6a3d4f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 06:07:16 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 02:07:16 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 2 commits: Take more care with unlifted bindings in the specialiser Message-ID: <6434f914c2d2a_3b00559e7e4ffc92426a@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: ab2b06cd by Simon Peyton Jones at 2023-04-11T11:19:24+05:30 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise (cherry picked from commit 7192ef91c855e1fae6997f75cfde76aafd0b4bcf) - - - - - d7699449 by Simon Peyton Jones at 2023-04-11T11:36:16+05:30 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 (cherry picked from commit 6206cb9287f3f6e70c669660a646a65274870d2b) - - - - - 8 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/Specialise.hs - + testsuite/tests/simplCore/should_compile/T22662.hs - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_run/T22998.hs - + testsuite/tests/simplCore/should_run/T22998.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -368,13 +368,69 @@ a Coercion, (sym c). Note [Core letrec invariant] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The right hand sides of all top-level and recursive @let at s -/must/ be of lifted type (see "Type#type_classification" for -the meaning of /lifted/ vs. /unlifted/). +The Core letrec invariant: -There is one exception to this rule, top-level @let at s are -allowed to bind primitive string literals: see -Note [Core top-level string literals]. + The right hand sides of all + /top-level/ or /recursive/ + bindings must be of lifted type + + There is one exception to this rule, top-level @let at s are + allowed to bind primitive string literals: see + Note [Core top-level string literals]. + +See "Type#type_classification" in GHC.Core.Type +for the meaning of "lifted" vs. "unlifted"). + +For the non-top-level, non-recursive case see Note [Core let-can-float invariant]. + +Note [Core let-can-float invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The let-can-float invariant: + + The right hand side of a /non-top-level/, /non-recursive/ binding + may be of unlifted type, but only if + the expression is ok-for-speculation + or the 'Let' is for a join point. + + (For top-level or recursive lets see Note [Core letrec invariant].) + +This means that the let can be floated around +without difficulty. For example, this is OK: + + y::Int# = x +# 1# + +But this is not, as it may affect termination if the +expression is floated out: + + y::Int# = fac 4# + +In this situation you should use @case@ rather than a @let at . The function +'GHC.Core.Utils.needsCaseBinding' can help you determine which to generate, or +alternatively use 'GHC.Core.Make.mkCoreLet' rather than this constructor directly, +which will generate a @case@ if necessary + +The let-can-float invariant is initially enforced by mkCoreLet in GHC.Core.Make. + +For discussion of some implications of the let-can-float invariant primops see +Note [Checking versus non-checking primops] in GHC.Builtin.PrimOps. + +Historical Note [The let/app invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Before 2022 GHC used the "let/app invariant", which applied the let-can-float rules +to the argument of an application, as well as to the RHS of a let. This made some +kind of sense, because 'let' can always be encoded as application: + let x=rhs in b = (\x.b) rhs + +But the let/app invariant got in the way of RULES; see #19313. For example + up :: Int# -> Int# + {-# RULES "up/down" forall x. up (down x) = x #-} +The LHS of this rule doesn't satisfy the let/app invariant. + +Indeed RULES is a big reason that GHC doesn't use ANF, where the argument of an +application is always a variable or a constant. To allow RULES to work nicely +we need to allow lots of things in the arguments of a call. + +TL;DR: we relaxed the let/app invariant to become the let-can-float invariant. Note [Core top-level string literals] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -414,6 +470,8 @@ parts of the compilation pipeline. Note [Core top-level string literals]. Core-to-core passes may introduce new top-level string literals. + See GHC.Core.Utils.exprIsTopLevelBindable, and exprIsTickedString + * In STG, top-level string literals are explicitly represented in the syntax tree. @@ -421,14 +479,9 @@ parts of the compilation pipeline. in the object file, the content of the exported literal is given a label with the _bytes suffix. -Note [Core let/app invariant] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The let/app invariant - the right hand side of a non-recursive 'Let', and - the argument of an 'App', - /may/ be of unlifted type, but only if - the expression is ok-for-speculation - or the 'Let' is for a join point. +Note [NON-BOTTOM-DICTS invariant] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is a global invariant (not checkable by Lint) that This means that the let can be floated around without difficulty. For example, this is OK: @@ -448,8 +501,24 @@ which will generate a @case@ if necessary The let/app invariant is initially enforced by mkCoreLet and mkCoreApp in GHC.Core.Make. -For discussion of some implications of the let/app invariant primops see -Note [Checking versus non-checking primops] in GHC.Builtin.PrimOps. +* A superclass selection from some other dictionary. This is harder to guarantee: + see Note [Recursive superclasses] and Note [Solving superclass constraints] + in GHC.Tc.TyCl.Instance. + +A bad Core-to-Core pass could invalidate this reasoning, but that's too bad. +It's still an invariant of Core programs generated by GHC from Haskell, and +Core-to-Core passes maintain it. + +Why is it useful to know that dictionaries are non-bottom? + +1. It justifies the use of `-XDictsStrict`; + see `GHC.Core.Types.Demand.strictifyDictDmd` + +2. It means that (eq_sel d) is ok-for-speculation and thus + case (eq_sel d) of _ -> blah + can be discarded by the Simplifier. See these Notes: + Note [exprOkForSpeculation and type classes] in GHC.Core.Utils + Note[Speculative evaluation] in GHC.CoreToStg.Prep Note [Case expression invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Opt/FloatIn.hs ===================================== @@ -34,9 +34,12 @@ import GHC.Types.Var import GHC.Types.Var.Set import GHC.Utils.Misc -import GHC.Utils.Panic import GHC.Utils.Panic.Plain +import GHC.Utils.Outputable + +import Data.List ( mapAccumL ) + {- Top-level interface function, @floatInwards at . Note that we do not actually float any bindings downwards from the top-level. @@ -123,7 +126,7 @@ the closure for a is not built. ************************************************************************ -} -type FreeVarSet = DIdSet +type FreeVarSet = DVarSet type BoundVarSet = DIdSet data FloatInBind = FB BoundVarSet FreeVarSet FloatBind @@ -131,11 +134,17 @@ data FloatInBind = FB BoundVarSet FreeVarSet FloatBind -- of recursive bindings, the set doesn't include the bound -- variables. -type FloatInBinds = [FloatInBind] - -- In reverse dependency order (innermost binder first) +type FloatInBinds = [FloatInBind] -- In normal dependency order + -- (outermost binder first) +type RevFloatInBinds = [FloatInBind] -- In reverse dependency order + -- (innermost binder first) + +instance Outputable FloatInBind where + ppr (FB bvs fvs _) = text "FB" <> braces (sep [ text "bndrs =" <+> ppr bvs + , text "fvs =" <+> ppr fvs ]) fiExpr :: Platform - -> FloatInBinds -- Binds we're trying to drop + -> RevFloatInBinds -- Binds we're trying to drop -- as far "inwards" as possible -> CoreExprWithFVs -- Input expr -> CoreExpr -- Result @@ -146,13 +155,12 @@ fiExpr _ to_drop (_, AnnType ty) = assert (null to_drop) $ Type ty fiExpr _ to_drop (_, AnnVar v) = wrapFloats to_drop (Var v) fiExpr _ to_drop (_, AnnCoercion co) = wrapFloats to_drop (Coercion co) fiExpr platform to_drop (_, AnnCast expr (co_ann, co)) - = wrapFloats (drop_here ++ co_drop) $ + = wrapFloats drop_here $ Cast (fiExpr platform e_drop expr) co where - [drop_here, e_drop, co_drop] - = sepBindsByDropPoint platform False - [freeVarsOf expr, freeVarsOfAnn co_ann] - to_drop + (drop_here, [e_drop]) + = sepBindsByDropPoint platform False to_drop + (freeVarsOfAnn co_ann) [freeVarsOf expr] {- Applications: we do float inside applications, mainly because we @@ -161,7 +169,7 @@ pull out any silly ones. -} fiExpr platform to_drop ann_expr@(_,AnnApp {}) - = wrapFloats drop_here $ wrapFloats extra_drop $ + = wrapFloats drop_here $ mkTicks ticks $ mkApps (fiExpr platform fun_drop ann_fun) (zipWithEqual "fiExpr" (fiExpr platform) arg_drops ann_args) @@ -171,19 +179,18 @@ fiExpr platform to_drop ann_expr@(_,AnnApp {}) (ann_fun, ann_args, ticks) = collectAnnArgsTicks tickishFloatable ann_expr fun_ty = exprType (deAnnotate ann_fun) fun_fvs = freeVarsOf ann_fun - arg_fvs = map freeVarsOf ann_args - (drop_here : extra_drop : fun_drop : arg_drops) - = sepBindsByDropPoint platform False - (extra_fvs : fun_fvs : arg_fvs) - to_drop + (drop_here, fun_drop : arg_drops) + = sepBindsByDropPoint platform False to_drop + here_fvs (fun_fvs : arg_fvs) + -- Shortcut behaviour: if to_drop is empty, -- sepBindsByDropPoint returns a suitable bunch of empty -- lists without evaluating extra_fvs, and hence without -- peering into each argument - (_, extra_fvs) = foldl' add_arg (fun_ty, extra_fvs0) ann_args - extra_fvs0 = case ann_fun of + ((_,here_fvs), arg_fvs) = mapAccumL add_arg (fun_ty, here_fvs0) ann_args + here_fvs0 = case ann_fun of (_, AnnVar _) -> fun_fvs _ -> emptyDVarSet -- Don't float the binding for f into f x y z; see Note [Join points] @@ -191,15 +198,13 @@ fiExpr platform to_drop ann_expr@(_,AnnApp {}) -- join point, floating it in isn't especially harmful but it's -- useless since the simplifier will immediately float it back out.) - add_arg :: (Type,FreeVarSet) -> CoreExprWithFVs -> (Type,FreeVarSet) - add_arg (fun_ty, extra_fvs) (_, AnnType ty) - = (piResultTy fun_ty ty, extra_fvs) - - add_arg (fun_ty, extra_fvs) (arg_fvs, arg) - | noFloatIntoArg arg arg_ty - = (res_ty, extra_fvs `unionDVarSet` arg_fvs) - | otherwise - = (res_ty, extra_fvs) + add_arg :: (Type,FreeVarSet) -> CoreExprWithFVs -> ((Type,FreeVarSet),FreeVarSet) + add_arg (fun_ty, here_fvs) (arg_fvs, AnnType ty) + = ((piResultTy fun_ty ty, here_fvs), arg_fvs) + -- We can't float into some arguments, so put them into the here_fvs + add_arg (fun_ty, here_fvs) (arg_fvs, arg) + | noFloatIntoArg arg arg_ty = ((res_ty,here_fvs `unionDVarSet` arg_fvs), emptyDVarSet) + | otherwise = ((res_ty,here_fvs), arg_fvs) where (_, arg_ty, res_ty) = splitFunTy fun_ty @@ -283,7 +288,6 @@ it's non-recursive, so we float only into non-recursive join points.) Urk! if all are tyvars, and we don't float in, we may miss an opportunity to float inside a nested case branch - Note [Floating coercions] ~~~~~~~~~~~~~~~~~~~~~~~~~ We could, in principle, have a coercion binding like @@ -303,6 +307,36 @@ of the types of all the drop points involved. If any of the floaters bind a coercion variable mentioned in any of the types, that binder must be dropped right away. +Note [Shadowing and name capture] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose we have + let x = y+1 in + case p of + (y:ys) -> ...x... + [] -> blah +It is obviously bogus for FloatIn to transform to + case p of + (y:ys) -> ...(let x = y+1 in x)... + [] -> blah +because the y is captured. This doesn't happen much, because shadowing is +rare, but it did happen in #22662. + +One solution would be to clone as we go. But a simpler one is this: + + at a binding site (like that for (y:ys) above), abandon float-in for + any floating bindings that mention the binders (y, ys in this case) + +We achieve that by calling sepBindsByDropPoint with the binders in +the "used-here" set: + +* In fiExpr (AnnLam ...). For the body there is no need to delete + the lambda-binders from the body_fvs, because any bindings that + mention these binders will be dropped here anyway. + +* In fiExpr (AnnCase ...). Remember to include the case_bndr in the + binders. Again, no need to delete the alt binders from the rhs + free vars, beause any bindings mentioning them will be dropped + here unconditionally. -} fiExpr platform to_drop lam@(_, AnnLam _ _) @@ -311,10 +345,17 @@ fiExpr platform to_drop lam@(_, AnnLam _ _) = wrapFloats to_drop (mkLams bndrs (fiExpr platform [] body)) | otherwise -- Float inside - = mkLams bndrs (fiExpr platform to_drop body) + = wrapFloats drop_here $ + mkLams bndrs (fiExpr platform body_drop body) where (bndrs, body) = collectAnnBndrs lam + body_fvs = freeVarsOf body + + -- Why sepBindsByDropPoint? Because of potential capture + -- See Note [Shadowing and name capture] + (drop_here, [body_drop]) = sepBindsByDropPoint platform False to_drop + (mkDVarSet bndrs) [body_fvs] {- We don't float lets inwards past an SCC. @@ -454,16 +495,16 @@ fiExpr platform to_drop (_, AnnCase scrut case_bndr _ [AnnAlt con alt_bndrs rhs] = wrapFloats shared_binds $ fiExpr platform (case_float : rhs_binds) rhs where - case_float = FB (mkDVarSet (case_bndr : alt_bndrs)) scrut_fvs + case_float = FB all_bndrs scrut_fvs (FloatCase scrut' case_bndr con alt_bndrs) scrut' = fiExpr platform scrut_binds scrut - rhs_fvs = freeVarsOf rhs `delDVarSetList` (case_bndr : alt_bndrs) - scrut_fvs = freeVarsOf scrut + rhs_fvs = freeVarsOf rhs -- No need to delete alt_bndrs + scrut_fvs = freeVarsOf scrut -- See Note [Shadowing and name capture] + all_bndrs = mkDVarSet alt_bndrs `extendDVarSet` case_bndr - [shared_binds, scrut_binds, rhs_binds] - = sepBindsByDropPoint platform False - [scrut_fvs, rhs_fvs] - to_drop + (shared_binds, [scrut_binds, rhs_binds]) + = sepBindsByDropPoint platform False to_drop + all_bndrs [scrut_fvs, rhs_fvs] fiExpr platform to_drop (_, AnnCase scrut case_bndr ty alts) = wrapFloats drop_here1 $ @@ -473,39 +514,43 @@ fiExpr platform to_drop (_, AnnCase scrut case_bndr ty alts) -- use zipWithEqual, we should have length alts_drops_s = length alts where -- Float into the scrut and alts-considered-together just like App - [drop_here1, scrut_drops, alts_drops] - = sepBindsByDropPoint platform False - [scrut_fvs, all_alts_fvs] - to_drop + (drop_here1, [scrut_drops, alts_drops]) + = sepBindsByDropPoint platform False to_drop + all_alt_bndrs [scrut_fvs, all_alt_fvs] + -- all_alt_bndrs: see Note [Shadowing and name capture] -- Float into the alts with the is_case flag set - (drop_here2 : alts_drops_s) - | [ _ ] <- alts = [] : [alts_drops] - | otherwise = sepBindsByDropPoint platform True alts_fvs alts_drops - - scrut_fvs = freeVarsOf scrut - alts_fvs = map alt_fvs alts - all_alts_fvs = unionDVarSets alts_fvs - alt_fvs (AnnAlt _con args rhs) - = foldl' delDVarSet (freeVarsOf rhs) (case_bndr:args) - -- Delete case_bndr and args from free vars of rhs - -- to get free vars of alt + (drop_here2, alts_drops_s) + = sepBindsByDropPoint platform True alts_drops emptyDVarSet alts_fvs + + scrut_fvs = freeVarsOf scrut + + all_alt_bndrs = foldr (unionDVarSet . ann_alt_bndrs) (unitDVarSet case_bndr) alts + ann_alt_bndrs (AnnAlt _ bndrs _) = mkDVarSet bndrs + + alts_fvs :: [DVarSet] + alts_fvs = [freeVarsOf rhs | AnnAlt _ _ rhs <- alts] + -- No need to delete binders + -- See Note [Shadowing and name capture] + + all_alt_fvs :: DVarSet + all_alt_fvs = foldr unionDVarSet (unitDVarSet case_bndr) alts_fvs fi_alt to_drop (AnnAlt con args rhs) = Alt con args (fiExpr platform to_drop rhs) ------------------ fiBind :: Platform - -> FloatInBinds -- Binds we're trying to drop - -- as far "inwards" as possible - -> CoreBindWithFVs -- Input binding - -> DVarSet -- Free in scope of binding - -> ( FloatInBinds -- Land these before - , FloatInBind -- The binding itself - , FloatInBinds) -- Land these after + -> RevFloatInBinds -- Binds we're trying to drop + -- as far "inwards" as possible + -> CoreBindWithFVs -- Input binding + -> DVarSet -- Free in scope of binding + -> ( RevFloatInBinds -- Land these before + , FloatInBind -- The binding itself + , RevFloatInBinds) -- Land these after fiBind platform to_drop (AnnNonRec id ann_rhs@(rhs_fvs, rhs)) body_fvs - = ( extra_binds ++ shared_binds -- Land these before - -- See Note [extra_fvs (1)] and Note [extra_fvs (2)] + = ( shared_binds -- Land these before + -- See Note [extra_fvs (1)] and Note [extra_fvs (2)] , FB (unitDVarSet id) rhs_fvs' -- The new binding itself (FloatLet (NonRec id rhs')) , body_binds ) -- Land these after @@ -523,10 +568,9 @@ fiBind platform to_drop (AnnNonRec id ann_rhs@(rhs_fvs, rhs)) body_fvs -- We *can't* float into ok-for-speculation unlifted RHSs -- But do float into join points - [shared_binds, extra_binds, rhs_binds, body_binds] - = sepBindsByDropPoint platform False - [extra_fvs, rhs_fvs, body_fvs2] - to_drop + (shared_binds, [rhs_binds, body_binds]) + = sepBindsByDropPoint platform False to_drop + extra_fvs [rhs_fvs, body_fvs2] -- Push rhs_binds into the right hand side of the binding rhs' = fiRhs platform rhs_binds id ann_rhs @@ -534,7 +578,7 @@ fiBind platform to_drop (AnnNonRec id ann_rhs@(rhs_fvs, rhs)) body_fvs -- Don't forget the rule_fvs; the binding mentions them! fiBind platform to_drop (AnnRec bindings) body_fvs - = ( extra_binds ++ shared_binds + = ( shared_binds , FB (mkDVarSet ids) rhs_fvs' (FloatLet (Rec (fi_bind rhss_binds bindings))) , body_binds ) @@ -548,17 +592,16 @@ fiBind platform to_drop (AnnRec bindings) body_fvs unionDVarSets [ rhs_fvs | (bndr, (rhs_fvs, rhs)) <- bindings , noFloatIntoRhs Recursive bndr rhs ] - (shared_binds:extra_binds:body_binds:rhss_binds) - = sepBindsByDropPoint platform False - (extra_fvs:body_fvs:rhss_fvs) - to_drop + (shared_binds, body_binds:rhss_binds) + = sepBindsByDropPoint platform False to_drop + extra_fvs (body_fvs:rhss_fvs) rhs_fvs' = unionDVarSets rhss_fvs `unionDVarSet` unionDVarSets (map floatedBindsFVs rhss_binds) `unionDVarSet` rule_fvs -- Don't forget the rule variables! -- Push rhs_binds into the right hand side of the binding - fi_bind :: [FloatInBinds] -- one per "drop pt" conjured w/ fvs_of_rhss + fi_bind :: [RevFloatInBinds] -- One per "drop pt" conjured w/ fvs_of_rhss -> [(Id, CoreExprWithFVs)] -> [(Id, CoreExpr)] @@ -567,7 +610,7 @@ fiBind platform to_drop (AnnRec bindings) body_fvs | ((binder, rhs), to_drop) <- zipEqual "fi_bind" pairs to_drops ] ------------------ -fiRhs :: Platform -> FloatInBinds -> CoreBndr -> CoreExprWithFVs -> CoreExpr +fiRhs :: Platform -> RevFloatInBinds -> CoreBndr -> CoreExprWithFVs -> CoreExpr fiRhs platform to_drop bndr rhs | Just join_arity <- isJoinId_maybe bndr , let (bndrs, body) = collectNAnnBndrs join_arity rhs @@ -667,68 +710,84 @@ point. We have to maintain the order on these drop-point-related lists. -} --- pprFIB :: FloatInBinds -> SDoc +-- pprFIB :: RevFloatInBinds -> SDoc -- pprFIB fibs = text "FIB:" <+> ppr [b | FB _ _ b <- fibs] sepBindsByDropPoint :: Platform - -> Bool -- True <=> is case expression - -> [FreeVarSet] -- One set of FVs per drop point - -- Always at least two long! - -> FloatInBinds -- Candidate floaters - -> [FloatInBinds] -- FIRST one is bindings which must not be floated - -- inside any drop point; the rest correspond - -- one-to-one with the input list of FV sets + -> Bool -- True <=> is case expression + -> RevFloatInBinds -- Candidate floaters + -> FreeVarSet -- here_fvs: if these vars are free in a binding, + -- don't float that binding inside any drop point + -> [FreeVarSet] -- fork_fvs: one set of FVs per drop point + -> ( RevFloatInBinds -- Bindings which must not be floated inside + , [RevFloatInBinds] ) -- Corresponds 1-1 with the input list of FV sets -- Every input floater is returned somewhere in the result; -- none are dropped, not even ones which don't seem to be -- free in *any* of the drop-point fvs. Why? Because, for example, -- a binding (let x = E in B) might have a specialised version of -- x (say x') stored inside x, but x' isn't free in E or B. +-- +-- The here_fvs argument is used for two things: +-- * Avoid shadowing bugs: see Note [Shadowing and name capture] +-- * Drop some of the bindings at the top, e.g. of an application type DropBox = (FreeVarSet, FloatInBinds) -sepBindsByDropPoint platform is_case drop_pts floaters +dropBoxFloats :: DropBox -> RevFloatInBinds +dropBoxFloats (_, floats) = reverse floats + +usedInDropBox :: DIdSet -> DropBox -> Bool +usedInDropBox bndrs (db_fvs, _) = db_fvs `intersectsDVarSet` bndrs + +initDropBox :: DVarSet -> DropBox +initDropBox fvs = (fvs, []) + +sepBindsByDropPoint platform is_case floaters here_fvs fork_fvs | null floaters -- Shortcut common case - = [] : [[] | _ <- drop_pts] + = ([], [[] | _ <- fork_fvs]) | otherwise - = assert (drop_pts `lengthAtLeast` 2) $ - go floaters (map (\fvs -> (fvs, [])) (emptyDVarSet : drop_pts)) + = go floaters (initDropBox here_fvs) (map initDropBox fork_fvs) where - n_alts = length drop_pts + n_alts = length fork_fvs - go :: FloatInBinds -> [DropBox] -> [FloatInBinds] - -- The *first* one in the argument list is the drop_here set - -- The FloatInBinds in the lists are in the reverse of - -- the normal FloatInBinds order; that is, they are the right way round! + go :: RevFloatInBinds -> DropBox -> [DropBox] + -> (RevFloatInBinds, [RevFloatInBinds]) + -- The *first* one in the pair is the drop_here set - go [] drop_boxes = map (reverse . snd) drop_boxes + go [] here_box fork_boxes + = (dropBoxFloats here_box, map dropBoxFloats fork_boxes) - go (bind_w_fvs@(FB bndrs bind_fvs bind) : binds) drop_boxes@(here_box : fork_boxes) - = go binds new_boxes + go (bind_w_fvs@(FB bndrs bind_fvs bind) : binds) here_box fork_boxes + | drop_here = go binds (insert here_box) fork_boxes + | otherwise = go binds here_box new_fork_boxes where -- "here" means the group of bindings dropped at the top of the fork - (used_here : used_in_flags) = [ fvs `intersectsDVarSet` bndrs - | (fvs, _) <- drop_boxes] + used_here = bndrs `usedInDropBox` here_box + used_in_flags = case fork_boxes of + [] -> [] + [_] -> [True] -- Push all bindings into a single branch + -- No need to look at its free vars + _ -> map (bndrs `usedInDropBox`) fork_boxes + -- Short-cut for the singleton case; + -- used for lambdas and singleton cases drop_here = used_here || cant_push n_used_alts = count id used_in_flags -- returns number of Trues in list. cant_push - | is_case = n_used_alts == n_alts -- Used in all, don't push - -- Remember n_alts > 1 + | is_case = (n_alts > 1 && n_used_alts == n_alts) + -- Used in all, muliple branches, don't push || (n_used_alts > 1 && not (floatIsDupable platform bind)) -- floatIsDupable: see Note [Duplicating floats] | otherwise = floatIsCase bind || n_used_alts > 1 -- floatIsCase: see Note [Floating primops] - new_boxes | drop_here = (insert here_box : fork_boxes) - | otherwise = (here_box : new_fork_boxes) - new_fork_boxes = zipWithEqual "FloatIn.sepBinds" insert_maybe fork_boxes used_in_flags @@ -738,8 +797,6 @@ sepBindsByDropPoint platform is_case drop_pts floaters insert_maybe box True = insert box insert_maybe box False = box - go _ _ = panic "sepBindsByDropPoint/go" - {- Note [Duplicating floats] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -756,14 +813,14 @@ If the thing is used in all RHSs there is nothing gained, so we don't duplicate then. -} -floatedBindsFVs :: FloatInBinds -> FreeVarSet +floatedBindsFVs :: RevFloatInBinds -> FreeVarSet floatedBindsFVs binds = mapUnionDVarSet fbFVs binds fbFVs :: FloatInBind -> DVarSet fbFVs (FB _ fvs _) = fvs -wrapFloats :: FloatInBinds -> CoreExpr -> CoreExpr --- Remember FloatInBinds is in *reverse* dependency order +wrapFloats :: RevFloatInBinds -> CoreExpr -> CoreExpr +-- Remember RevFloatInBinds is in *reverse* dependency order wrapFloats [] e = e wrapFloats (FB _ _ fl : bs) e = wrapFloats bs (wrapFloat fl e) ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -29,7 +29,8 @@ import qualified GHC.Core.Subst as Core import GHC.Core.Unfold.Make import GHC.Core import GHC.Core.Rules -import GHC.Core.Utils ( exprIsTrivial, getIdFromTrivialExpr_maybe +import GHC.Core.Utils ( exprIsTrivial, exprIsTopLevelBindable + , getIdFromTrivialExpr_maybe , mkCast, exprType ) import GHC.Core.FVs import GHC.Core.TyCo.Rep (TyCoBinder (..)) @@ -1321,7 +1322,10 @@ specBind rhs_env (NonRec fn rhs) body_uds = [mkDB $ NonRec b r | (b,r) <- pairs] ++ bagToList dump_dbs - ; if float_all then + can_float_this_one = exprIsTopLevelBindable rhs (idType fn) + -- exprIsTopLevelBindable: see Note [Care with unlifted bindings] + + ; if float_all && can_float_this_one then -- Rather than discard the calls mentioning the bound variables -- we float this (dictionary) binding along with the others return ([], free_uds `snocDictBinds` final_binds) @@ -1659,6 +1663,28 @@ even in the case that @x = False@! Instead, we add a dummy 'Void#' argument to the specialisation '$sfInt' ($sfInt :: Void# -> Array# Int) in order to preserve laziness. +Note [Care with unlifted bindings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider (#22998) + f x = let x::ByteArray# = + n::Natural = NB x + in wombat @192827 (n |> co) +where + co :: Natural ~ KnownNat 192827 + wombat :: forall (n:Nat). KnownNat n => blah + +Left to itself, the specialiser would float the bindings for `x` and `n` to top +level, so we can specialise `wombat`. But we can't have a top-level ByteArray# +(see Note [Core letrec invariant] in GHC.Core). Boo. + +This is pretty exotic, so we take a simple way out: in specBind (the NonRec +case) do not float the binding itself unless it satisfies exprIsTopLevelBindable. +This is conservative: maybe the RHS of `x` has a free var that would stop it +floating to top level anyway; but that is hard to spot (since we don't know what +the non-top-level in-scope binders are) and rare (since the binding must satisfy +Note [Core let-can-float invariant] in GHC.Core). + + Note [Specialising Calls] ~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have a function with a complicated type: ===================================== testsuite/tests/simplCore/should_compile/T22662.hs ===================================== @@ -0,0 +1,6 @@ +module T22662 where + +import Data.Set + +foo x = sequence_ [ f y | y <- x ] + where f _ = return (fromList [0]) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -397,3 +397,4 @@ test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddu test('T22491', normal, compile, ['-O2']) test('T22623', normal, multimod_compile, ['T22623', '-O -v0']) +test('T22662', normal, compile, ['']) ===================================== testsuite/tests/simplCore/should_run/T22998.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE DataKinds #-} +module Main where + +import Data.Proxy (Proxy(Proxy)) +import GHC.TypeLits (natVal) + +main :: IO () +main = print x + where + x = natVal @18446744073709551616 Proxy + natVal @18446744073709551616 Proxy ===================================== testsuite/tests/simplCore/should_run/T22998.stdout ===================================== @@ -0,0 +1 @@ +36893488147419103232 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -105,3 +105,4 @@ test('T21575b', [], multimod_compile_and_run, ['T21575b', '-O']) test('T20836', normal, compile_and_run, ['-O0']) # Should not time out; See #20836 test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) test('T23184', normal, compile_and_run, ['-O']) +test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b81dba4bd54c6ec7c1ab73937a9b8c20ed6a3d4f...d769944930469441f18b60affa866e2533a027fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b81dba4bd54c6ec7c1ab73937a9b8c20ed6a3d4f...d769944930469441f18b60affa866e2533a027fd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 06:07:54 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 02:07:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/js-stgrhsclosure Message-ID: <6434f93aa568b_3b00559e81d5c8924810@gitlab.mail> Josh Meredith pushed new branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/js-stgrhsclosure You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 06:24:08 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 02:24:08 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] Fix void-arg-adding mechanism for worker/wrapper Message-ID: <6434fd081c127_3b00559ea9cc40927317@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: aad62f1f by Simon Peyton Jones at 2023-04-11T11:50:34+05:30 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. (cherry picked from commit 964284fcab6e27fe2fa5c279ea008551cbc15dbb) - - - - - 7 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Utils.hs - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T18328.stderr - + testsuite/tests/simplCore/should_compile/T22725.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -45,6 +45,7 @@ import GHC.Unit.Module.ModGuts import GHC.Types.Literal ( litIsLifted ) import GHC.Types.Id +import GHC.Types.Id.Make ( voidArgId, voidPrimId ) import GHC.Types.Var.Env import GHC.Types.Var.Set import GHC.Types.Name @@ -1741,24 +1742,13 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) -- return () -- And build the results - ; let spec_body_ty = exprType spec_body - (spec_lam_args1, spec_sig, spec_arity1, spec_join_arity1) - = calcSpecInfo fn call_pat extra_bndrs - -- Annotate the variables with the strictness information from - -- the function (see Note [Strictness information in worker binders]) - add_void_arg = needsVoidWorkerArg fn arg_bndrs spec_lam_args1 - (spec_lam_args, spec_call_args, spec_arity, spec_join_arity) - | add_void_arg - -- See Note [SpecConst needs to add void args first] - , (spec_lam_args, spec_call_args, _) <- addVoidWorkerArg spec_lam_args1 [] - -- needsVoidWorkerArg: usual w/w hack to avoid generating - -- a spec_rhs of unlifted type and no args. - , !spec_arity <- spec_arity1 + 1 - , !spec_join_arity <- fmap (+ 1) spec_join_arity1 - = (spec_lam_args, spec_call_args, spec_arity, spec_join_arity) - | otherwise - = (spec_lam_args1, spec_lam_args1, spec_arity1, spec_join_arity1) + ; let spec_body_ty = exprType spec_body + (spec_lam_args, spec_call_args, spec_sig) + = calcSpecInfo fn arg_bndrs call_pat extra_bndrs + spec_arity = count isId spec_lam_args + spec_join_arity | isJoinId fn = Just (length spec_call_args) + | otherwise = Nothing spec_id = asWorkerLikeId $ mkLocalId spec_name Many (mkLamTypes spec_lam_args spec_body_ty) @@ -1768,13 +1758,9 @@ spec_one env fn arg_bndrs body (call_pat, rule_number) `setIdArity` spec_arity `asJoinId_maybe` spec_join_arity - -- Conditionally use result of new worker-wrapper transform - spec_rhs = mkLams spec_lam_args (mkSeqs cbv_args spec_body_ty spec_body) - rule_rhs = mkVarApps (Var spec_id) $ - -- This will give us all the arguments we quantify over - -- in the rule plus the void argument if present - -- since `length(qvars) + void + length(extra_bndrs) = length spec_call_args` - dropTail (length extra_bndrs) spec_call_args + -- Conditionally use result of new worker-wrapper transform + spec_rhs = mkLams spec_lam_args (mkSeqs cbv_args spec_body_ty spec_body) + rule_rhs = mkVarApps (Var spec_id) spec_call_args inline_act = idInlineActivation fn this_mod = sc_module env rule = mkRule this_mod True {- Auto -} True {- Local -} @@ -1814,64 +1800,122 @@ mkSeqs seqees res_ty rhs = = rhs -{- Note [SpecConst needs to add void args first] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [SpecConstr void argument insertion] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function + f :: Bool -> forall t. blah f start @t = e We want to specialize for a partially applied call `f True`. See also Note [SpecConstr call patterns], second Wrinkle. Naively we would expect to get + $sf :: forall t. blah $sf @t = $se RULE: f True = $sf -The specialized function only takes a single type argument -so we add a void argument to prevent it from turning into -a thunk. See Note [Protecting the last value argument] for details -why. Normally we would add the void argument after the -type argument giving us: +The specialized function only takes a single type argument so we add a +void argument to prevent it from turning into a thunk. See Note +[Protecting the last value argument] for details why. Normally we +would add the void argument after the type argument giving us: + $sf :: forall t. Void# -> bla $sf @t void = $se RULE: f True = $sf void# (wrong) -But if you look closely this wouldn't typecheck! -If we substitute `f True` with `$sf void#` we expect the type argument to be applied first -but we apply void# first. -The easist fix seems to be just to add the void argument to the front of the arguments. -Now we get: + +But if you look closely this wouldn't typecheck! If we substitute `f +True` with `$sf void#` we expect the type argument to be applied first +but we apply void# first. The easiest fix seems to be just to add the +void argument to the front of the arguments. Now we get: + $sf :: Void# -> forall t. bla $sf void @t = $se RULE: f True = $sf void# + And now we can substitute `f True` with `$sf void#` with everything working out nicely! + +More precisely, in `calcSpecInfo` +(i) we need the void arg to /precede/ the `extra_bndrs`, but +(ii) it must still /follow/ `qvar_bndrs`. + +Example to illustrate (ii): + f :: forall r (a :: TYPE r). Bool -> a + f = /\r. /\(a::TYPE r). \b. body + + {- Specialise for f _ _ True -} + + $sf :: forall r (a :: TYPE r). Void# -> a + $sf = /\r. /\(a::TYPE r). \v. body[True/b] + RULE: forall r (a :: TYPE r). f @r @a True = $sf @r @a void# + +The void argument must follow the foralls, lest the forall be +ill-kinded. See Note [Worker/wrapper needs to add void arg last] in +GHC.Core.Opt.WorkWrap.Utils. + +Note [generaliseDictPats] +~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider these two rules (#21831, item 2): + RULE "SPEC:foo" forall d1 d2. foo @Int @Integer d1 d2 = $sfoo1 + RULE "SC:foo" forall a. foo @Int @a $fNumInteger = $sfoo2 @a +The former comes from the type class specialiser, the latter from SpecConstr. +Note that $fNumInteger is a top-level binding for Num Integer. + +The trouble is that neither is more general than the other. In a call + (foo @Int @Integer $fNumInteger d) +it isn't clear which rule to fire. + +The trouble is that the SpecConstr rule fires on a /specific/ dict, $fNumInteger, +but actually /could/ fire regardless. That is, it could be + RULE "SC:foo" forall a d. foo @Int @a d = $sfoo2 @a + +Now, it is clear that SPEC:foo is more specific. But GHC can't tell +that, because SpecConstr doesn't know that dictionary arguments are +singleton types! So generaliseDictPats teaches it this fact. It +spots such patterns (using typeDeterminesValue), and quantifies over +the dictionary. Now we get + + RULE "SC:foo" forall a d. foo @Int @a d = $sfoo2 @a + +And /now/ "SPEC:foo" is clearly more specific: we can instantiate the new +"SC:foo" to match the (prefix of) "SPEC:foo". -} -calcSpecInfo :: Id -- The original function - -> CallPat -- Call pattern - -> [Var] -- Extra bndrs - -> ( [Var] -- Demand-decorated binders - , DmdSig -- Strictness of specialised thing - , Arity, Maybe JoinArity ) -- Arities of specialised thing --- Calcuate bits of IdInfo for the specialised function +calcSpecInfo :: Id -- The original function + -> [InVar] -- Lambda binders of original RHS + -> CallPat -- Call pattern + -> [Var] -- Extra bndrs + -> ( [Var] -- Demand-decorated lambda binders + -- for RHS of specialised function + , [Var] -- Args for call site + , DmdSig ) -- Strictness of specialised thing +-- Calculate bits of IdInfo for the specialised function -- See Note [Transfer strictness] -- See Note [Strictness information in worker binders] -calcSpecInfo fn (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs - | isJoinId fn -- Join points have strictness and arity for LHS only - = ( bndrs_w_dmds - , mkClosedDmdSig qvar_dmds div - , count isId qvars - , Just (length qvars) ) - | otherwise - = ( bndrs_w_dmds - , mkClosedDmdSig (qvar_dmds ++ extra_dmds) div - , count isId qvars + count isId extra_bndrs - , Nothing ) +calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs + = ( spec_lam_bndrs_w_dmds + , spec_call_args + , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) where DmdSig (DmdType _ fn_dmds div) = idDmdSig fn - val_pats = filterOut isTypeArg pats -- value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. + val_pats = filterOut isTypeArg pats + -- Value args at call sites, used to determine how many demands to drop + -- from the original functions demand and for setting up dmd_env. + dmd_env = go emptyVarEnv fn_dmds val_pats qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds - bndrs_w_dmds = set_dmds qvars qvar_dmds - ++ set_dmds extra_bndrs extra_dmds + -- Annotate the variables with the strictness information from + -- the function (see Note [Strictness information in worker binders]) + qvars_w_dmds = set_dmds qvars qvar_dmds + extras_w_dmds = set_dmds extra_bndrs extra_dmds + spec_lam_bndrs_w_dmds = final_qvars_w_dmds ++ extras_w_dmds + + (final_qvars_w_dmds, spec_call_args) + | needsVoidWorkerArg fn arg_bndrs (qvars ++ extra_bndrs) + -- Usual w/w hack to avoid generating + -- a spec_rhs of unlifted or ill-kinded type and no args. + -- See Note [SpecConstr void argument insertion] + = ( qvars_w_dmds ++ [voidArgId], qvars ++ [voidPrimId] ) + | otherwise + = ( qvars_w_dmds, qvars ) set_dmds :: [Var] -> [Demand] -> [Var] set_dmds [] _ = [] @@ -1879,8 +1923,6 @@ calcSpecInfo fn (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - dmd_env = go emptyVarEnv fn_dmds val_pats - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats @@ -1894,7 +1936,6 @@ calcSpecInfo fn (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = go env ds args go_one env _ _ = env - {- Note [spec_usg includes rhs_usg] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -9,7 +9,7 @@ A library for the ``worker\/wrapper'' back-end to the strictness analyser module GHC.Core.Opt.WorkWrap.Utils ( WwOpts(..), initWwOpts, mkWwBodies, mkWWstr, mkWWstr_one - , needsVoidWorkerArg, addVoidWorkerArg + , needsVoidWorkerArg , DataConPatContext(..) , UnboxingDecision(..), wantToUnboxArg , findTypeShape, IsRecDataConResult(..), isRecDataCon @@ -387,25 +387,34 @@ We use the state-token type which generates no code. -- Note [Preserving float barriers]. needsVoidWorkerArg :: Id -> [Var] -> [Var] -> Bool needsVoidWorkerArg fn_id wrap_args work_args - = not (isJoinId fn_id) && no_value_arg -- See Note [Protecting the last value argument] - || needs_float_barrier -- See Note [Preserving float barriers] + = thunk_problem -- See Note [Protecting the last value argument] + || needs_float_barrier -- See Note [Preserving float barriers] where - no_value_arg = all (not . isId) work_args + -- thunk_problem: see Note [Protecting the last value argument] + -- For join points we are only worried about (4), not (1-4). + -- And (4) can't happen if (null work_args) + -- (We could be more clever, by looking at the result type, but + -- this approach is simple and conservative.) + thunk_problem | isJoinId fn_id = no_value_arg && not (null work_args) + | otherwise = no_value_arg + no_value_arg = not (any isId work_args) + + -- needs_float_barrier: see Note [Preserving float barriers] + needs_float_barrier = wrap_had_barrier && not work_has_barrier is_float_barrier v = isId v && hasNoOneShotInfo (idOneShotInfo v) wrap_had_barrier = any is_float_barrier wrap_args work_has_barrier = any is_float_barrier work_args - needs_float_barrier = wrap_had_barrier && not work_has_barrier --- | Inserts a `Void#` arg before the first argument. --- --- Why as the first argument? See Note [SpecConst needs to add void args first] --- in SpecConstr. +-- | Inserts a `Void#` arg as the last argument. +-- Why last? See Note [Worker/wrapper needs to add void arg last] addVoidWorkerArg :: [Var] -> [StrictnessMark] - -> ([Var], -- Lambda bound args - [Var], -- Args at call site - [StrictnessMark]) -- cbv semantics for the worker args. -addVoidWorkerArg work_args cbv_marks - = (voidArgId : work_args, voidPrimId:work_args, NotMarkedStrict:cbv_marks) + -> ( [Var] -- Lambda bound args + , [Var] -- Args at call site + , [StrictnessMark]) -- str semantics for the worker args +addVoidWorkerArg work_args str_marks + = ( work_args ++ [voidArgId] + , work_args ++ [voidPrimId] + , str_marks ++ [NotMarkedStrict] ) {- Note [Protecting the last value argument] @@ -413,8 +422,8 @@ Note [Protecting the last value argument] If the user writes (\_ -> E), they might be intentionally disallowing the sharing of E. Since absence analysis and worker-wrapper are keen to remove such unused arguments, we add in a void argument to prevent -the function from becoming a thunk. Three reasons why turning a function -into a thunk might be bad: +the function from becoming a thunk. Here are several reasons why turning +a function into a thunk might be bad: 1) It can create a space leak. e.g. f x = let y () = [1..x] @@ -433,7 +442,19 @@ into a thunk might be bad: g = \x. 30# Removing the \x would leave an unlifted binding. -NB: none of these apply to a join point. +4) It can create a worker of ill-kinded type (#22275). Consider + f :: forall r (a :: TYPE r). () -> a + f x = f x + Here `x` is absent, but if we simply drop it we'd end up with + $wf :: forall r (a :: TYPE r). a + But alas $wf's type is ill-kinded: the kind of (/\r (a::TYPE r).a) + is (TYPE r), which mentions the bound variable `r`. See also + Note [Worker/wrapper needs to add void arg last] + +See also Note [Preserving float barriers] + +NB: Of these, only (1-3) don't apply to a join point, which can be +unlifted even if the RHS is not ok-for-speculation. Note [Preserving float barriers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -467,7 +488,7 @@ which some are absent or one-shot and the resulting worker arguments: * \a{Abs}.\b{os}.\c{os}... ==> \b{os}.\c{os}.\(_::Void#)... Wrapper arg `a` was the only float barrier and had been dropped. Hence Void# - * \a{Abs,os}.\b{os}.\c... ==> \b{os}.\c... +p * \a{Abs,os}.\b{os}.\c... ==> \b{os}.\c... Worker arg `c` is a float barrier. * \a.\b{Abs}.\c{os}... ==> \a.\c{os}... Worker arg `a` is a float barrier. @@ -479,6 +500,27 @@ which some are absent or one-shot and the resulting worker arguments: Executable examples in T21150. +Note [Worker/wrapper needs to add void arg last] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider point (4) of Note [Protecting the last value argument] + + f :: forall r (a :: TYPE r). () -> a + f x = f x + +As pointed out in (4) we need to add a void argument. But if we add +it /first/ we'd get + + $wf :: Void# -> forall r (a :: TYPE r). a + $wf = ... + +But alas $wf's type is /still/ still-kinded, just as before in (4). +Solution is simple: put the void argument /last/: + + $wf :: forall r (a :: TYPE r). Void# -> a + $wf = ... + +c.f Note [SpecConstr void argument insertion] in GHC.Core.Opt.SpecConstr + Note [Join points and beta-redexes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Originally, the worker would invoke the original function by calling it with ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -166,7 +166,7 @@ coreAltsType :: [CoreAlt] -> Type coreAltsType (alt:_) = coreAltType alt coreAltsType [] = panic "coreAltsType" -mkLamType :: Var -> Type -> Type +mkLamType :: HasDebugCallStack => Var -> Type -> Type -- ^ Makes a @(->)@ type or an implicit forall type, depending -- on whether it is given a type variable or a term variable. -- This is used, for example, when producing the type of a lambda. ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -1,14 +1,14 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 71, types: 41, coercions: 0, joins: 0/0} + = {terms: 71, types: 40, coercions: 0, joins: 0/0} Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] - :: (# #) -> forall {a}. a + :: forall {a}. (# #) -> a [GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] -T13143.$wf = \ _ [Occ=Dead] (@a) -> T13143.$wf GHC.Prim.(##) @a +T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) end Rec } -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} @@ -20,8 +20,8 @@ f [InlPrag=[final]] :: forall a. Int -> a Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) - Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf GHC.Prim.(##) @a}] -f = \ (@a) _ [Occ=Dead] -> T13143.$wf GHC.Prim.(##) @a + Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)}] +f = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T13143.$trModule4 :: GHC.Prim.Addr# @@ -59,13 +59,13 @@ T13143.$trModule :: GHC.Types.Module T13143.$trModule = GHC.Types.Module T13143.$trModule3 T13143.$trModule1 --- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -lvl :: forall {a}. a +-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} +lvl :: Int [GblId, Str=b, Cpr=b] -lvl = T13143.$wf GHC.Prim.(##) +lvl = T13143.$wf @Int GHC.Prim.(##) Rec { --- RHS size: {terms: 28, types: 8, coercions: 0, joins: 0/0} +-- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0} T13143.$wg [InlPrag=[2], Occ=LoopBreaker] :: Bool -> Bool -> GHC.Prim.Int# -> GHC.Prim.Int# [GblId[StrictWorker([!, !])], ===================================== testsuite/tests/simplCore/should_compile/T18328.stderr ===================================== @@ -1,84 +1,90 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 65, types: 53, coercions: 0, joins: 1/1} + = {terms: 69, types: 55, coercions: 0, joins: 1/1} --- RHS size: {terms: 38, types: 23, coercions: 0, joins: 1/1} +-- RHS size: {terms: 42, types: 25, coercions: 0, joins: 1/1} T18328.$wf [InlPrag=[2]] :: forall {a}. GHC.Prim.Int# -> [a] -> [a] -> [a] -[GblId, +[GblId[StrictWorker([~, !])], Arity=3, Str=, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [176 0 0] 306 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [176 0 0] 306 0}] T18328.$wf - = \ (@a) (ww :: GHC.Prim.Int#) (w :: [a]) (w1 :: [a]) -> + = \ (@a) (ww :: GHC.Prim.Int#) (ys :: [a]) (eta :: [a]) -> join { - $wj [InlPrag=NOINLINE, Dmd=ML] :: forall {p}. [a] - [LclId[JoinId(1)]] - $wj (@p) + $wj [InlPrag=NOINLINE, Dmd=MC(1,L)] :: forall {p}. (# #) -> [a] + [LclId[JoinId(2)(Nothing)], Arity=1, Str=, Unf=OtherCon []] + $wj (@p) _ [Occ=Dead, OS=OneShot] = case ww of { - __DEFAULT -> ++ @a w (++ @a w (++ @a w w1)); - 3# -> ++ @a w (++ @a w (++ @a w (++ @a w w1))) + __DEFAULT -> ++ @a ys (++ @a ys (++ @a ys eta)); + 3# -> ++ @a ys (++ @a ys (++ @a ys (++ @a ys eta))) } } in case ww of { - __DEFAULT -> ++ @a w w1; - 1# -> jump $wj @Integer; - 2# -> jump $wj @Integer; - 3# -> jump $wj @Integer + __DEFAULT -> ++ @a ys eta; + 1# -> jump $wj @Integer GHC.Prim.(##); + 2# -> jump $wj @Integer GHC.Prim.(##); + 3# -> jump $wj @Integer GHC.Prim.(##) } -- RHS size: {terms: 11, types: 9, coercions: 0, joins: 0/0} f [InlPrag=[2]] :: forall a. Int -> [a] -> [a] -> [a] [GblId, Arity=3, - Str=<1P(SL)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Str=<1!P(SL)>, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) Tmpl= \ (@a) - (w [Occ=Once1!] :: Int) - (w1 [Occ=Once1] :: [a]) - (w2 [Occ=Once1] :: [a]) -> - case w of { GHC.Types.I# ww [Occ=Once1] -> - T18328.$wf @a ww w1 w2 + (x [Occ=Once1!] :: Int) + (ys [Occ=Once1] :: [a]) + (eta [Occ=Once1] :: [a]) -> + case x of { GHC.Types.I# ww [Occ=Once1] -> + T18328.$wf @a ww ys eta }}] -f = \ (@a) (w :: Int) (w1 :: [a]) (w2 :: [a]) -> - case w of { GHC.Types.I# ww -> T18328.$wf @a ww w1 w2 } +f = \ (@a) (x :: Int) (ys :: [a]) (eta :: [a]) -> + case x of { GHC.Types.I# ww -> T18328.$wf @a ww ys eta } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T18328.$trModule4 :: GHC.Prim.Addr# [GblId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] T18328.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18328.$trModule3 :: GHC.Types.TrName [GblId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18328.$trModule3 = GHC.Types.TrNameS T18328.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T18328.$trModule2 :: GHC.Prim.Addr# [GblId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] T18328.$trModule2 = "T18328"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18328.$trModule1 :: GHC.Types.TrName [GblId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18328.$trModule1 = GHC.Types.TrNameS T18328.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18328.$trModule :: GHC.Types.Module [GblId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18328.$trModule = GHC.Types.Module T18328.$trModule3 T18328.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/T22725.hs ===================================== @@ -0,0 +1,6 @@ +module M where + +import GHC.Exts (TYPE) + +f :: forall r (a :: TYPE r). () -> a +f x = f x ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -398,3 +398,4 @@ test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddu test('T22491', normal, compile, ['-O2']) test('T22623', normal, multimod_compile, ['T22623', '-O -v0']) test('T22662', normal, compile, ['']) +test('T22725', normal, compile, ['-O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aad62f1f11679d875705a0d9b86fbc9552e336cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aad62f1f11679d875705a0d9b86fbc9552e336cc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 06:25:28 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 02:25:28 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 14 commits: Add test for T23184 Message-ID: <6434fd58ee728_3b00559ec9fe7092802@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: d73ba44f by Matthew Pickering at 2023-04-11T11:55:10+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - f5322d7d by Matthew Pickering at 2023-04-11T11:55:10+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - 998f537b by Ben Gamari at 2023-04-11T11:55:10+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - 74397df1 by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - 917b9314 by Ben Gamari at 2023-04-11T11:55:11+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - aa27169d by Simon Peyton Jones at 2023-04-11T11:55:11+05:30 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise (cherry picked from commit 7192ef91c855e1fae6997f75cfde76aafd0b4bcf) - - - - - 1e6a6302 by Simon Peyton Jones at 2023-04-11T11:55:11+05:30 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 (cherry picked from commit 6206cb9287f3f6e70c669660a646a65274870d2b) - - - - - 9025be6f by Simon Peyton Jones at 2023-04-11T11:55:11+05:30 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. (cherry picked from commit 964284fcab6e27fe2fa5c279ea008551cbc15dbb) - - - - - f7ec8dc5 by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 3ba0de7d by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 0c3b31a0 by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - d3af633b by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 616ca622 by Ben Gamari at 2023-04-11T11:55:11+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - 58d64efe by Andreas Klebinger at 2023-04-11T11:55:11+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Utils.hs - rts/Capability.c - rts/Capability.h - rts/Messages.h - rts/PrimOps.cmm - rts/Printer.c - rts/ProfHeap.c - rts/ProfilerReport.c - rts/ProfilerReportJson.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/RtsUtils.c - rts/RtsUtils.h - rts/SMPClosureOps.h - rts/STM.c - rts/Schedule.c - rts/Sparks.c - rts/Stats.c - rts/Task.c - rts/Threads.c - rts/TraverseHeap.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aad62f1f11679d875705a0d9b86fbc9552e336cc...58d64efeeef6ae61cb7a7f33e0eafb583e1c021a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aad62f1f11679d875705a0d9b86fbc9552e336cc...58d64efeeef6ae61cb7a7f33e0eafb583e1c021a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 07:00:55 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 03:00:55 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 3 commits: Windows: Remove mingwex dependency Message-ID: <643505a744816_3b00559f73fce093074f@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: df3f069f by Ryan Scott at 2023-04-11T12:27:45+05:30 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` (cherry picked from commit de1d15127ac3f41ac3044215b0ea3398a36edc89) - - - - - 85b82afd by Tamar Christina at 2023-04-11T12:29:28+05:30 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. (cherry picked from commit 48e391952c17ff7eab10b0b1456e3f2a2af28a9b) - - - - - 83ffbcaa by Ben Gamari at 2023-04-11T12:30:25+05:30 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - 21 changed files: - .gitlab-ci.yml - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Oracles/Flag.hs - hadrian/src/Settings/Packages.hs - libraries/base/System/Posix/Internals.hs - libraries/base/base.cabal - libraries/base/configure.ac - libraries/base/include/HsBase.h - libraries/ghc-prim/ghc-prim.cabal - mk/get-win32-tarballs.py - rts/Linker.c - rts/LinkerInternals.h - rts/RtsSymbols.c - rts/linker/PEi386.c - rts/rts.cabal.in - testsuite/tests/ghci/linking/dyn/Makefile - testsuite/tests/ghci/linking/dyn/all.T - + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll - + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a - testsuite/tests/rts/all.T Changes: ===================================== .gitlab-ci.yml ===================================== @@ -6,7 +6,7 @@ variables: # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. - CACHE_REV: 8 + CACHE_REV: 10 # Disable shallow clones; they break our linting rules GIT_DEPTH: 0 ===================================== configure.ac ===================================== @@ -958,16 +958,6 @@ AC_CHECK_DECLS([ctime_r], , , #define _POSIX_C_SOURCE 199506L #include ]) -dnl ** check for mingwex library -AC_CHECK_LIB( - [mingwex], - [closedir], - [AC_SUBST([HaveLibMingwEx],[YES])] [AC_SUBST([CabalMingwex],[True])], - [AC_SUBST([HaveLibMingwEx],[NO])] [AC_SUBST([CabalMingwex],[False])]) - -if test $HaveLibMingwEx = YES ; then - AC_DEFINE([HAVE_MINGWEX], [1], [Define to 1 if you have the mingwex library.]) -fi dnl ** check for math library dnl Keep that check as early as possible. ===================================== hadrian/cfg/system.config.in ===================================== @@ -206,4 +206,3 @@ libnuma-lib-dir = @LibNumaLibDir@ with-libdw = @UseLibdw@ with-libnuma = @UseLibNuma@ -have-lib-mingw-ex = @HaveLibMingwEx@ ===================================== hadrian/src/Oracles/Flag.hs ===================================== @@ -30,7 +30,6 @@ data Flag = ArSupportsAtFile | SolarisBrokenShld | WithLibdw | WithLibnuma - | HaveLibMingwEx | UseSystemFfi | BootstrapThreadedRts | BootstrapEventLoggingRts @@ -55,7 +54,6 @@ flag f = do SolarisBrokenShld -> "solaris-broken-shld" WithLibdw -> "with-libdw" WithLibnuma -> "with-libnuma" - HaveLibMingwEx -> "have-lib-mingw-ex" UseSystemFfi -> "use-system-ffi" BootstrapThreadedRts -> "bootstrap-threaded-rts" BootstrapEventLoggingRts -> "bootstrap-event-logging-rts" ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -409,7 +409,7 @@ rtsPackageArgs = package rts ? do [ "-DTOP=" ++ show top ] , builder HsCpp ? flag WithLibdw ? arg "-DUSE_LIBDW" - , builder HsCpp ? flag HaveLibMingwEx ? arg "-DHAVE_LIBMINGWEX" ] + ] -- Compile various performance-critical pieces *without* -fPIC -dynamic -- even when building a shared library. If we don't do this, then the ===================================== libraries/base/System/Posix/Internals.hs ===================================== @@ -36,9 +36,7 @@ import Foreign.C -- import Data.Bits import Data.Maybe -#if !defined(HTYPE_TCFLAG_T) import System.IO.Error -#endif import GHC.Base import GHC.Num @@ -430,106 +428,158 @@ foreign import ccall unsafe "HsBase.h __hscore_fstat" foreign import ccall unsafe "HsBase.h __hscore_lstat" lstat :: CFilePath -> Ptr CStat -> IO CInt -{- Note: Win32 POSIX functions -Functions that are not part of the POSIX standards were -at some point deprecated by Microsoft. This deprecation -was performed by renaming the functions according to the -C++ ABI Section 17.6.4.3.2b. This was done to free up the -namespace of normal Windows programs since Windows isn't -POSIX compliant anyway. +#if defined(mingw32_HOST_OS) +-- See Note [Windows types] +foreign import capi unsafe "HsBase.h _read" + c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt -These were working before since the RTS was re-exporting -these symbols under the undeprecated names. This is no longer -being done. See #11223 +-- See Note [Windows types] +foreign import capi safe "HsBase.h _read" + c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt -See https://msdn.microsoft.com/en-us/library/ms235384.aspx -for more. +foreign import ccall unsafe "HsBase.h _umask" + c_umask :: CMode -> IO CMode -However since we can't hope to get people to support Windows -packages we should support the deprecated names. See #12497 --} -foreign import capi unsafe "unistd.h lseek" - c_lseek :: CInt -> COff -> CInt -> IO COff +-- See Note [Windows types] +foreign import capi unsafe "HsBase.h _write" + c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt -foreign import ccall unsafe "HsBase.h access" +-- See Note [Windows types] +foreign import capi safe "HsBase.h _write" + c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt + +foreign import ccall unsafe "HsBase.h _pipe" + c_pipe :: Ptr CInt -> IO CInt + +foreign import capi unsafe "HsBase.h _lseeki64" + c_lseek :: CInt -> Int64 -> CInt -> IO Int64 + +foreign import capi unsafe "HsBase.h _access" c_access :: CString -> CInt -> IO CInt -foreign import ccall unsafe "HsBase.h chmod" +#if !defined(HAVE_CHMOD) +c_chmod :: CString -> CMode -> IO CInt +c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "_chmod") +#else +foreign import ccall unsafe "HsBase.h _chmod" c_chmod :: CString -> CMode -> IO CInt +#endif -foreign import ccall unsafe "HsBase.h close" +foreign import capi unsafe "HsBase.h _close" c_close :: CInt -> IO CInt -foreign import ccall unsafe "HsBase.h creat" +foreign import capi unsafe "HsBase.h _creat" c_creat :: CString -> CMode -> IO CInt -foreign import ccall unsafe "HsBase.h dup" +#if !defined(HAVE_DUP) +c_dup :: CInt -> IO CInt +c_dup _ = ioError (ioeSetLocation unsupportedOperation "_dup") + +c_dup2 :: CInt -> CInt -> IO CInt +c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "_dup2") +#else +foreign import ccall unsafe "HsBase.h _dup" c_dup :: CInt -> IO CInt -foreign import ccall unsafe "HsBase.h dup2" +foreign import ccall unsafe "HsBase.h _dup2" c_dup2 :: CInt -> CInt -> IO CInt +#endif -foreign import ccall unsafe "HsBase.h isatty" +foreign import capi unsafe "HsBase.h _isatty" c_isatty :: CInt -> IO CInt -#if defined(mingw32_HOST_OS) --- See Note: Windows types -foreign import capi unsafe "HsBase.h _read" - c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt - --- See Note: Windows types -foreign import capi safe "HsBase.h _read" - c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt - -foreign import ccall unsafe "HsBase.h _umask" - c_umask :: CMode -> IO CMode +foreign import capi unsafe "HsBase.h _unlink" + c_unlink :: CString -> IO CInt --- See Note: Windows types -foreign import capi unsafe "HsBase.h _write" - c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt +foreign import capi unsafe "HsBase.h _utime" + c_utime :: CString -> Ptr CUtimbuf -> IO CInt --- See Note: Windows types -foreign import capi safe "HsBase.h _write" - c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt +foreign import capi unsafe "HsBase.h _getpid" + c_getpid :: IO CPid -foreign import ccall unsafe "HsBase.h _pipe" - c_pipe :: Ptr CInt -> IO CInt #else -- We use CAPI as on some OSs (eg. Linux) this is wrapped by a macro -- which redirects to the 64-bit-off_t versions when large file -- support is enabled. --- See Note: Windows types +-- See Note [Windows types] foreign import capi unsafe "HsBase.h read" c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize --- See Note: Windows types +-- See Note [Windows types] foreign import capi safe "HsBase.h read" c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize foreign import ccall unsafe "HsBase.h umask" c_umask :: CMode -> IO CMode --- See Note: Windows types +-- See Note [Windows types] foreign import capi unsafe "HsBase.h write" c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize --- See Note: Windows types +-- See Note [Windows types] foreign import capi safe "HsBase.h write" c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize +#if !defined(HAVE_PIPE) +c_pipe :: Ptr CInt -> IO CInt +c_pipe _ = ioError (ioeSetLocation unsupportedOperation "pipe") +#else foreign import ccall unsafe "HsBase.h pipe" c_pipe :: Ptr CInt -> IO CInt #endif +foreign import capi unsafe "unistd.h lseek" + c_lseek :: CInt -> COff -> CInt -> IO COff + +foreign import ccall unsafe "HsBase.h access" + c_access :: CString -> CInt -> IO CInt + +#if !defined(HAVE_CHMOD) +c_chmod :: CString -> CMode -> IO CInt +c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "chmod") +#else +foreign import ccall unsafe "HsBase.h chmod" + c_chmod :: CString -> CMode -> IO CInt +#endif + +foreign import ccall unsafe "HsBase.h close" + c_close :: CInt -> IO CInt + +foreign import ccall unsafe "HsBase.h creat" + c_creat :: CString -> CMode -> IO CInt + +#if !defined(HAVE_DUP) +c_dup :: CInt -> IO CInt +c_dup _ = ioError (ioeSetLocation unsupportedOperation "dup") + +c_dup2 :: CInt -> CInt -> IO CInt +c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "dup2") +#else +foreign import ccall unsafe "HsBase.h dup" + c_dup :: CInt -> IO CInt + +foreign import ccall unsafe "HsBase.h dup2" + c_dup2 :: CInt -> CInt -> IO CInt +#endif + +foreign import ccall unsafe "HsBase.h isatty" + c_isatty :: CInt -> IO CInt + foreign import ccall unsafe "HsBase.h unlink" c_unlink :: CString -> IO CInt foreign import capi unsafe "HsBase.h utime" c_utime :: CString -> Ptr CUtimbuf -> IO CInt +#if !defined(HAVE_GETPID) +c_getpid :: IO CPid +c_getpid = pure 1 +#else foreign import ccall unsafe "HsBase.h getpid" c_getpid :: IO CPid +#endif +#endif foreign import ccall unsafe "HsBase.h __hscore_stat" c_stat :: CFilePath -> Ptr CStat -> IO CInt @@ -656,7 +706,8 @@ foreign import capi unsafe "stdio.h value SEEK_SET" sEEK_SET :: CInt foreign import capi unsafe "stdio.h value SEEK_END" sEEK_END :: CInt {- -Note: Windows types +Note [Windows types] +~~~~~~~~~~~~~~~~~~~~ Windows' _read and _write have types that differ from POSIX. They take an unsigned int for length and return a signed int where POSIX uses size_t and ===================================== libraries/base/base.cabal ===================================== @@ -377,7 +377,6 @@ Library if os(windows) -- Windows requires some extra libraries for linking because the RTS -- is no longer re-exporting them. - -- mingwex: provides C99 compatibility. libm is a stub on MingW. -- mingw32: Unfortunately required because of a resource leak between -- mingwex and mingw32. the __math_err symbol is defined in -- mingw32 which is required by mingwex. @@ -390,7 +389,7 @@ Library -- advapi32: provides advanced kernel functions extra-libraries: wsock32, user32, shell32, mingw32, kernel32, advapi32, - mingwex, ws2_32, shlwapi, ole32, rpcrt4, ntdll + ws2_32, shlwapi, ole32, rpcrt4, ntdll -- Minimum supported Windows version. -- These numbers can be found at: -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx ===================================== libraries/base/configure.ac ===================================== @@ -38,7 +38,7 @@ AC_CHECK_FUNCS([lstat]) AC_CHECK_LIB([rt], [clock_gettime]) AC_CHECK_FUNCS([clock_gettime]) AC_CHECK_FUNCS([getclock getrusage times]) -AC_CHECK_FUNCS([_chsize ftruncate]) +AC_CHECK_FUNCS([_chsize_s ftruncate]) # event-related fun # The line below already defines HAVE_KQUEUE and HAVE_POLL, so technically some of the ===================================== libraries/base/include/HsBase.h ===================================== @@ -283,15 +283,12 @@ __hscore_o_nonblock( void ) INLINE int __hscore_ftruncate( int fd, off_t where ) { -#if defined(HAVE_FTRUNCATE) +#if defined(HAVE__CHSIZE_S) + return _chsize_s(fd,where); +#elif defined(HAVE_FTRUNCATE) return ftruncate(fd,where); -#elif defined(HAVE__CHSIZE) - return _chsize(fd,where); #else -// ToDo: we should use _chsize_s() on Windows which allows a 64-bit -// offset, but it doesn't seem to be available from mingw at this time -// --SDM (01/2008) -#error at least ftruncate or _chsize functions are required to build +#error at least _chsize_s or ftruncate functions are required to build #endif } ===================================== libraries/ghc-prim/ghc-prim.cabal ===================================== @@ -60,15 +60,14 @@ Library if os(windows) -- Windows requires some extra libraries for linking because the RTS -- is no longer re-exporting them (see #11223) - -- msvcrt: standard C library. The RTS will automatically include this, - -- but is added for completeness. - -- mingwex: provides C99 compatibility. libm is a stub on MingW. + -- ucrt: standard C library. The RTS will automatically include this, + -- but is added for completeness. -- mingw32: Unfortunately required because of a resource leak between -- mingwex and mingw32. the __math_err symbol is defined in -- mingw32 which is required by mingwex. -- user32: provides access to apis to modify user components (UI etc) -- on Windows. Required because of mingw32. - extra-libraries: user32, mingw32, mingwex, ucrt + extra-libraries: user32, mingw32, ucrt if os(linux) -- we need libm, but for musl and other's we might need libc, as libm ===================================== mk/get-win32-tarballs.py ===================================== @@ -8,7 +8,7 @@ import argparse import sys from sys import stderr -TARBALL_VERSION = '0.7' +TARBALL_VERSION = '0.8' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['x86_64', 'sources'] ===================================== rts/Linker.c ===================================== @@ -135,7 +135,7 @@ extern void iconv(); This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will never use. This is especially painful on Windows, where the number of - libraries required to link things like mingwex grows to be quite high. + libraries required to link things like QT or WxWidgets grows to be quite high. We proceed through these stages as follows, @@ -193,7 +193,7 @@ extern void iconv(); 1) Dependency chains, if A.o required a .o in libB but A.o isn't required to link then we don't need to load libB. This means the dependency chain for libraries - such as mingw32 and mingwex can be broken down. + such as ucrt can be broken down. 2) The number of duplicate symbols, since now only symbols that are true duplicates will display the error. @@ -226,7 +226,7 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key, static const char * symbolTypeString (SymType type) { - switch (type) { + switch (type & ~SYM_TYPE_DUP_DISCARD) { case SYM_TYPE_CODE: return "code"; case SYM_TYPE_DATA: return "data"; case SYM_TYPE_INDIRECT_DATA: return "indirect-data"; @@ -275,14 +275,18 @@ int ghciInsertSymbolTable( insertStrHashTable(table, key, pinfo); return 1; } - else if (pinfo->type != type) + else if (pinfo->type ^ type) { - debugBelch("Symbol type mismatch.\n"); - debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n", - key, obj_name, symbolTypeString(type)); - debugBelch(" yet was defined by %" PATH_FMT " to be a %s symbol.\n", - pinfo->owner ? pinfo->owner->fileName : WSTR(""), - symbolTypeString(pinfo->type)); + /* We were asked to discard the symbol on duplicates, do so quietly. */ + if (!(type & SYM_TYPE_DUP_DISCARD)) + { + debugBelch("Symbol type mismatch.\n"); + debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n", + key, obj_name, symbolTypeString(type)); + debugBelch(" yet was defined by %" PATH_FMT " to be a %s symbol.\n", + pinfo->owner ? pinfo->owner->fileName : WSTR(""), + symbolTypeString(pinfo->type)); + } return 1; } else if (pinfo->strength == STRENGTH_STRONG) ===================================== rts/LinkerInternals.h ===================================== @@ -52,11 +52,16 @@ typedef struct _Section Section; */ /* What kind of thing a symbol identifies. We need to know this to determine how - * to process overflowing relocations. See Note [Processing overflowed relocations]. */ + * to process overflowing relocations. See Note [Processing overflowed relocations]. + * This is bitfield however only the option SYM_TYPE_DUP_DISCARD can be combined + * with the other values. */ typedef enum _SymType { - SYM_TYPE_CODE, /* the symbol is a function and can be relocated via a jump island */ - SYM_TYPE_DATA, /* the symbol is data */ - SYM_TYPE_INDIRECT_DATA, /* see Note [_iob_func symbol] */ + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ } SymType; ===================================== rts/RtsSymbols.c ===================================== @@ -107,26 +107,6 @@ extern char **environ; * by the RtsSymbols entry. To avoid this we introduce a horrible special case * in `ghciInsertSymbolTable`, ensure that `atexit` is never overridden. */ -/* - * Note [Symbols for MinGW's printf] - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * The printf offered by Microsoft's libc implementation, msvcrt, is quite - * incomplete, lacking support for even %ull. Consequently mingw-w64 offers its - * own implementation which we enable. However, to be thread-safe the - * implementation uses _lock_file. This would be fine except msvcrt.dll doesn't - * export _lock_file, only numbered versions do (e.g. msvcrt90.dll). - * - * To work around this mingw-w64 packages a static archive of msvcrt which - * includes their own implementation of _lock_file. However, this means that - * the archive contains things which the dynamic library does not; consequently - * we need to ensure that the runtime linker provides this symbol. - * - * It's all just so terrible. - * - * See also: - * https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ - * https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/ - */ /* Note [_iob_func symbol] * ~~~~~~~~~~~~~~~~~~~~~~~ * Microsoft in VS2013 to VS2015 transition made a backwards incompatible change @@ -164,10 +144,6 @@ extern char **environ; SymI_NeedsProto(__mingw_module_is_dll) \ RTS_WIN32_ONLY(SymI_NeedsProto(___chkstk_ms)) \ RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \ - RTS_WIN64_ONLY(SymI_HasProto(_errno)) \ - /* see Note [Symbols for MinGW's printf] */ \ - SymI_HasProto(_lock_file) \ - SymI_HasProto(_unlock_file) \ SymI_HasProto(__mingw_vsnwprintf) \ /* ^^ Need to figure out why this is needed. */ \ /* See Note [_iob_func symbol] */ \ @@ -179,120 +155,8 @@ extern char **environ; /* ^^ Need to figure out why this is needed. */ \ SymI_HasProto(__mingw_vfprintf) \ /* ^^ Need to figure out why this is needed. */ - -#define RTS_MINGW_COMPAT_SYMBOLS \ - SymI_HasProto_deprecated(access) \ - SymI_HasProto_deprecated(cabs) \ - SymI_HasProto_deprecated(cgets) \ - SymI_HasProto_deprecated(chdir) \ - SymI_HasProto_deprecated(chmod) \ - SymI_HasProto_deprecated(chsize) \ - SymI_HasProto_deprecated(close) \ - SymI_HasProto_deprecated(cprintf) \ - SymI_HasProto_deprecated(cputs) \ - SymI_HasProto_deprecated(creat) \ - SymI_HasProto_deprecated(cscanf) \ - SymI_HasProto_deprecated(cwait) \ - SymI_HasProto_deprecated(dup) \ - SymI_HasProto_deprecated(dup2) \ - SymI_HasProto_deprecated(ecvt) \ - SymI_HasProto_deprecated(eof) \ - SymI_HasProto_deprecated(execl) \ - SymI_HasProto_deprecated(execle) \ - SymI_HasProto_deprecated(execlp) \ - SymI_HasProto_deprecated(execlpe) \ - SymI_HasProto_deprecated(execv) \ - SymI_HasProto_deprecated(execve) \ - SymI_HasProto_deprecated(execvp) \ - SymI_HasProto_deprecated(execvpe) \ - SymI_HasProto_deprecated(fcloseall) \ - SymI_HasProto_deprecated(fcvt) \ - SymI_HasProto_deprecated(fdopen) \ - SymI_HasProto_deprecated(fgetchar) \ - SymI_HasProto_deprecated(filelength) \ - SymI_HasProto_deprecated(fileno) \ - SymI_HasProto_deprecated(flushall) \ - SymI_HasProto_deprecated(fputchar) \ - SymI_HasProto_deprecated(gcvt) \ - SymI_HasProto_deprecated(getch) \ - SymI_HasProto_deprecated(getche) \ - SymI_HasProto_deprecated(getcwd) \ - SymI_HasProto_deprecated(getpid) \ - SymI_HasProto_deprecated(getw) \ - SymI_HasProto_deprecated(hypot) \ - SymI_HasProto_deprecated(inp) \ - SymI_HasProto_deprecated(inpw) \ - SymI_HasProto_deprecated(isascii) \ - SymI_HasProto_deprecated(isatty) \ - SymI_HasProto_deprecated(iscsym) \ - SymI_HasProto_deprecated(iscsymf) \ - SymI_HasProto_deprecated(itoa) \ - SymI_HasProto_deprecated(j0) \ - SymI_HasProto_deprecated(j1) \ - SymI_HasProto_deprecated(jn) \ - SymI_HasProto_deprecated(kbhit) \ - SymI_HasProto_deprecated(lfind) \ - SymI_HasProto_deprecated(locking) \ - SymI_HasProto_deprecated(lsearch) \ - SymI_HasProto_deprecated(lseek) \ - SymI_HasProto_deprecated(ltoa) \ - SymI_HasProto_deprecated(memccpy) \ - SymI_HasProto_deprecated(memicmp) \ - SymI_HasProto_deprecated(mkdir) \ - SymI_HasProto_deprecated(mktemp) \ - SymI_HasProto_deprecated(open) \ - SymI_HasProto_deprecated(outp) \ - SymI_HasProto_deprecated(outpw) \ - SymI_HasProto_deprecated(putch) \ - SymI_HasProto_deprecated(putenv) \ - SymI_HasProto_deprecated(putw) \ - SymI_HasProto_deprecated(read) \ - SymI_HasProto_deprecated(rmdir) \ - SymI_HasProto_deprecated(rmtmp) \ - SymI_HasProto_deprecated(setmode) \ - SymI_HasProto_deprecated(sopen) \ - SymI_HasProto_deprecated(spawnl) \ - SymI_HasProto_deprecated(spawnle) \ - SymI_HasProto_deprecated(spawnlp) \ - SymI_HasProto_deprecated(spawnlpe) \ - SymI_HasProto_deprecated(spawnv) \ - SymI_HasProto_deprecated(spawnve) \ - SymI_HasProto_deprecated(spawnvp) \ - SymI_HasProto_deprecated(spawnvpe) \ - SymI_HasProto_deprecated(strcmpi) \ - SymI_HasProto_deprecated(strdup) \ - SymI_HasProto_deprecated(stricmp) \ - SymI_HasProto_deprecated(strlwr) \ - SymI_HasProto_deprecated(strnicmp) \ - SymI_HasProto_deprecated(strnset) \ - SymI_HasProto_deprecated(strrev) \ - SymI_HasProto_deprecated(strset) \ - SymI_HasProto_deprecated(strupr) \ - SymI_HasProto_deprecated(swab) \ - SymI_HasProto_deprecated(tell) \ - SymI_HasProto_deprecated(tempnam) \ - SymI_HasProto_deprecated(toascii) \ - SymI_HasProto_deprecated(tzset) \ - SymI_HasProto_deprecated(ultoa) \ - SymI_HasProto_deprecated(umask) \ - SymI_HasProto_deprecated(ungetch) \ - SymI_HasProto_deprecated(unlink) \ - SymI_HasProto_deprecated(wcsdup) \ - SymI_HasProto_deprecated(wcsicmp) \ - SymI_HasProto_deprecated(wcsicoll) \ - SymI_HasProto_deprecated(wcslwr) \ - SymI_HasProto_deprecated(wcsnicmp) \ - SymI_HasProto_deprecated(wcsnset) \ - SymI_HasProto_deprecated(wcsrev) \ - SymI_HasProto_deprecated(wcsset) \ - SymI_HasProto_deprecated(wcsupr) \ - SymI_HasProto_deprecated(write) \ - SymI_HasProto_deprecated(y0) \ - SymI_HasProto_deprecated(y1) \ - SymI_HasProto_deprecated(yn) #else #define RTS_MINGW_ONLY_SYMBOLS /**/ -#define RTS_MINGW_COMPAT_SYMBOLS /**/ #endif @@ -1105,7 +969,6 @@ extern char **environ; #define SymI_HasProto(vvv) /**/ #define SymI_HasDataProto(vvv) /**/ #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/ -#define SymI_HasProto_deprecated(vvv) /**/ RTS_SYMBOLS RTS_RET_SYMBOLS @@ -1123,7 +986,6 @@ RTS_LIBFFI_SYMBOLS #undef SymI_HasProto #undef SymI_HasDataProto #undef SymI_HasProto_redirect -#undef SymI_HasProto_deprecated #undef SymE_HasProto #undef SymE_HasDataProto #undef SymE_NeedsProto @@ -1149,22 +1011,11 @@ RTS_LIBFFI_SYMBOLS { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \ (void*)(&(xxx)), strength, ty }, -// SymI_HasProto_deprecated allows us to redirect references from their deprecated -// names to the undeprecated ones. e.g. access -> _access. -// We use the hexspeak for unallocated memory 0xBAADF00D to signal the RTS -// that this needs to be loaded from somewhere else. -// These are inserted as weak symbols to prevent us overriding packages that do -// define them, since on Windows these functions shouldn't be in the top level -// namespace, but we have them for POSIX compatibility. -#define SymI_HasProto_deprecated(vvv) \ - { #vvv, (void*)0xBAADF00D, STRENGTH_WEAK, SYM_TYPE_CODE }, - RtsSymbolVal rtsSyms[] = { RTS_SYMBOLS RTS_RET_SYMBOLS RTS_POSIX_ONLY_SYMBOLS RTS_MINGW_ONLY_SYMBOLS - RTS_MINGW_COMPAT_SYMBOLS RTS_DARWIN_ONLY_SYMBOLS RTS_OPENBSD_ONLY_SYMBOLS RTS_LIBGCC_SYMBOLS ===================================== rts/linker/PEi386.c ===================================== @@ -261,6 +261,54 @@ .asciiz "libfoo_data" + Note [GHC Linking model and import libraries] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + The above describes how import libraries work for static linking. + Fundamentally this does not apply to dynamic linking as we do in GHC. + The issue is two-folds: + + 1. In the linking model above it is expected that the .idata sections be + materialized into PLTs during linking. However in GHC we never create + PLTs, but have out own mechanism for this which is the jump island + machinery. This is required for efficiency. For one materializing the + .idata sections would result in wasting pages. We'd use one page for + every ~100 bytes. This is extremely wasteful and also fragments the + memory. Secondly the dynamic linker is lazy. We only perform the final + loading if the symbol is used, however with an import library we can + discard the actual OC immediately after reading it. This prevents us from + keeping ~1k in memory per symbol for no reason. + + 2. GHC itself does not observe symbol visibility correctly during NGC. This + in itself isn't an academic exercise. The issue stems from GHC using one + mechanism for providing two incompatible linking modes: + a) The first mode is generating Haskell shared libraries which are + intended to be used by other Haskell code. This requires us to + export the info, data and closures. For this GHC just re-exports + all symbols. But it doesn't correcly mark data/code. Symbol + visibility is overwritten by telling the linker to export all + symbols. + b) The second code is producing code that's supposed to be call-able + through a C insterface. This in reality does not require the + export of closures and info tables. But also does not require the + inclusion of the RTS inside the DLL. Hover this is done today + because we don't properly have the RTS as a dynamic library. + i.e. GHC does not only export symbols denoted by foreign export. + Also GHC should depend on an RTS library, but at the moment it + cannot because of TNTC is incompatible with dynamic linking. + + These two issues mean that for GHC we need to take a different approach + to handling import libraries. For normal C libraries we have proper + differentiation between CODE and DATA. For GHC produced import libraries + we do not. As such the SYM_TYPE_DUP_DISCARD tells the linker that if a + duplicate symbol is found, and we were going to discard it anyway, just do + so quitely. This works because the RTS symbols themselves are provided by + the currently loaded RTS as built-in symbols. + + Secondly we cannot rely on a text symbol being available. As such we + should only depend on the symbols as defined in the .idata sections, + otherwise we would not be able to correctly link against GHC produced + import libraries. + Note [Memory allocation] ~~~~~~~~~~~~~~~~~~~~~~~~ The loading of an object begins in `preloadObjectFile`, which allocates a buffer, @@ -1700,7 +1748,10 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if ( secNumber != IMAGE_SYM_UNDEFINED && secNumber > 0 && section - && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY) { + /* Skip all BFD import sections. */ + && section->kind != SECTIONKIND_IMPORT + && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY + && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY_HEAD) { /* This symbol is global and defined, viz, exported */ /* for IMAGE_SYMCLASS_EXTERNAL && !IMAGE_SYM_UNDEFINED, @@ -1733,12 +1784,49 @@ ocGetNames_PEi386 ( ObjectCode* oc ) IF_DEBUG(linker_verbose, debugBelch("bss symbol @ %p %u\n", addr, symValue)); } else if (section && section->kind == SECTIONKIND_BFD_IMPORT_LIBRARY) { - setImportSymbol(oc, sname); + /* Disassembly of section .idata$5: + + 0000000000000000 <__imp_Insert>: + ... + 0: IMAGE_REL_AMD64_ADDR32NB .idata$6 + + The first two bytes contain the ordinal of the function + in the format of lowpart highpart. The two bytes combined + for the total range of 16 bits which is the function export limit + of DLLs. See note [GHC Linking model and import libraries]. */ + sname = (SymbolName*)section->start+2; + COFF_symbol* sym = &oc->info->symbols[info->numberOfSymbols-1]; + addr = get_sym_name( getSymShortName (info, sym), oc); + + IF_DEBUG(linker, + debugBelch("addImportSymbol `%s' => `%s'\n", + sname, (char*)addr)); + /* We're going to free the any data associated with the import + library without copying the sections. So we have to duplicate + the symbol name and values before the pointers become invalid. */ + sname = strdup (sname); + addr = strdup (addr); + type = has_code_section ? SYM_TYPE_CODE : SYM_TYPE_DATA; + type |= SYM_TYPE_DUP_DISCARD; + if (!ghciInsertSymbolTable(oc->fileName, symhash, sname, + addr, false, type, oc)) { + releaseOcInfo (oc); + stgFree (oc->image); + oc->image = NULL; + return false; + } + setImportSymbol (oc, sname); + + /* Don't process this oc any further. Just exit. */ + oc->n_symbols = 0; + oc->symbols = NULL; + stgFree (oc->image); + oc->image = NULL; + releaseOcInfo (oc); // There is nothing that we need to resolve in this object since we // will never call the import stubs in its text section oc->status = OBJECT_DONT_RESOLVE; - - IF_DEBUG(linker_verbose, debugBelch("import symbol %s\n", sname)); + return true; } else if (secNumber > 0 && section @@ -2285,21 +2373,7 @@ SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType } else { if (type) *type = pinfo->type; - // If Windows, perform initialization of uninitialized - // Symbols from the C runtime which was loaded above. - // We do this on lookup to prevent the hit when - // The symbol isn't being used. - if (pinfo->value == (void*)0xBAADF00D) - { - char symBuffer[50]; - const char *crt_impl = "ucrtbase"; - sprintf(symBuffer, "_%s", lbl); - static HMODULE crt = NULL; - if (!crt) crt = GetModuleHandle(crt_impl); - pinfo->value = GetProcAddress(crt, symBuffer); - return pinfo->value; - } - else if (pinfo && pinfo->owner && isSymbolImport (pinfo->owner, lbl)) + if (pinfo && pinfo->owner && isSymbolImport (pinfo->owner, lbl)) { /* See Note [BFD import library]. */ HINSTANCE dllInstance = (HINSTANCE)lookupDependentSymbol(pinfo->value, dependent, type); ===================================== rts/rts.cabal.in ===================================== @@ -24,8 +24,6 @@ flag need-pthread default: @CabalNeedLibpthread@ flag libbfd default: @CabalHaveLibbfd@ -flag mingwex - default: @CabalMingwex@ flag need-atomic default: @CabalNeedLibatomic@ flag libdw @@ -145,8 +143,6 @@ library if flag(libbfd) -- for debugging extra-libraries: bfd iberty - if flag(mingwex) - extra-libraries: mingwex if flag(libdw) -- for backtraces extra-libraries: elf dw ===================================== testsuite/tests/ghci/linking/dyn/Makefile ===================================== @@ -88,10 +88,6 @@ compile_libAB_dyn: .PHONY: compile_libAS_impl_gcc compile_libAS_impl_gcc: - rm -rf bin_impl_gcc - mkdir bin_impl_gcc - '$(TEST_HC)' $(MY_TEST_HC_OPTS) -odir "bin_impl_gcc" -shared A.c -o "bin_impl_gcc/$(call DLL,ASimpL)" - mv bin_impl_gcc/libASimpL.dll.a bin_impl_gcc/libASx.dll.a echo "main" | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) T11072.hs -lASx -L./bin_impl_gcc .PHONY: compile_libAS_impl_msvc ===================================== testsuite/tests/ghci/linking/dyn/all.T ===================================== @@ -33,9 +33,9 @@ test('T10458', extra_hc_opts('-L"$PWD/T10458dir" -lAS')], ghci_script, ['T10458.script']) -test('T11072gcc', [extra_files(['A.c', 'T11072.hs']), - expect_broken(18718), - unless(doing_ghci, skip), unless(opsys('mingw32'), skip)], +test('T11072gcc', [extra_files(['A.c', 'T11072.hs', 'bin_impl_gcc/']), + unless(doing_ghci, skip), unless(opsys('mingw32'), skip), + unless(arch('x86_64'), skip)], makefile_test, ['compile_libAS_impl_gcc']) test('T11072msvc', [extra_files(['A.c', 'T11072.hs', 'libAS.def', 'i686/', 'x86_64/']), ===================================== testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll ===================================== Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll differ ===================================== testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a ===================================== Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a differ ===================================== testsuite/tests/rts/all.T ===================================== @@ -368,7 +368,7 @@ test('T10296b', [only_ways(['threaded2'])], compile_and_run, ['']) test('numa001', [ extra_run_opts('8'), unless(unregisterised(), extra_ways(['debug_numa'])) ] , compile_and_run, ['']) -test('T12497', [ unless(opsys('mingw32'), skip) +test('T12497', [ unless(opsys('mingw32'), skip), expect_broken(22694) ], makefile_test, ['T12497']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58d64efeeef6ae61cb7a7f33e0eafb583e1c021a...83ffbcaa88c852c4a09ff4871c4e5f2926aa5b2b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/58d64efeeef6ae61cb7a7f33e0eafb583e1c021a...83ffbcaa88c852c4a09ff4871c4e5f2926aa5b2b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 07:14:46 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Apr 2023 03:14:46 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] undo accidental change to GHC.Bits Message-ID: <643508e67ff78_3b00559fbed094931144@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 9ab0c9d2 by Simon Peyton Jones at 2023-04-11T08:16:06+01:00 undo accidental change to GHC.Bits - - - - - 1 changed file: - libraries/base/GHC/Bits.hs Changes: ===================================== libraries/base/GHC/Bits.hs ===================================== @@ -722,4 +722,3 @@ own to enable constant folding; for example 'shift': -- > ; True -> Just (W16# (narrow16Word# (int2Word# b1))) -- > } -- > } -x=y \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ab0c9d2e30e2e25f78e5dfa6f2f76e891c8dcfe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ab0c9d2e30e2e25f78e5dfa6f2f76e891c8dcfe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 07:17:25 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 03:17:25 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] base: Remove HAVE_* CPP guards Message-ID: <643509852f9c3_3b00559fdbc9389317cb@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: a553978b by Zubin Duggal at 2023-04-11T12:47:08+05:30 base: Remove HAVE_* CPP guards - - - - - 1 changed file: - libraries/base/System/Posix/Internals.hs Changes: ===================================== libraries/base/System/Posix/Internals.hs ===================================== @@ -36,7 +36,9 @@ import Foreign.C -- import Data.Bits import Data.Maybe +#if !defined(HTYPE_TCFLAG_T) import System.IO.Error +#endif import GHC.Base import GHC.Num @@ -457,13 +459,8 @@ foreign import capi unsafe "HsBase.h _lseeki64" foreign import capi unsafe "HsBase.h _access" c_access :: CString -> CInt -> IO CInt -#if !defined(HAVE_CHMOD) -c_chmod :: CString -> CMode -> IO CInt -c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "_chmod") -#else foreign import ccall unsafe "HsBase.h _chmod" c_chmod :: CString -> CMode -> IO CInt -#endif foreign import capi unsafe "HsBase.h _close" c_close :: CInt -> IO CInt @@ -471,19 +468,11 @@ foreign import capi unsafe "HsBase.h _close" foreign import capi unsafe "HsBase.h _creat" c_creat :: CString -> CMode -> IO CInt -#if !defined(HAVE_DUP) -c_dup :: CInt -> IO CInt -c_dup _ = ioError (ioeSetLocation unsupportedOperation "_dup") - -c_dup2 :: CInt -> CInt -> IO CInt -c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "_dup2") -#else foreign import ccall unsafe "HsBase.h _dup" c_dup :: CInt -> IO CInt foreign import ccall unsafe "HsBase.h _dup2" c_dup2 :: CInt -> CInt -> IO CInt -#endif foreign import capi unsafe "HsBase.h _isatty" c_isatty :: CInt -> IO CInt @@ -521,13 +510,8 @@ foreign import capi unsafe "HsBase.h write" foreign import capi safe "HsBase.h write" c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize -#if !defined(HAVE_PIPE) -c_pipe :: Ptr CInt -> IO CInt -c_pipe _ = ioError (ioeSetLocation unsupportedOperation "pipe") -#else foreign import ccall unsafe "HsBase.h pipe" c_pipe :: Ptr CInt -> IO CInt -#endif foreign import capi unsafe "unistd.h lseek" c_lseek :: CInt -> COff -> CInt -> IO COff @@ -535,13 +519,8 @@ foreign import capi unsafe "unistd.h lseek" foreign import ccall unsafe "HsBase.h access" c_access :: CString -> CInt -> IO CInt -#if !defined(HAVE_CHMOD) -c_chmod :: CString -> CMode -> IO CInt -c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "chmod") -#else foreign import ccall unsafe "HsBase.h chmod" c_chmod :: CString -> CMode -> IO CInt -#endif foreign import ccall unsafe "HsBase.h close" c_close :: CInt -> IO CInt @@ -549,19 +528,11 @@ foreign import ccall unsafe "HsBase.h close" foreign import ccall unsafe "HsBase.h creat" c_creat :: CString -> CMode -> IO CInt -#if !defined(HAVE_DUP) -c_dup :: CInt -> IO CInt -c_dup _ = ioError (ioeSetLocation unsupportedOperation "dup") - -c_dup2 :: CInt -> CInt -> IO CInt -c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "dup2") -#else foreign import ccall unsafe "HsBase.h dup" c_dup :: CInt -> IO CInt foreign import ccall unsafe "HsBase.h dup2" c_dup2 :: CInt -> CInt -> IO CInt -#endif foreign import ccall unsafe "HsBase.h isatty" c_isatty :: CInt -> IO CInt @@ -572,14 +543,9 @@ foreign import ccall unsafe "HsBase.h unlink" foreign import capi unsafe "HsBase.h utime" c_utime :: CString -> Ptr CUtimbuf -> IO CInt -#if !defined(HAVE_GETPID) -c_getpid :: IO CPid -c_getpid = pure 1 -#else foreign import ccall unsafe "HsBase.h getpid" c_getpid :: IO CPid #endif -#endif foreign import ccall unsafe "HsBase.h __hscore_stat" c_stat :: CFilePath -> Ptr CStat -> IO CInt View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a553978b7703e360947db8e9a763e6ab358553ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a553978b7703e360947db8e9a763e6ab358553ef You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 07:46:22 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 03:46:22 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] lint Message-ID: <6435104e6dc27_3b0055a05bbd509341c4@gitlab.mail> Josh Meredith pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: c8e264d5 by Josh Meredith at 2023-04-11T07:46:10+00:00 lint - - - - - 2 changed files: - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/StgToJS/Expr.hs Changes: ===================================== compiler/GHC/Stg/BcPrep.hs ===================================== @@ -79,7 +79,7 @@ bcPrepExpr (StgTick tick rhs) = StgTick tick <$> bcPrepExpr rhs bcPrepExpr (StgLet xlet bnds expr) = StgLet xlet <$> bcPrepBind bnds - <*> bcPrepExpr expr + <*> bcPrepExpr expr bcPrepExpr (StgLetNoEscape xlne bnds expr) = StgLet xlne <$> bcPrepBind bnds <*> bcPrepExpr expr ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -319,7 +319,7 @@ genBody ctx i startReg args e typ = do -- compute PrimReps and their number of slots required to return the result of -- i applied to args. - let res_vars = resultSize args i typ + let res_vars = resultSize typ -- compute typed expressions for each slot and assign registers let go_var regs = \case @@ -360,23 +360,13 @@ genBody ctx i startReg args e typ = do -- In case of failure to determine the type, we default to LiftedRep as it's -- probably what it is. -- -resultSize :: HasDebugCallStack => [Id] -> Var -> Type -> [(PrimRep, Int)] -resultSize args t ty = result +resultSize :: HasDebugCallStack => Type -> [(PrimRep, Int)] +resultSize ty = result where result = result_reps `zip` result_slots result_slots = fmap (slotCount . primRepSize) result_reps result_reps = typePrimRep ty - trim_args t 0 = typePrimRep t - trim_args t n - | Just (_af, _mult, arg, res) <- splitFunTy_maybe t - , nargs <- length (typePrimRepArgs arg) - , assert (n >= nargs) True - = trim_args (unwrapType res) (n - nargs) - | otherwise - = pprTrace "result_type: not a function type, assume LiftedRep" (ppr t) - [LiftedRep] - -- | Ensure that the set of identifiers has valid 'RuntimeRep's. This function -- returns a no-op when 'csRuntimeAssert' in 'StgToJSConfig' is False. verifyRuntimeReps :: HasDebugCallStack => [Id] -> G JStat View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8e264d555b1281518614db24463ea9502cf249c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8e264d555b1281518614db24463ea9502cf249c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 08:10:35 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 04:10:35 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] lint-notes: accept output Message-ID: <643515fb437cb_3b0055a0e48720936730@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 05e44f81 by Zubin Duggal at 2023-04-11T13:40:21+05:30 lint-notes: accept output - - - - - 1 changed file: - testsuite/tests/linters/notes.stdout Changes: ===================================== testsuite/tests/linters/notes.stdout ===================================== @@ -1,138 +1,153 @@ +ref compiler/GHC/Builtin/PrimOps.hs:329:7: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:178:10: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:189:10: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:520:3: Note [exprOkForSpeculation and type classes] ref compiler/GHC/Core/Coercion/Axiom.hs:458:2: Note [RoughMap and rm_empty] -ref compiler/GHC/Core/Opt/Arity.hs:: Note [Combining case branches] -ref compiler/GHC/Core/Opt/Arity.hs:: Note [ArityType for let-bindings] +ref compiler/GHC/Core/Lint.hs:635:15: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:120:47: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:146:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:161:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:175:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:190:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Arity.hs:610:5: Note [Combining case branches] +ref compiler/GHC/Core/Opt/Arity.hs:1298:0: Note [ArityType for let-bindings] +ref compiler/GHC/Core/Opt/ConstantFold.hs:1413:15: Note [Core let/app invariant] ref compiler/GHC/Core/Opt/OccurAnal.hs:851:15: Note [Loop breaking] ref compiler/GHC/Core/Opt/SetLevels.hs:1598:30: Note [Top level scope] -ref compiler/GHC/Core/Opt/Simplify.hs:2618:13: Note [Case binder next] -ref compiler/GHC/Core/Opt/Simplify.hs:3239:0: Note [Suppressing binder-swaps on linear case] -ref compiler/GHC/Core/Opt/Simplify.hs:3767:8: Note [Lambda-bound unfoldings] -ref compiler/GHC/Core/Opt/Simplify.hs:4123:33: Note [Do not eta-expand trivial expressions] -ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1225:37: Note [Gentle mode] -ref compiler/GHC/Core/Opt/Specialise.hs:1593:28: Note [Arity decrease] +ref compiler/GHC/Core/Opt/Simplify.hs:1708:17: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Simplify.hs:2672:13: Note [Case binder next] +ref compiler/GHC/Core/Opt/Simplify.hs:3294:0: Note [Suppressing binder-swaps on linear case] +ref compiler/GHC/Core/Opt/Simplify.hs:3844:8: Note [Lambda-bound unfoldings] +ref compiler/GHC/Core/Opt/Simplify.hs:4200:33: Note [Do not eta-expand trivial expressions] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1240:37: Note [Gentle mode] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1294:7: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1420:7: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Specialise.hs:1588:28: Note [Arity decrease] ref compiler/GHC/Core/RoughMap.hs:183:35: Note [RoughMatch and beta reduction] ref compiler/GHC/Core/Subst.hs:100:60: Note [Apply once] ref compiler/GHC/Core/Subst.hs:111:16: Note [Extending the TCvSubst] -ref compiler/GHC/Core/TyCo/FVs.hs:289:7: Note [Free variables of Coercions] +ref compiler/GHC/Core/TyCo/FVs.hs:286:7: Note [Free variables of Coercions] ref compiler/GHC/Core/TyCo/Ppr.hs:71:23: Note [IfaceType and pretty-printing] -ref compiler/GHC/Core/TyCo/Rep.hs:1711:31: Note [What prevents a constraint from floating] +ref compiler/GHC/Core/TyCo/Rep.hs:1748:31: Note [What prevents a constraint from floating] ref compiler/GHC/Core/TyCo/Subst.hs:784:15: Note [Extending the TCvSubst] ref compiler/GHC/Core/TyCo/Subst.hs:1001:15: Note [Extending the TCvSubst] -ref compiler/GHC/Core/TyCon.hs:961:35: Note [Promoted GADT data construtors] -ref compiler/GHC/Core/TyCon.hs:2442:62: Note [Sharing nullary TyCons] -ref compiler/GHC/Core/Unfold.hs:1171:23: Note [INLINE for small functions (3)] -ref compiler/GHC/Core/Unfold.hs:1242:50: Note [Unfold info lazy contexts] +ref compiler/GHC/Core/TyCon.hs:966:35: Note [Promoted GADT data construtors] +ref compiler/GHC/Core/TyCon.hs:2472:62: Note [Sharing nullary TyCons] +ref compiler/GHC/Core/Unfold.hs:1174:23: Note [INLINE for small functions (3)] +ref compiler/GHC/Core/Unfold.hs:1245:50: Note [Unfold info lazy contexts] ref compiler/GHC/Core/Unfold/Make.hs:157:34: Note [DFunUnfoldings] -ref compiler/GHC/Core/Unify.hs:1390:9: Note [INLINE pragmas and (>>)] -ref compiler/GHC/Core/Utils.hs:947:40: Note [ _ -> [con1] -ref compiler/GHC/CoreToStg.hs:462:15: Note [Nullary unboxed tuple] -ref compiler/GHC/Driver/Main.hs:1566:34: Note [simpleTidyPgm - mkBootModDetailsTc] -ref compiler/GHC/Driver/Session.hs:1947:36: Note [GHC.Driver.Main . Safe Haskell Inference] -ref compiler/GHC/Driver/Session.hs:3916:49: Note [Eta-reduction in -O0] +ref compiler/GHC/Core/Unify.hs:1492:9: Note [INLINE pragmas and (>>)] +ref compiler/GHC/Core/Utils.hs:952:40: Note [ _ -> [con1] +ref compiler/GHC/CoreToStg.hs:463:15: Note [Nullary unboxed tuple] +ref compiler/GHC/Driver/Main.hs:1594:34: Note [simpleTidyPgm - mkBootModDetailsTc] +ref compiler/GHC/Driver/Session.hs:1997:36: Note [GHC.Driver.Main . Safe Haskell Inference] +ref compiler/GHC/Driver/Session.hs:3991:49: Note [Eta-reduction in -O0] ref compiler/GHC/Hs/Extension.hs:140:5: Note [Strict argument type constraints] ref compiler/GHC/HsToCore/Binds.hs:313:33: Note [AbsBinds wrappers] -ref compiler/GHC/HsToCore/Binds.hs:849:46: Note [Free dictionaries] -ref compiler/GHC/HsToCore/Binds.hs:883:36: Note [Free tyvars in rule LHS] -ref compiler/GHC/HsToCore/Binds.hs:884:35: Note [Free dictionaries in rule LHS] -ref compiler/GHC/HsToCore/Binds.hs:942:24: Note [Free dictionaries] -ref compiler/GHC/HsToCore/Binds.hs:999:34: Note [Dead spec binders] -ref compiler/GHC/HsToCore/Docs.hs:126:70: Note [1] -ref compiler/GHC/HsToCore/Docs.hs:130:0: Note [1] -ref compiler/GHC/HsToCore/Pmc/Solver.hs:853:20: Note [COMPLETE sets on data families] +ref compiler/GHC/HsToCore/Binds.hs:850:46: Note [Free dictionaries] +ref compiler/GHC/HsToCore/Binds.hs:884:36: Note [Free tyvars in rule LHS] +ref compiler/GHC/HsToCore/Binds.hs:885:35: Note [Free dictionaries in rule LHS] +ref compiler/GHC/HsToCore/Binds.hs:943:24: Note [Free dictionaries] +ref compiler/GHC/HsToCore/Binds.hs:1000:34: Note [Dead spec binders] +ref compiler/GHC/HsToCore/Docs.hs:272:70: Note [1] +ref compiler/GHC/HsToCore/Docs.hs:276:0: Note [1] +ref compiler/GHC/HsToCore/Pmc/Solver.hs:855:20: Note [COMPLETE sets on data families] ref compiler/GHC/HsToCore/Types.hs:61:13: Note [Generating fresh names for FFI wrappers] -ref compiler/GHC/HsToCore/Utils.hs:939:62: Note [Don't CPR join points] +ref compiler/GHC/HsToCore/Utils.hs:942:62: Note [Don't CPR join points] ref compiler/GHC/Iface/Syntax.hs:708:0: Note [Minimal complete definition] ref compiler/GHC/Iface/Syntax.hs:768:44: Note [Minimal complete definition] -ref compiler/GHC/Parser/Lexer.x:185:7: Note [Lexing NumericUnderscores extension] -ref compiler/GHC/Parser/Lexer.x:502:3: Note [Lexing NumericUnderscores extension] -ref compiler/GHC/Rename/Expr.hs:2013:9: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2046:12: Note [ApplicativeDo and refutable patterns] -ref compiler/GHC/Rename/Expr.hs:2130:18: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2148:0: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2203:0: Note [ApplicativeDo and refutable patterns] +ref compiler/GHC/Parser/Lexer.x:188:7: Note [Lexing NumericUnderscores extension] +ref compiler/GHC/Parser/Lexer.x:505:3: Note [Lexing NumericUnderscores extension] +ref compiler/GHC/Rename/Expr.hs:2043:9: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2082:12: Note [ApplicativeDo and refutable patterns] +ref compiler/GHC/Rename/Expr.hs:2166:18: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2184:0: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2239:0: Note [ApplicativeDo and refutable patterns] ref compiler/GHC/Rename/Pat.hs:888:29: Note [Disambiguating record fields] -ref compiler/GHC/Rename/Splice.hs:450:27: Note [Splices] -ref compiler/GHC/Runtime/Eval.hs:996:2: Note [Querying instances for a type] +ref compiler/GHC/Rename/Splice.hs:478:27: Note [Splices] +ref compiler/GHC/Runtime/Eval.hs:995:2: Note [Querying instances for a type] ref compiler/GHC/Runtime/Interpreter.hs:198:30: Note [uninterruptibleMask_] -ref compiler/GHC/StgToCmm.hs:108:18: Note [codegen-split-init] -ref compiler/GHC/StgToCmm.hs:111:18: Note [pipeline-split-init] -ref compiler/GHC/StgToCmm/Expr.hs:585:4: Note [case on bool] -ref compiler/GHC/StgToCmm/Expr.hs:848:3: Note [alg-alt heap check] -ref compiler/GHC/Tc/Errors.hs:180:13: Note [Fail fast on kind errors] -ref compiler/GHC/Tc/Errors.hs:2016:0: Note [Highlighting ambiguous type variables] -ref compiler/GHC/Tc/Errors/Ppr.hs:1760:11: Note [Highlighting ambiguous type variables] -ref compiler/GHC/Tc/Gen/Arrow.hs:435:29: Note [RecStmt] -ref compiler/GHC/Tc/Gen/Bind.hs:1397:19: Note [Existentials in pattern bindings] -ref compiler/GHC/Tc/Gen/Export.hs:187:15: Note [Modules without a module header] -ref compiler/GHC/Tc/Gen/Export.hs:418:0: Note [Modules without a module header] -ref compiler/GHC/Tc/Gen/Export.hs:576:7: Note [Typing Pattern Synonym Exports] -ref compiler/GHC/Tc/Gen/Export.hs:615:16: Note [Types of TyCon] -ref compiler/GHC/Tc/Gen/Expr.hs:670:24: Note [Disambiguating record fields] -ref compiler/GHC/Tc/Gen/Expr.hs:687:15: Note [Mixed Record Selectors] +ref compiler/GHC/Stg/Lint.hs:9:56: Note [Core let/app invariant] +ref compiler/GHC/StgToCmm.hs:106:18: Note [codegen-split-init] +ref compiler/GHC/StgToCmm.hs:109:18: Note [pipeline-split-init] +ref compiler/GHC/StgToCmm/Expr.hs:579:4: Note [case on bool] +ref compiler/GHC/StgToCmm/Expr.hs:847:3: Note [alg-alt heap check] +ref compiler/GHC/Tc/Errors.hs:178:13: Note [Fail fast on kind errors] +ref compiler/GHC/Tc/Errors.hs:2239:0: Note [Highlighting ambiguous type variables] +ref compiler/GHC/Tc/Errors/Ppr.hs:2074:11: Note [Highlighting ambiguous type variables] +ref compiler/GHC/Tc/Gen/Arrow.hs:438:29: Note [RecStmt] +ref compiler/GHC/Tc/Gen/Bind.hs:1368:19: Note [Existentials in pattern bindings] +ref compiler/GHC/Tc/Gen/Export.hs:188:15: Note [Modules without a module header] +ref compiler/GHC/Tc/Gen/Export.hs:423:0: Note [Modules without a module header] +ref compiler/GHC/Tc/Gen/Export.hs:581:7: Note [Typing Pattern Synonym Exports] +ref compiler/GHC/Tc/Gen/Export.hs:620:16: Note [Types of TyCon] +ref compiler/GHC/Tc/Gen/Expr.hs:662:24: Note [Disambiguating record fields] +ref compiler/GHC/Tc/Gen/Expr.hs:679:15: Note [Mixed Record Selectors] ref compiler/GHC/Tc/Gen/Expr.hs:1195:7: Note [Disambiguating record fields] ref compiler/GHC/Tc/Gen/Expr.hs:1298:11: Note [Deprecating ambiguous fields] ref compiler/GHC/Tc/Gen/Foreign.hs:149:26: Note [Expanding newtypes] -ref compiler/GHC/Tc/Gen/HsType.hs:552:56: Note [Skolem escape prevention] -ref compiler/GHC/Tc/Gen/HsType.hs:2623:7: Note [Matching a kind sigature with a declaration] -ref compiler/GHC/Tc/Gen/Match.hs:553:20: Note [GroupStmt binder map] -ref compiler/GHC/Tc/Gen/Match.hs:746:20: Note [GroupStmt binder map] -ref compiler/GHC/Tc/Gen/Match.hs:1011:0: Note [typechecking ApplicativeStmt] -ref compiler/GHC/Tc/Gen/Pat.hs:169:20: Note [Typing patterns in pattern bindings] -ref compiler/GHC/Tc/Gen/Pat.hs:476:7: Note [Pattern coercions] -ref compiler/GHC/Tc/Gen/Pat.hs:1077:7: Note [Matching polytyped patterns] -ref compiler/GHC/Tc/Gen/Pat.hs:1376:16: Note [Pattern coercions] +ref compiler/GHC/Tc/Gen/HsType.hs:551:56: Note [Skolem escape prevention] +ref compiler/GHC/Tc/Gen/HsType.hs:2632:7: Note [Matching a kind sigature with a declaration] +ref compiler/GHC/Tc/Gen/Match.hs:541:20: Note [GroupStmt binder map] +ref compiler/GHC/Tc/Gen/Match.hs:734:20: Note [GroupStmt binder map] +ref compiler/GHC/Tc/Gen/Match.hs:999:0: Note [typechecking ApplicativeStmt] +ref compiler/GHC/Tc/Gen/Pat.hs:171:20: Note [Typing patterns in pattern bindings] +ref compiler/GHC/Tc/Gen/Pat.hs:480:7: Note [Pattern coercions] +ref compiler/GHC/Tc/Gen/Pat.hs:1107:7: Note [Matching polytyped patterns] +ref compiler/GHC/Tc/Gen/Pat.hs:1407:16: Note [Pattern coercions] ref compiler/GHC/Tc/Gen/Sig.hs:78:10: Note [Overview of type signatures] ref compiler/GHC/Tc/Instance/Family.hs:515:35: Note [Constrained family instances] -ref compiler/GHC/Tc/Module.hs:698:15: Note [Extra dependencies from .hs-boot files] -ref compiler/GHC/Tc/Module.hs:1904:19: Note [Root-main id] -ref compiler/GHC/Tc/Module.hs:1974:6: Note [Root-main id] -ref compiler/GHC/Tc/Solver/Canonical.hs:1229:33: Note [Canonical LHS] -ref compiler/GHC/Tc/Solver/Interact.hs:1638:9: Note [No touchables as FunEq RHS] -ref compiler/GHC/Tc/Solver/Interact.hs:2292:12: Note [The equality class story] -ref compiler/GHC/Tc/Solver/Rewrite.hs:1032:7: Note [Stability of rewriting] +ref compiler/GHC/Tc/Module.hs:705:15: Note [Extra dependencies from .hs-boot files] +ref compiler/GHC/Tc/Module.hs:1916:19: Note [Root-main id] +ref compiler/GHC/Tc/Module.hs:1986:6: Note [Root-main id] +ref compiler/GHC/Tc/Solver/Canonical.hs:1087:33: Note [Canonical LHS] +ref compiler/GHC/Tc/Solver/Interact.hs:1619:9: Note [No touchables as FunEq RHS] +ref compiler/GHC/Tc/Solver/Interact.hs:2305:12: Note [The equality class story] +ref compiler/GHC/Tc/Solver/Rewrite.hs:988:7: Note [Stability of rewriting] ref compiler/GHC/Tc/TyCl.hs:627:3: Note [Single function non-recursive binding special-case] ref compiler/GHC/Tc/TyCl.hs:1106:6: Note [Unification variables need fresh Names] ref compiler/GHC/Tc/TyCl.hs:1895:13: Note [TyConBinders for the result kind signatures of a data type] -ref compiler/GHC/Tc/TyCl.hs:4366:16: Note [rejigCon and c.f. Note [Check role annotations in a second pass] +ref compiler/GHC/Tc/TyCl.hs:4362:16: Note [rejigCon and c.f. Note [Check role annotations in a second pass] ref compiler/GHC/Tc/TyCl/Instance.hs:947:26: Note [Generalising in tcFamTyPatsGuts] -ref compiler/GHC/Tc/Types.hs:647:17: Note [Generating fresh names for FFI wrappers] -ref compiler/GHC/Tc/Types.hs:696:33: Note [Extra dependencies from .hs-boot files] -ref compiler/GHC/Tc/Types.hs:1154:28: Note [Don't promote data constructors with non-equality contexts] -ref compiler/GHC/Tc/Types.hs:1230:36: Note [Bindings with closed types] -ref compiler/GHC/Tc/Types.hs:1466:47: Note [Care with plugin imports] -ref compiler/GHC/Tc/Types/Constraint.hs:238:34: Note [NonCanonical Semantics] +ref compiler/GHC/Tc/Types.hs:653:17: Note [Generating fresh names for FFI wrappers] +ref compiler/GHC/Tc/Types.hs:702:33: Note [Extra dependencies from .hs-boot files] +ref compiler/GHC/Tc/Types.hs:1160:28: Note [Don't promote data constructors with non-equality contexts] +ref compiler/GHC/Tc/Types.hs:1236:36: Note [Bindings with closed types] +ref compiler/GHC/Tc/Types.hs:1472:47: Note [Care with plugin imports] +ref compiler/GHC/Tc/Types/Constraint.hs:254:34: Note [NonCanonical Semantics] ref compiler/GHC/Tc/Utils/Env.hs:556:7: Note [Bindings with closed types] ref compiler/GHC/Tc/Utils/Env.hs:1128:7: Note [Generating fresh names for ccall wrapper] ref compiler/GHC/Tc/Utils/Env.hs:1141:0: Note [Generating fresh names for FFI wrappers] ref compiler/GHC/Tc/Utils/Env.hs:1192:7: Note [Placeholder PatSyn kinds] -ref compiler/GHC/Tc/Utils/TcMType.hs:793:7: Note [Kind checking for GADTs] -ref compiler/GHC/Tc/Utils/TcType.hs:529:7: Note [TyVars and TcTyVars] -ref compiler/GHC/ThToHs.hs:1738:11: Note [Adding parens for splices] -ref compiler/GHC/ThToHs.hs:1749:3: Note [Adding parens for splices] -ref compiler/GHC/Types/Basic.hs:619:17: Note [Safe Haskell isSafeOverlap] -ref compiler/GHC/Types/Basic.hs:1359:7: Note [Activation competition] -ref compiler/GHC/Types/Demand.hs:307:25: Note [Preserving Boxity of results is rarely a win] -ref compiler/GHC/Types/Demand.hs:1100:4: Note [Use one-shot information] +ref compiler/GHC/Tc/Utils/TcMType.hs:750:7: Note [Kind checking for GADTs] +ref compiler/GHC/Tc/Utils/TcType.hs:591:7: Note [TyVars and TcTyVars] +ref compiler/GHC/ThToHs.hs:1788:11: Note [Adding parens for splices] +ref compiler/GHC/ThToHs.hs:1799:3: Note [Adding parens for splices] +ref compiler/GHC/Types/Basic.hs:624:17: Note [Safe Haskell isSafeOverlap] +ref compiler/GHC/Types/Basic.hs:1370:7: Note [Activation competition] +ref compiler/GHC/Types/Demand.hs:310:25: Note [Preserving Boxity of results is rarely a win] +ref compiler/GHC/Types/Demand.hs:1142:4: Note [Use one-shot information] ref compiler/GHC/Types/Error.hs:358:3: Note [Suppressing Messages] ref compiler/GHC/Types/Error.hs:393:28: Note [Suppressing Messages] ref compiler/GHC/Types/Name/Occurrence.hs:301:4: Note [Unique OccNames from Template Haskell] ref compiler/GHC/Types/Unique.hs:78:25: Note [Uniques-prelude - Uniques for wired-in Prelude things] -ref compiler/GHC/Unit/Module/Deps.hs:79:13: Note [Structure of dep_boot_mods] +ref compiler/GHC/Unit/Module/Deps.hs:82:13: Note [Structure of dep_boot_mods] ref compiler/GHC/Utils/Monad.hs:391:34: Note [multiShotIO] -ref compiler/Language/Haskell/Syntax/Binds.hs:226:31: Note [fun_id in Match] -ref compiler/Language/Haskell/Syntax/Expr.hs:1561:32: Note [Quasi-quote overview] +ref compiler/Language/Haskell/Syntax/Binds.hs:204:31: Note [fun_id in Match] +ref compiler/Language/Haskell/Syntax/Expr.hs:1571:32: Note [Quasi-quote overview] ref compiler/Language/Haskell/Syntax/Pat.hs:336:12: Note [Disambiguating record fields] -ref configure.ac:212:10: Note [Linking ghc-bin against threaded stage0 RTS] +ref configure.ac:213:10: Note [Linking ghc-bin against threaded stage0 RTS] ref docs/core-spec/core-spec.mng:177:6: Note [TyBinders] -ref ghc/GHCi/UI.hs:3646:25: Note [ModBreaks.decls] -ref ghc/ghc.mk:62:6: Note [Linking ghc-bin against threaded stage0 RTS] -ref hadrian/src/Expression.hs:130:30: Note [Linking ghc-bin against threaded stage0 RTS] -ref libraries/base/GHC/ST.hs:139:7: Note [Definition of runRW#] +ref ghc/GHCi/UI.hs:3648:25: Note [ModBreaks.decls] +ref ghc/ghc.mk:57:6: Note [Linking ghc-bin against threaded stage0 RTS] +ref hadrian/src/Expression.hs:134:30: Note [Linking ghc-bin against threaded stage0 RTS] +ref libraries/base/GHC/ST.hs:134:7: Note [Definition of runRW#] ref linters/lint-notes/Notes.hs:32:29: Note [" <> T.unpack x <> "] ref linters/lint-notes/Notes.hs:69:22: Note [...] -ref testsuite/config/ghc:212:10: Note [WayFlags] +ref testsuite/config/ghc:243:10: Note [WayFlags] ref testsuite/driver/testlib.py:152:10: Note [Why is there no stage1 setup function?] ref testsuite/driver/testlib.py:156:2: Note [Why is there no stage1 setup function?] -ref testsuite/mk/boilerplate.mk:263:2: Note [WayFlags] +ref testsuite/mk/boilerplate.mk:267:2: Note [WayFlags] ref testsuite/tests/indexed-types/should_fail/ExtraTcsUntch.hs:30:27: Note [Extra TcS Untouchables] ref testsuite/tests/perf/join_points/join005.hs:19:63: Note [Don't CPR join points] ref testsuite/tests/perf/should_run/all.T:3:6: Note [Solving from instances when interacting Dicts] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05e44f81dad1b0db6911969ed56262c39f8fa9c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05e44f81dad1b0db6911969ed56262c39f8fa9c2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 08:15:45 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 04:15:45 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] hadrian: Extend xattr Darwin hack to cover /lib Message-ID: <6435173167660_3b0055a0e522c0939449@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: cf444699 by Ben Gamari at 2023-04-11T13:45:29+05:30 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit 78d04cfadfd728bb088b08b1e88905b43cc0360c) - - - - - 1 changed file: - hadrian/bindist/Makefile Changes: ===================================== hadrian/bindist/Makefile ===================================== @@ -147,7 +147,9 @@ install_bin_libdir: fi; \ done # Work around #17418 on Darwin - if [ -e "${XATTR}" ]; then "${XATTR}" -c -r "$(DESTDIR)$(ActualBinsDir)"; fi + if [ -e "${XATTR}" ]; then \ + "${XATTR}" -c -r "$(DESTDIR)$(ActualBinsDir)"; \ + fi install_bin_direct: @echo "Copying binaries to $(DESTDIR)$(WrapperBinsDir)" @@ -181,6 +183,10 @@ install_lib: lib/settings for i in $(DOCS); do \ cp -R $$i "$(DESTDIR)$(docdir)/"; \ done + # Work around #17418 on Darwin + if [ -e "${XATTR}" ]; then \ + "${XATTR}" -c -r "$(DESTDIR)$(ActualLibsDir)"; \ + fi install_docs: @echo "Copying docs to $(DESTDIR)$(docdir)" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf44469945d4059d70127c22372b9c2170dc9a34 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf44469945d4059d70127c22372b9c2170dc9a34 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 08:32:50 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 04:32:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add structured error messages for GHC.Tc.TyCl.Utils Message-ID: <64351b32bf50a_3b0055a11db95094485f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - 166d19f1 by Cheng Shao at 2023-04-11T04:32:38-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 919e1ece by Cheng Shao at 2023-04-11T04:32:38-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - 3cf6809e by Bodigrim at 2023-04-11T04:32:41-04:00 Set base 'maintainer' field to CLC - - - - - 17 changed files: - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Wasm/ControlFlow/FromCmm.hs - libraries/base/base.cabal - testsuite/tests/backpack/should_fail/bkpfail29.stderr - testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr - testsuite/tests/module/mod27.stderr - + testsuite/tests/rename/should_compile/T23240.hs - + testsuite/tests/rename/should_compile/T23240_aux.hs - testsuite/tests/rename/should_compile/all.T Changes: ===================================== compiler/GHC/CmmToAsm/Wasm/FromCmm.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Types.ForeignCall import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Map +import GHC.Types.Unique.Supply import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Wasm.ControlFlow.FromCmm @@ -1328,7 +1329,7 @@ lower_CmmUnsafeForeignCall_Drop :: [CmmActual] -> WasmCodeGenM w (WasmStatements w) lower_CmmUnsafeForeignCall_Drop lbl sym_callee ret_cmm_ty arg_exprs = do - ret_uniq <- wasmUniq + ret_uniq <- getUniqueM let ret_local = LocalReg ret_uniq ret_cmm_ty lower_CmmUnsafeForeignCall lbl @@ -1528,9 +1529,11 @@ lower_CmmGraph :: CLabel -> CmmGraph -> WasmCodeGenM w (FuncBody w) lower_CmmGraph lbl g = do ty_word <- wasmWordTypeM platform <- wasmPlatformM + us <- getUniqueSupplyM body <- structuredControl platform + us (\_ -> lower_CmmExpr_Typed lbl ty_word) (lower_CmmActions lbl) g ===================================== compiler/GHC/CmmToAsm/Wasm/Types.hs ===================================== @@ -45,7 +45,6 @@ module GHC.CmmToAsm.Wasm.Types wasmStateM, wasmModifyM, wasmExecM, - wasmUniq, ) where @@ -466,10 +465,18 @@ wasmStateM = coerce . State wasmModifyM :: (WasmCodeGenState w -> WasmCodeGenState w) -> WasmCodeGenM w () wasmModifyM = coerce . modify +wasmEvalM :: WasmCodeGenM w a -> WasmCodeGenState w -> a +wasmEvalM (WasmCodeGenM s) = evalState s + wasmExecM :: WasmCodeGenM w a -> WasmCodeGenState w -> WasmCodeGenState w wasmExecM (WasmCodeGenM s) = execState s -wasmUniq :: WasmCodeGenM w Unique -wasmUniq = wasmStateM $ - \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of - (u, us) -> (# u, s {wasmUniqSupply = us} #) +instance MonadUnique (WasmCodeGenM w) where + getUniqueSupplyM = wasmGetsM wasmUniqSupply + getUniqueM = wasmStateM $ + \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of + (u, us) -> (# u, s {wasmUniqSupply = us} #) + getUniquesM = do + u <- getUniqueM + s <- WasmCodeGenM get + pure $ u:(wasmEvalM getUniquesM s) ===================================== compiler/GHC/Rename/Env.hs ===================================== @@ -534,30 +534,29 @@ lookupRecFieldOcc mb_con rdr_name = return $ mk_unbound_rec_fld con | Just con <- mb_con = do { let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - ; res <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] + ; mb_nm <- lookupExactOrOrig rdr_name ensure_recfld $ -- See Note [Record field names and Template Haskell] do { flds <- lookupConstructorFields con ; env <- getGlobalRdrEnv - ; let lbl = FieldLabelString $ occNameFS (rdrNameOcc rdr_name) - mb_gre = do fl <- find ((== lbl) . flLabel) flds + ; let mb_gre = do fl <- find ((== lbl) . flLabel) flds -- We have the label, now check it is in scope. If -- there is a qualifier, use pickGREs to check that -- the qualifier is correct, and return the filtered -- GRE so we get import usage right (see #17853). gre <- lookupGRE_FieldLabel env fl if isQual rdr_name - then listToMaybe (pickGREs rdr_name [gre]) + then listToMaybe $ pickGREs rdr_name [gre] else return gre ; traceRn "lookupRecFieldOcc" $ vcat [ text "mb_con:" <+> ppr mb_con , text "rdr_name:" <+> ppr rdr_name , text "flds:" <+> ppr flds , text "mb_gre:" <+> ppr mb_gre ] - ; return mb_gre } - ; case res of + ; mapM_ (addUsedGRE True) mb_gre + ; return $ flSelector . fieldGRELabel <$> mb_gre } + ; case mb_nm of { Nothing -> do { addErr (badFieldConErr con lbl) ; return $ mk_unbound_rec_fld con } - ; Just gre -> do { addUsedGRE True gre - ; return (flSelector $ fieldGRELabel gre) } } } + ; Just nm -> return nm } } | otherwise -- Can't use the data constructor to disambiguate = greName <$> lookupGlobalOccRn' (IncludeFields WantField) rdr_name @@ -572,7 +571,9 @@ lookupRecFieldOcc mb_con rdr_name mkRecFieldOccFS (getOccFS con) (occNameFS occ) occ = rdrNameOcc rdr_name - ensure_recfld gre = do { guard (isRecFldGRE gre) ; return gre } + ensure_recfld :: GlobalRdrElt -> Maybe Name + ensure_recfld gre = do { guard (isRecFldGRE gre) + ; return $ greName gre } {- Note [DisambiguateRecordFields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1855,7 +1855,10 @@ mkImportMap gres RealSrcLoc decl_loc _ -> Map.insertWith add decl_loc [gre] imp_map UnhelpfulLoc _ -> imp_map where - best_imp_spec = bestImport (bagToList imp_specs) + best_imp_spec = + case bagToList imp_specs of + [] -> pprPanic "mkImportMap: GRE with no ImportSpecs" (ppr gre) + is:iss -> bestImport (is NE.:| iss) add _ gres = gre : gres warnUnusedImport :: WarningFlag -> GlobalRdrEnv ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1716,6 +1716,18 @@ instance Diagnostic TcRnMessage where -> mkSimpleDecorated $ text "Illegal" <+> (text $ levelString typeOrKind) <> colon <+> quotes (ppr thing) + TcRnTypeSynonymCycle decl_or_tcs + -> mkSimpleDecorated $ + sep [ text "Cycle in type synonym declarations:" + , nest 2 (vcat (map ppr_decl decl_or_tcs)) ] + where + ppr_decl = \case + Right (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl + Left tc -> + let n = tyConName tc + in ppr (getSrcSpan n) <> colon <+> ppr (tyConName tc) + <+> text "from external module" + diagnosticReason = \case TcRnUnknownMessage m @@ -2286,6 +2298,8 @@ instance Diagnostic TcRnMessage where -> WarningWithFlag Opt_WarnUnusedForalls TcRnDataKindsError{} -> ErrorWithoutFlag + TcRnTypeSynonymCycle{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -2883,6 +2897,8 @@ instance Diagnostic TcRnMessage where -> noHints TcRnDataKindsError{} -> [suggestExtension LangExt.DataKinds] + TcRnTypeSynonymCycle{} + -> noHints diagnosticCode = constructorCode ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -108,6 +108,7 @@ module GHC.Tc.Errors.Types ( , TyFamsDisabledReason(..) , HsTypeOrSigType(..) , HsTyVarBndrExistentialFlag(..) + , TySynCycleTyCons ) where import GHC.Prelude @@ -3787,6 +3788,15 @@ data TcRnMessage where -> HsExpr GhcPs -- ^ Section -> TcRnMessage + {-| TcRnTypeSynonymCycle is an error indicating that a cycle between type + synonyms has occurred. + + Test cases: + mod27, ghc-e-fail2, bkpfail29 + -} + TcRnTypeSynonymCycle :: !TySynCycleTyCons -- ^ The tycons involved in the cycle + -> TcRnMessage + deriving Generic -- | Things forbidden in @type data@ declarations. @@ -5192,3 +5202,6 @@ data HsTyVarBndrExistentialFlag = forall flag. OutputableBndrFlag flag 'Renamed instance Outputable HsTyVarBndrExistentialFlag where ppr (HsTyVarBndrExistentialFlag hsTyVarBndr) = ppr hsTyVarBndr + +type TySynCycleTyCons = + [Either TyCon (LTyClDecl GhcRn)] ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -65,7 +65,6 @@ import GHC.Data.FastString import GHC.Unit.Module import GHC.Types.Basic -import GHC.Types.Error import GHC.Types.FieldLabel import GHC.Types.SrcLoc import GHC.Types.SourceFile @@ -168,7 +167,7 @@ synonymTyConsOfType ty -- track of the TyCons which are known to be acyclic, or -- a failure message reporting that a cycle was found. newtype SynCycleM a = SynCycleM { - runSynCycleM :: SynCycleState -> Either (SrcSpan, SDoc) (a, SynCycleState) } + runSynCycleM :: SynCycleState -> Either (SrcSpan, TySynCycleTyCons) (a, SynCycleState) } deriving (Functor) -- TODO: TyConSet is implemented as IntMap over uniques. @@ -188,8 +187,8 @@ instance Monad SynCycleM where runSynCycleM (f x) state' Left err -> Left err -failSynCycleM :: SrcSpan -> SDoc -> SynCycleM () -failSynCycleM loc err = SynCycleM $ \_ -> Left (loc, err) +failSynCycleM :: SrcSpan -> TySynCycleTyCons -> SynCycleM () +failSynCycleM loc seen_tcs = SynCycleM $ \_ -> Left (loc, seen_tcs) -- | Test if a 'Name' is acyclic, short-circuiting if we've -- seen it already. @@ -209,7 +208,7 @@ checkTyConIsAcyclic tc m = SynCycleM $ \s -> checkSynCycles :: Unit -> [TyCon] -> [LTyClDecl GhcRn] -> TcM () checkSynCycles this_uid tcs tyclds = case runSynCycleM (mapM_ (go emptyTyConSet []) tcs) emptyTyConSet of - Left (loc, err) -> setSrcSpan loc $ failWithTc (mkTcRnUnknownMessage $ mkPlainError noHints err) + Left (loc, err) -> setSrcSpan loc $ failWithTc (TcRnTypeSynonymCycle err) Right _ -> return () where -- Try our best to print the LTyClDecl for locally defined things @@ -226,9 +225,7 @@ checkSynCycles this_uid tcs tyclds = go' :: TyConSet -> [TyCon] -> TyCon -> SynCycleM () go' so_far seen_tcs tc | tc `elemTyConSet` so_far - = failSynCycleM (getSrcSpan (head seen_tcs)) $ - sep [ text "Cycle in type synonym declarations:" - , nest 2 (vcat (map ppr_decl seen_tcs)) ] + = failSynCycleM (getSrcSpan (head seen_tcs)) (lookup_decl <$> seen_tcs) -- Optimization: we don't allow cycles through external packages, -- so once we find a non-local name we are guaranteed to not -- have a cycle. @@ -245,13 +242,10 @@ checkSynCycles this_uid tcs tyclds = where n = tyConName tc mod = nameModule n - ppr_decl tc = - case lookupNameEnv lcl_decls n of - Just (L loc decl) -> ppr (locA loc) <> colon <+> ppr decl - Nothing -> ppr (getSrcSpan n) <> colon <+> ppr n - <+> text "from external module" - where - n = tyConName tc + lookup_decl tc = + case lookupNameEnv lcl_decls (tyConName tc) of + Just decl -> Right decl + Nothing -> Left tc go_ty :: TyConSet -> [TyCon] -> Type -> SynCycleM () go_ty so_far seen_tcs ty = ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -578,6 +578,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnRoleAnnotationsDisabled" = 17779 GhcDiagnosticCode "TcRnIncoherentRoles" = 18273 GhcDiagnosticCode "TcRnTyFamNameMismatch" = 88221 + GhcDiagnosticCode "TcRnTypeSynonymCycle" = 97522 -- TcRnBadFieldAnnotation/BadFieldAnnotationReason GhcDiagnosticCode "LazyFieldsDisabled" = 81601 ===================================== compiler/GHC/Types/Name/Reader.hs ===================================== @@ -126,7 +126,6 @@ import GHC.Utils.Panic import Control.DeepSeq import Control.Monad ( guard ) import Data.Data -import Data.List ( sortBy ) import qualified Data.List.NonEmpty as NE import qualified Data.Map.Strict as Map import qualified Data.Semigroup as S @@ -1654,12 +1653,9 @@ data ImpItemSpec -- only @T@ is named explicitly. deriving (Eq, Data) -bestImport :: [ImportSpec] -> ImportSpec +bestImport :: NE.NonEmpty ImportSpec -> ImportSpec -- See Note [Choosing the best import declaration] -bestImport iss - = case sortBy best iss of - (is:_) -> is - [] -> pprPanic "bestImport" (ppr iss) +bestImport iss = NE.head $ NE.sortBy best iss where best :: ImportSpec -> ImportSpec -> Ordering -- Less means better ===================================== compiler/GHC/Wasm/ControlFlow/FromCmm.hs ===================================== @@ -19,12 +19,13 @@ import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dominators import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label +import GHC.Cmm.Reducibility import GHC.Cmm.Switch import GHC.CmmToAsm.Wasm.Types import GHC.Platform - +import GHC.Types.Unique.Supply import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable ( Outputable, text, (<+>), ppr @@ -140,15 +141,19 @@ emptyPost _ = False structuredControl :: forall expr stmt m . Applicative m => Platform -- ^ needed for offset calculation + -> UniqSupply -> (Label -> CmmExpr -> m expr) -- ^ translator for expressions -> (Label -> CmmActions -> m stmt) -- ^ translator for straight-line code -> CmmGraph -- ^ CFG to be translated -> m (WasmControl stmt expr '[] '[ 'I32]) -structuredControl platform txExpr txBlock g = +structuredControl platform us txExpr txBlock g' = doTree returns dominatorTree emptyContext where + g :: CmmGraph + g = gwd_graph gwd + gwd :: GraphWithDominators CmmNode - gwd = graphWithDominators g + gwd = initUs_ us $ asReducible $ graphWithDominators g' dominatorTree :: Tree.Tree CmmBlock-- Dominator tree in which children are sorted -- with highest reverse-postorder number first ===================================== libraries/base/base.cabal ===================================== @@ -5,8 +5,8 @@ version: 4.18.0.0 license: BSD-3-Clause license-file: LICENSE -maintainer: libraries at haskell.org -bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +maintainer: Core Libraries Committee +bug-reports: https://github.com/haskell/core-libraries-committee/issues synopsis: Basic libraries category: Prelude build-type: Configure ===================================== testsuite/tests/backpack/should_fail/bkpfail29.stderr ===================================== @@ -5,7 +5,7 @@ [3 of 3] Processing r [1 of 4] Compiling A[sig] ( r/A.hsig, nothing ) -bkpfail29.bkp:8:9: error: +bkpfail29.bkp:8:9: error: [GHC-97522] • Cycle in type synonym declarations: bkpfail29.bkp:8:9-18: S from external module bkpfail29.bkp:7:9-14: T from external module ===================================== testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr ===================================== @@ -1,5 +1,5 @@ -:0:1: error: +:0:1: error: [GHC-97522] Cycle in type synonym declarations: :0:1-10: type A = A 1 ===================================== testsuite/tests/module/mod27.stderr ===================================== @@ -1,5 +1,5 @@ -mod27.hs:3:1: error: +mod27.hs:3:1: error: [GHC-97522] Cycle in type synonym declarations: mod27.hs:3:1-18: type T1 = (Int, T2) mod27.hs:4:1-18: type T2 = (Int, T1) ===================================== testsuite/tests/rename/should_compile/T23240.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +-- Crucial to triggering the bug. +{-# LANGUAGE DisambiguateRecordFields #-} + +-- Need to enable the unused imports warning to trigger the bug. +{-# OPTIONS_GHC -Wunused-imports #-} + +module T23240 ( test ) where +import T23240_aux ( D, mkD ) + +test :: D +test = $$mkD ===================================== testsuite/tests/rename/should_compile/T23240_aux.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE Haskell2010 #-} +{-# LANGUAGE TemplateHaskell #-} + +module T23240_aux where + +import Language.Haskell.TH ( CodeQ ) + +data D = MkD { myFld :: () } +mkD :: CodeQ D +mkD = [|| MkD { myFld = () } ||] ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -209,3 +209,4 @@ test('ImportNullaryRecordWildcard', [extra_files(['NullaryRecordWildcard.hs', 'N test('GHCINullaryRecordWildcard', combined_output, ghci_script, ['GHCINullaryRecordWildcard.script']) test('GHCIImplicitImportNullaryRecordWildcard', combined_output, ghci_script, ['GHCIImplicitImportNullaryRecordWildcard.script']) test('T22122', [expect_broken(22122), extra_files(['T22122_aux.hs'])], multimod_compile, ['T22122', '-v0']) +test('T23240', [req_th, extra_files(['T23240_aux.hs'])], multimod_compile, ['T23240', '-v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ff849e25c4a5cf4d56611482014c9ddd46c4fa6...3cf6809efb65a286349c4b453bc38ccaed03c90c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6ff849e25c4a5cf4d56611482014c9ddd46c4fa6...3cf6809efb65a286349c4b453bc38ccaed03c90c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 08:38:14 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 04:38:14 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] lint Message-ID: <64351c76cf965_35453030082c26864@gitlab.mail> Josh Meredith pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: 9b90863b by Josh Meredith at 2023-04-11T08:38:04+00:00 lint - - - - - 2 changed files: - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs Changes: ===================================== compiler/GHC/StgToJS/CodeGen.hs ===================================== @@ -335,7 +335,7 @@ genToplevelRhs i rhs = case rhs of -} eid@(TxtI eidt) <- identForEntryId i (TxtI idt) <- identForId i - body <- genBody (initExprCtx i) i R2 args body typ + body <- genBody (initExprCtx i) R2 args body typ global_occs <- globalOccs (jsSaturate (Just "ghcjs_tmp_sat_") body) let lidents = map global_ident global_occs let lids = map global_id global_occs ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -74,7 +74,6 @@ import GHC.Core.Type hiding (typeSize) import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import GHC.Utils.Outputable (ppr, renderWithContext, defaultSDocContext) import qualified Control.Monad.Trans.State.Strict as State import GHC.Data.FastString @@ -238,7 +237,7 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body typ) = ]) | otherwise = mempty lvs <- popLneFrame True payloadSize ctx - body <- genBody ctx i R1 args body typ + body <- genBody ctx R1 args body typ ei@(TxtI eii) <- identForEntryId i sr <- genStaticRefsRhs rhs let f = JFunc [] (bh <> lvs <> body) @@ -270,7 +269,7 @@ genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body typ) = ll <- loadLiveFun live llv <- verifyRuntimeReps live upd <- genUpdFrame upd_flag i - body <- genBody entryCtx i R2 args body typ + body <- genBody entryCtx R2 args body typ ei@(TxtI eii) <- identForEntryId i et <- genEntryType args setcc <- ifProfiling $ @@ -302,13 +301,12 @@ genEntryType args0 = do -- | Generate the body of an object genBody :: HasDebugCallStack => ExprCtx - -> Id -> StgReg -> [Id] -> CgStgExpr -> Type -> G JStat -genBody ctx i startReg args e typ = do +genBody ctx startReg args e typ = do -- load arguments into local variables la <- do args' <- concatMapM genIdArgI args View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b90863b69e3fce969bb8fcb1bbb2418dd5ece5f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9b90863b69e3fce969bb8fcb1bbb2418dd5ece5f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 08:51:46 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 04:51:46 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 48 commits: hadrian bindist: Install manpages to share/man/man1/ghc.1 Message-ID: <64351fa2f261e_35453058cb18273db@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 6f4d4183 by Matthew Pickering at 2023-04-11T14:21:10+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - 0f66e042 by Matthew Pickering at 2023-04-11T14:21:10+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - b22be33e by Matthew Pickering at 2023-04-11T14:21:10+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - 758e5bf3 by Matthew Pickering at 2023-04-11T14:21:10+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 4509941c by Matthew Pickering at 2023-04-11T14:21:10+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 6198f5c8 by Matthew Pickering at 2023-04-11T14:21:10+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 4a2ed4f0 by Matthew Pickering at 2023-04-11T14:21:10+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 25abf0e4 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - 2b1cb6ae by Matthew Pickering at 2023-04-11T14:21:11+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 647b8685 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - ec025db7 by Simon Peyton Jones at 2023-04-11T14:21:11+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - da548fd0 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - ad34d110 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - 91fa7f73 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - 4022a117 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - f4b4d8f2 by Matthew Pickering at 2023-04-11T14:21:11+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - d66ec1da by Krzysztof Gogolewski at 2023-04-11T14:21:11+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - df640029 by Simon Peyton Jones at 2023-04-11T14:21:11+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - dcbfb699 by sheaf at 2023-04-11T14:21:11+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - 612f6029 by Sylvain Henry at 2023-04-11T14:21:11+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - 92c0acf2 by Sylvain Henry at 2023-04-11T14:21:11+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 2eec25f1 by Sylvain Henry at 2023-04-11T14:21:11+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - d3afd617 by Sylvain Henry at 2023-04-11T14:21:11+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 939b17c4 by Ben Gamari at 2023-04-11T14:21:11+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - 318af91c by Ben Gamari at 2023-04-11T14:21:11+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - 9d3d8b99 by Ben Gamari at 2023-04-11T14:21:11+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - b5ce8f77 by Ben Gamari at 2023-04-11T14:21:11+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 91298f87 by Li-yao Xia at 2023-04-11T14:21:12+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - f64d0c8f by Matthew Pickering at 2023-04-11T14:21:12+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - 4f202c11 by Matthew Pickering at 2023-04-11T14:21:12+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - 65ec3508 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - d5427586 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - 776b960e by Ben Gamari at 2023-04-11T14:21:12+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - ba35912a by Simon Peyton Jones at 2023-04-11T14:21:12+05:30 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise (cherry picked from commit 7192ef91c855e1fae6997f75cfde76aafd0b4bcf) - - - - - 68b24571 by Simon Peyton Jones at 2023-04-11T14:21:12+05:30 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 (cherry picked from commit 6206cb9287f3f6e70c669660a646a65274870d2b) - - - - - de176808 by Simon Peyton Jones at 2023-04-11T14:21:12+05:30 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. (cherry picked from commit 964284fcab6e27fe2fa5c279ea008551cbc15dbb) - - - - - 60fe05c6 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - a727929a by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 7afce0a4 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 1de84de2 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 98d49908 by Ben Gamari at 2023-04-11T14:21:12+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - f8e88ac9 by Andreas Klebinger at 2023-04-11T14:21:12+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - 6a8c8153 by Ryan Scott at 2023-04-11T14:21:12+05:30 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` (cherry picked from commit de1d15127ac3f41ac3044215b0ea3398a36edc89) - - - - - 3e737ee4 by Tamar Christina at 2023-04-11T14:21:12+05:30 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. (cherry picked from commit 48e391952c17ff7eab10b0b1456e3f2a2af28a9b) - - - - - 93dce14f by Ben Gamari at 2023-04-11T14:21:12+05:30 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - 6b286fe2 by Zubin Duggal at 2023-04-11T14:21:13+05:30 base: Remove HAVE_* CPP guards - - - - - 697e9f16 by Zubin Duggal at 2023-04-11T14:21:13+05:30 lint-notes: accept output - - - - - 9e24ef67 by Ben Gamari at 2023-04-11T14:21:13+05:30 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit 78d04cfadfd728bb088b08b1e88905b43cc0360c) - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Match.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf44469945d4059d70127c22372b9c2170dc9a34...9e24ef678d655f826d1567b95801b2305eff566d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf44469945d4059d70127c22372b9c2170dc9a34...9e24ef678d655f826d1567b95801b2305eff566d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 09:34:49 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 05:34:49 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] ci: debug Message-ID: <643529b961616_35453011852582983c@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: c4ae751e by Zubin Duggal at 2023-04-11T15:04:37+05:30 ci: debug - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -268,6 +268,7 @@ lint-ci-config: - cp -Rf cabal-cache/* ~/.cabal || true script: - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#cabal-install nixpkgs#ghc -c cabal update + - cat /root/.cabal/config - .gitlab/generate_jobs # 1 if .gitlab/generate_jobs changed the output of the generated config - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#git -c git diff --exit-code View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4ae751eea90867fa22ecb14407c6830c99ef234 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4ae751eea90867fa22ecb14407c6830c99ef234 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 09:47:59 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 05:47:59 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] ci: lint-ci-config: remove line metioning nix from cabal.config Message-ID: <64352ccfe3115_3545301635ec4307a9@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 65a9d023 by Zubin Duggal at 2023-04-11T15:17:46+05:30 ci: lint-ci-config: remove line metioning nix from cabal.config - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -268,7 +268,7 @@ lint-ci-config: - cp -Rf cabal-cache/* ~/.cabal || true script: - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#cabal-install nixpkgs#ghc -c cabal update - - cat /root/.cabal/config + - sed -i "/nix:/d" /root/.cabal/config - .gitlab/generate_jobs # 1 if .gitlab/generate_jobs changed the output of the generated config - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#git -c git diff --exit-code View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/65a9d0230d912dd023642abd778e9edb55368b88 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/65a9d0230d912dd023642abd778e9edb55368b88 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 10:01:03 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Apr 2023 06:01:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/spj-add-nospec-notes Message-ID: <64352fdfaf95a_35453018749ec333c2@gitlab.mail> Simon Peyton Jones pushed new branch wip/spj-add-nospec-notes at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/spj-add-nospec-notes You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 10:06:56 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 06:06:56 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] 13 commits: GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) Message-ID: <6435314064617_35453018a3e2c36890@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - fd18dfce by Josh Meredith at 2023-04-11T10:01:35+00:00 JS: fix bounds checking (Issue 23123) * For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. * Range-based operations must also check both the start and end of the range for bounds * All indicies are valid for ranges of size zero, since they are essentially no-ops * For case ByteArray accesses (e.g. read as Int), the end index is (i * sizeof(type) + sizeof(type) - 1), while the previous implementation uses (i + sizeof(type) - 1). In the Int32 example, this is (i * 4 + 3). - - - - - 30 changed files: - compiler/GHC/Core/Unify.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Name/Reader.hs - docs/users_guide/using-warnings.rst - libraries/base/GHC/Base.hs - libraries/base/changelog.md - libraries/ghci/GHCi/RemoteTypes.hs - rts/include/rts/storage/ClosureMacros.h - testsuite/tests/backpack/should_fail/bkpfail29.stderr - testsuite/tests/codeGen/should_fail/all.T - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/ghc-e/should_fail/ghc-e-fail2.stderr - testsuite/tests/module/mod27.stderr - + testsuite/tests/rename/should_compile/T23240.hs - + testsuite/tests/rename/should_compile/T23240_aux.hs - testsuite/tests/rename/should_compile/all.T - + testsuite/tests/simplCore/should_run/T23134.hs - + testsuite/tests/simplCore/should_run/T23134.stdout - testsuite/tests/simplCore/should_run/all.T - + testsuite/tests/th/T23203.hs - + testsuite/tests/th/T23203.stderr - testsuite/tests/th/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/db5327f085b84f3a296d7347b63af6394dae026a...fd18dfce7a11270ef7cfc25da96b88d9a47db57b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/db5327f085b84f3a296d7347b63af6394dae026a...fd18dfce7a11270ef7cfc25da96b88d9a47db57b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 10:28:07 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 06:28:07 -0400 Subject: [Git][ghc/ghc][wip/js-exports] 115 commits: Simplifier: `countValArgs` should not count Type args (#23102) Message-ID: <64353637ee532_35453020106d83732b@gitlab.mail> Josh Meredith pushed to branch wip/js-exports at Glasgow Haskell Compiler / GHC Commits: 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - ffb4fc49 by Josh Meredith at 2023-04-11T10:27:20+00:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65129449323bbd723a8ffbab480187de6af77c61...ffb4fc49cc57c411dcd2d83f8b5e6c3fb48923b7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65129449323bbd723a8ffbab480187de6af77c61...ffb4fc49cc57c411dcd2d83f8b5e6c3fb48923b7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 11:15:31 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 11 Apr 2023 07:15:31 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 50 commits: hadrian bindist: Install manpages to share/man/man1/ghc.1 Message-ID: <64354153ce2c5_354530306fe98413a3@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 5a278522 by Matthew Pickering at 2023-04-11T16:44:41+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - b43896ea by Matthew Pickering at 2023-04-11T16:44:41+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 59214122 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - e6ec408e by Matthew Pickering at 2023-04-11T16:44:41+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 52be078b by Matthew Pickering at 2023-04-11T16:44:41+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 54010624 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 64a60b3d by Matthew Pickering at 2023-04-11T16:44:41+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 429c8d2d by Matthew Pickering at 2023-04-11T16:44:41+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - babd33d9 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 3b0d9f8c by Matthew Pickering at 2023-04-11T16:44:41+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 375fae2f by Simon Peyton Jones at 2023-04-11T16:44:41+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - f2f46364 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - b22e4bda by Matthew Pickering at 2023-04-11T16:44:41+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - d3768c41 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - b7ebc474 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 744464c3 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 53c4d24f by Krzysztof Gogolewski at 2023-04-11T16:44:42+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - bbfe16dc by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - dd847c14 by sheaf at 2023-04-11T16:44:42+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - 3247e44a by Sylvain Henry at 2023-04-11T16:44:42+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - 35b059d8 by Sylvain Henry at 2023-04-11T16:44:42+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 9e07003f by Sylvain Henry at 2023-04-11T16:44:42+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - 69ab7f35 by Sylvain Henry at 2023-04-11T16:44:42+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 5e102834 by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - ddf602f0 by Ben Gamari at 2023-04-11T16:44:42+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - 60372935 by Ben Gamari at 2023-04-11T16:44:42+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - 5d036a5a by Ben Gamari at 2023-04-11T16:44:42+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 98b09661 by Li-yao Xia at 2023-04-11T16:44:42+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - 850c5ad3 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - b9d38595 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - 7d9de292 by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - b64260bc by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - 55392bee by Ben Gamari at 2023-04-11T16:44:42+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - 98f45e6f by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise (cherry picked from commit 7192ef91c855e1fae6997f75cfde76aafd0b4bcf) - - - - - 29236f70 by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 (cherry picked from commit 6206cb9287f3f6e70c669660a646a65274870d2b) - - - - - 602bc279 by Simon Peyton Jones at 2023-04-11T16:44:43+05:30 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. (cherry picked from commit 964284fcab6e27fe2fa5c279ea008551cbc15dbb) - - - - - 9de197b8 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 36611c83 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 874d956b by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 00797e00 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 69644eb3 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - ece2324c by Andreas Klebinger at 2023-04-11T16:44:43+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - c6b63a85 by Ryan Scott at 2023-04-11T16:44:43+05:30 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` (cherry picked from commit de1d15127ac3f41ac3044215b0ea3398a36edc89) - - - - - eaeaa979 by Tamar Christina at 2023-04-11T16:44:43+05:30 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. (cherry picked from commit 48e391952c17ff7eab10b0b1456e3f2a2af28a9b) - - - - - 0b7e51ce by Ben Gamari at 2023-04-11T16:44:43+05:30 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - 08bc1d16 by Zubin Duggal at 2023-04-11T16:44:43+05:30 base: Remove HAVE_* CPP guards - - - - - ded80fd0 by Zubin Duggal at 2023-04-11T16:44:43+05:30 lint-notes: accept output - - - - - 81fff329 by Ben Gamari at 2023-04-11T16:44:44+05:30 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit 78d04cfadfd728bb088b08b1e88905b43cc0360c) - - - - - 962acddb by Zubin Duggal at 2023-04-11T16:44:44+05:30 ci: debug - - - - - 02e1f7a1 by Zubin Duggal at 2023-04-11T16:44:44+05:30 ci: lint-ci-config: remove line metioning nix from cabal.config - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Match.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65a9d0230d912dd023642abd778e9edb55368b88...02e1f7a104f7aae90da19bcc3e74f15cdd582d86 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65a9d0230d912dd023642abd778e9edb55368b88...02e1f7a104f7aae90da19bcc3e74f15cdd582d86 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 12:09:23 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Tue, 11 Apr 2023 08:09:23 -0400 Subject: [Git][ghc/ghc][wip/spj-add-nospec-notes] Clarify a couple of Notes about 'nospec' Message-ID: <64354df3e404_3545303ad006851995@gitlab.mail> Simon Peyton Jones pushed to branch wip/spj-add-nospec-notes at Glasgow Haskell Compiler / GHC Commits: 843eda05 by Simon Peyton Jones at 2023-04-11T13:10:49+01:00 Clarify a couple of Notes about 'nospec' - - - - - 2 changed files: - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -849,8 +849,10 @@ Here are the moving parts: * `GHC.HsToCore.Binds.dsHsWrapper` desugars the evidence application (f d) into (nospec f d) if `d` is incoherent. It has to do a dependency analysis to - determine transitive dependencies, but we need to do that anway. + determine transitive dependencies, but we need to do that anyway. See Note [Desugaring incoherent evidence] in GHC.HsToCore.Binds. + + See also Note [nospecId magic] in GHC.Types.Id.Make. -} type DFunInstType = Maybe Type ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -2002,10 +2002,15 @@ Note that this happens *after* unfoldings are exposed in the interface file. This is crucial: otherwise, we could import an unfolding in which 'nospec' has been inlined (= erased), and we would lose the benefit. -'nospec' is used in the implementation of 'withDict': we insert 'nospec' -so that the typeclass specialiser doesn't assume any two evidence terms -of the same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, -and see test case T21575b for an example. +'nospec' is used: + +* In the implementation of 'withDict': we insert 'nospec' so that the + typeclass specialiser doesn't assume any two evidence terms of the + same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, + and see test case T21575b for an example. + +* To defeat the specialiser when we have incoherent instances. + See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. Note [The oneShot function] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/843eda05bc82dee0882750542d866dee52160c93 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/843eda05bc82dee0882750542d866dee52160c93 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 12:22:47 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 08:22:47 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] Apply 1 suggestion(s) to 1 file(s) Message-ID: <64355117b603b_35453041df6105624c@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: 243bb9f9 by Sylvain Henry at 2023-04-11T12:22:45+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - compiler/GHC/StgToJS/Prim.hs Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1466,22 +1466,45 @@ newByteArray :: JExpr -> JExpr -> JStat newByteArray tgt len = tgt |= app "h$newByteArray" [len] -boundsChecked :: Bool -- ^ Should we do bounds checking? - -> JExpr -- ^ Array - -> JExpr -- ^ Index - -> JStat -- ^ Result - -> JStat -boundsChecked False _ _ r = r -boundsChecked True xs i r = - ifS ((i .>=. zero_) .&&. (i .<. xs .^ "length")) r $ +boundsChecked' + :: JExpr -- ^ Max index expression + -> Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsChecked' _ False _ r = r +boundsChecked' max_index True i r = + ifS ((i .>=. zero_) .&&. (i .<. max_index)) r $ returnS (app "h$exitProcess" [Int 134]) -boundsCheckedRangeLen :: Bool - -> JExpr - -> JExpr - -> JExpr - -> JStat - -> JStat +-- | Bounds checking using ".length" property (Arrays) +boundsChecked + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsChecked do_check arr = boundsChecked' (arr .^ "length") do_check + +-- | Bounds checking using ".len" property (ByteArrays) +boundsCheckedLen + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsCheckedLen do_check arr = boundsChecked' (arr .^ "len") do_check + +-- | Bounds checking on a range and using ".len" property (ByteArrays) +-- +-- Empty ranges trivially pass the check +boundsCheckedRangeLen + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JExpr -- ^ Range size + -> JStat -- ^ Result + -> JStat boundsCheckedRangeLen False _ _ _ r = r boundsCheckedRangeLen True xs i n r = ifS (n .<. zero_) (returnS $ app "h$exitProcess" [Int 134]) $ @@ -1490,17 +1513,6 @@ boundsCheckedRangeLen True xs i n r = (boundsCheckedLen True xs (Add i (Sub n 1)) (boundsCheckedLen True xs i r)) -boundsCheckedLen :: Bool -- ^ Should we do bounds checking? - -> JExpr -- ^ Array - -> JExpr -- ^ Index - -> JStat -- ^ Result - -> JStat -boundsCheckedLen False _ _ r = r -boundsCheckedLen True xs i r = - -- Byte arrays use `len` - ifS ((i .>=. zero_) .&&. (i .<. xs .^ "len")) r $ - returnS (app "h$exitProcess" [Int 134]) - byteIndex16 :: JExpr -> JExpr byteIndex16 i = Add 1 (Mul 2 i) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/243bb9f956df8b249d811ffd8a8772406409a970 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/243bb9f956df8b249d811ffd8a8772406409a970 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 12:43:09 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Apr 2023 08:43:09 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 2 commits: Use relaxed accesses in ticky bumping Message-ID: <643555dd513ac_3545304854fa4623c7@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 73c0e306 by Ben Gamari at 2023-04-11T08:28:58-04:00 Use relaxed accesses in ticky bumping - - - - - ec7473e2 by Ben Gamari at 2023-04-11T08:42:23-04:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - 17 changed files: - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/StgToCmm/Utils.hs - rts/Apply.cmm - rts/Compact.cmm - rts/Heap.c - rts/Interpreter.c - rts/PrimOps.cmm - rts/StableName.c - rts/StgMiscClosures.cmm - rts/ThreadPaused.c - rts/Threads.c - rts/Updates.cmm - rts/Updates.h - rts/include/stg/SMP.h - rts/sm/NonMovingMark.c - utils/genapply/Main.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -702,11 +702,19 @@ emitBlackHoleCode node = do when eager_blackholing $ do whenUpdRemSetEnabled $ emitUpdRemSetPushThunk node - emitStore (cmmOffsetW platform node (fixedHdrSizeW profile)) (currentTSOExpr platform) + emitAtomicStore platform OrderingSeqCst + (cmmOffsetW platform node (fixedHdrSizeW profile)) + (currentTSOExpr platform) -- See Note [Heap memory barriers] in SMP.h. - let w = wordWidth platform - emitPrimCall [] (MO_AtomicWrite w MemOrderRelease) - [node, CmmReg (CmmGlobal $ GlobalRegUse EagerBlackholeInfo $ bWord platform)] + emitAtomicStore platform OrderingRelaxed + node + (CmmReg (CmmGlobal $ GlobalRegUse EagerBlackholeInfo $ bWord platform)) + +emitAtomicStore :: Platform -> MemoryOrdering -> CmmExpr -> CmmExpr -> FCode () +emitAtomicStore platform mord addr val = + emitPrimCall [] (MO_AtomicWrite w mord) [addr, val] + where + w = typeWidth $ cmmExprType platform val setupUpdate :: ClosureInfo -> LocalReg -> FCode () -> FCode () -- Nota Bene: this function does not change Node (even if it's a CAF), ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -829,25 +829,34 @@ bumpTickyLit :: CmmLit -> FCode () bumpTickyLit lhs = bumpTickyLitBy lhs 1 bumpTickyLitBy :: CmmLit -> Int -> FCode () -bumpTickyLitBy lhs n = do - platform <- getPlatform - emit (addToMem (bWord platform) (CmmLit lhs) n) +bumpTickyLitBy lhs n = emitAddToMem (CmmLit lhs) n bumpTickyLitByE :: CmmLit -> CmmExpr -> FCode () -bumpTickyLitByE lhs e = do - platform <- getPlatform - emit (addToMemE (bWord platform) (CmmLit lhs) e) +bumpTickyLitByE lhs e = emitAddToMemE (CmmLit lhs) e bumpHistogram :: FastString -> Int -> FCode () bumpHistogram lbl n = do platform <- getPlatform let offset = n `min` (pc_TICKY_BIN_COUNT (platformConstants platform) - 1) - emit (addToMem (bWord platform) - (cmmIndexExpr platform + let addr = + cmmIndexExpr platform (wordWidth platform) (CmmLit (CmmLabel (mkRtsCmmDataLabel lbl))) - (CmmLit (CmmInt (fromIntegral offset) (wordWidth platform)))) - 1) + (CmmLit (CmmInt (fromIntegral offset) (wordWidth platform))) + emitAddToMem addr 1 + +emitAddToMem :: CmmExpr -> Int -> FCode () +emitAddToMem lhs n = do + platform <- getPlatform + emitAddToMemE lhs (mkIntExpr platform n) + +emitAddToMemE :: CmmExpr -> CmmExpr -> FCode () +emitAddToMemE lhs n = do + platform <- getPlatform + val <- newTemp (bWord platform) + emitAtomicRead MemOrderRelaxed val lhs + let val' = cmmOffsetExpr platform (CmmReg (CmmLocal val)) n + emitAtomicWrite MemOrderRelaxed lhs val' ------------------------------------------------------------------ -- Showing the "type category" for ticky-ticky profiling ===================================== compiler/GHC/StgToCmm/Utils.hs ===================================== @@ -37,6 +37,7 @@ module GHC.StgToCmm.Utils ( cmmUntag, cmmIsTagged, addToMem, addToMemE, addToMemLblE, addToMemLbl, + emitAtomicRead, emitAtomicWrite, -- * Update remembered set operations whenUpdRemSetEnabled, @@ -59,6 +60,7 @@ import GHC.Platform.Regs import GHC.Cmm.CLabel import GHC.Cmm.Utils import GHC.Cmm.Switch +import {-# SOURCE #-} GHC.StgToCmm.Foreign (emitPrimCall) import GHC.StgToCmm.CgUtils import GHC.Types.ForeignCall @@ -118,6 +120,29 @@ addToMemE :: CmmType -- rep of the counter addToMemE rep ptr n = mkStore ptr (CmmMachOp (MO_Add (typeWidth rep)) [CmmLoad ptr rep NaturallyAligned, n]) +------------------------------------------------------------------------- +-- Atomic loads and stores +------------------------------------------------------------------------- + +emitAtomicRead + :: MemoryOrdering + -> LocalReg -- ^ result register + -> CmmExpr -- ^ address + -> FCode () +emitAtomicRead mord res addr + = void $ emitPrimCall [res] (MO_AtomicRead w mord) [addr] + where + w = typeWidth $ localRegType res + +emitAtomicWrite + :: MemoryOrdering + -> CmmExpr -- ^ address + -> CmmExpr -- ^ value + -> FCode () +emitAtomicWrite mord addr val + = do platform <- getPlatform + let w = typeWidth $ cmmExprType platform val + void $ emitPrimCall [] (MO_AtomicWrite w mord) [addr, val] ------------------------------------------------------------------------- -- ===================================== rts/Apply.cmm ===================================== @@ -108,7 +108,7 @@ again: IND, IND_STATIC: { - fun = StgInd_indirectee(fun); + fun = %acquire StgInd_indirectee(fun); goto again; } case BCO: @@ -693,7 +693,7 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK") } // Can't add StgInd_indirectee(ap) to UpdRemSet here because the old value is // not reachable. - StgInd_indirectee(ap) = CurrentTSO; + %release StgInd_indirectee(ap) = CurrentTSO; SET_INFO_RELEASE(ap, __stg_EAGER_BLACKHOLE_info); /* ensure there is at least AP_STACK_SPLIM words of headroom available ===================================== rts/Compact.cmm ===================================== @@ -100,7 +100,7 @@ eval: // Follow indirections: case IND, IND_STATIC: { - p = StgInd_indirectee(p); + p = %acquire StgInd_indirectee(p); goto eval; } ===================================== rts/Heap.c ===================================== @@ -173,7 +173,7 @@ StgWord collect_pointers(StgClosure *closure, StgClosure *ptrs[]) { case IND: case IND_STATIC: case BLACKHOLE: - ptrs[nptrs++] = (StgClosure *)(((StgInd *)closure)->indirectee); + ptrs[nptrs++] = (StgClosure *) ACQUIRE_LOAD(&((StgInd *)closure)->indirectee); break; case MUT_ARR_PTRS_CLEAN: ===================================== rts/Interpreter.c ===================================== @@ -401,7 +401,7 @@ eval_obj: case IND: case IND_STATIC: { - tagged_obj = ((StgInd*)obj)->indirectee; + tagged_obj = ACQUIRE_LOAD(&((StgInd*)obj)->indirectee); goto eval_obj; } ===================================== rts/PrimOps.cmm ===================================== @@ -1770,7 +1770,7 @@ loop: qinfo = GET_INFO_ACQUIRE(q); if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -1838,7 +1838,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -1940,7 +1940,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -2029,7 +2029,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -2309,7 +2309,7 @@ loop: //Possibly IND added by removeFromMVarBlockedQueue if (StgHeader_info(q) == stg_IND_info || StgHeader_info(q) == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } ===================================== rts/StableName.c ===================================== @@ -156,11 +156,11 @@ removeIndirections (StgClosure* p) switch (get_itbl(q)->type) { case IND: case IND_STATIC: - p = ((StgInd *)q)->indirectee; + p = ACQUIRE_LOAD(&((StgInd *)q)->indirectee); continue; case BLACKHOLE: - p = ((StgInd *)q)->indirectee; + p = ACQUIRE_LOAD(&((StgInd *)q)->indirectee); if (GET_CLOSURE_TAG(p) != 0) { continue; } else { ===================================== rts/StgMiscClosures.cmm ===================================== @@ -521,8 +521,8 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") (P_ node) { TICK_ENT_DYN_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - node = UNTAG(StgInd_indirectee(node)); + node = %acquire StgInd_indirectee(node); + node = UNTAG(node); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(node) (node); } @@ -530,8 +530,9 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") /* explicit stack */ { TICK_ENT_DYN_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - R1 = UNTAG(StgInd_indirectee(R1)); + P_ p; + p = %acquire StgInd_indirectee(R1); + R1 = UNTAG(p); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(R1) [R1]; } @@ -541,8 +542,9 @@ INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC") /* explicit stack */ { TICK_ENT_STATIC_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - R1 = UNTAG(StgInd_indirectee(R1)); + P_ p; + p = %acquire StgInd_indirectee(R1); + R1 = UNTAG(p); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(R1) [R1]; } @@ -567,8 +569,7 @@ INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE") retry: // Synchronizes with the release-store in updateWithIndirection. // See Note [Heap memory barriers] in SMP.h. - ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info); - p = %relaxed StgInd_indirectee(node); + p = %acquire StgInd_indirectee(node); if (GETTAG(p) != 0) { return (p); } ===================================== rts/ThreadPaused.c ===================================== @@ -352,7 +352,7 @@ threadPaused(Capability *cap, StgTSO *tso) OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info))); // The payload of the BLACKHOLE points to the TSO - ((StgInd *)bh)->indirectee = (StgClosure *)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: ===================================== rts/Threads.c ===================================== @@ -437,7 +437,7 @@ checkBlockingQueues (Capability *cap, StgTSO *tso) p = UNTAG_CLOSURE(bq->bh); const StgInfoTable *pinfo = ACQUIRE_LOAD(&p->header.info); if (pinfo != &stg_BLACKHOLE_info || - ((StgInd *)p)->indirectee != (StgClosure*)bq) + (RELAXED_LOAD(&((StgInd *)p)->indirectee) != (StgClosure*)bq)) { wakeBlockingQueue(cap,bq); } ===================================== rts/Updates.cmm ===================================== @@ -59,7 +59,7 @@ INFO_TABLE_RET ( stg_marked_upd_frame, UPDATE_FRAME, ASSERT(HpAlloc == 0); // Note [HpAlloc] // we know the closure is a BLACKHOLE - v = StgInd_indirectee(updatee); + v = %acquire StgInd_indirectee(updatee); if (GETTAG(v) != 0) (likely: False) { // updated by someone else: discard our value and use the ===================================== rts/Updates.h ===================================== @@ -59,8 +59,8 @@ } \ \ OVERWRITING_CLOSURE(p1); \ - %relaxed StgInd_indirectee(p1) = p2; \ - SET_INFO_RELEASE(p1, stg_BLACKHOLE_info); \ + %release StgInd_indirectee(p1) = p2; \ + %relaxed SET_INFO(p1, stg_BLACKHOLE_info); \ LDV_RECORD_CREATE(p1); \ and_then; ===================================== rts/include/stg/SMP.h ===================================== @@ -178,6 +178,7 @@ EXTERN_INLINE void load_load_barrier(void); * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgTSO: block_info + * - StgInd: indirectee * * Writing to a mutable pointer field must be done via a release-store. * Reading from such a field is done via an acquire-load. @@ -222,9 +223,9 @@ EXTERN_INLINE void load_load_barrier(void); * can see the indirectee. Consequently, a thunk update (see rts/Updates.h) * does the following: * - * 1. Use a relaxed-store to place the new indirectee into the thunk's + * 1. Use a release-store to place the new indirectee into the thunk's * indirectee field - * 2. use a release-store to set the info table to stg_BLACKHOLE (which + * 2. use a relaxed-store to set the info table to stg_BLACKHOLE (which * represents an indirection) * * Blackholing a thunk (either eagerly, by GHC.StgToCmm.Bind.emitBlackHoleCode, @@ -237,13 +238,10 @@ EXTERN_INLINE void load_load_barrier(void); * 1. We jump into the entry code of the indirection (e.g. stg_BLACKHOLE); * this of course implies that we have already read the thunk's info table * pointer, which is done with a relaxed load. - * 2. use an acquire-fence to ensure that our view on the thunk is - * up-to-date. This synchronizes with step (2) in the update - * procedure. - * 3. relaxed-load the indirectee. Since thunks are updated at most + * 2. acquire-load the indirectee. Since thunks are updated at most * once we know that the fence in the last step has given us * an up-to-date view of the indirectee closure. - * 4. enter the indirectee (or block if the indirectee is a TSO) + * 3. enter the indirectee (or block if the indirectee is a TSO) * * Other closures * -------------- @@ -270,7 +268,7 @@ EXTERN_INLINE void load_load_barrier(void); * in this primops. * * - Sending a Message to another capability: - * This is protected by the acquition and release of the target capability's + * This is protected by the acquision and release of the target capability's * lock in Messages.c:sendMessage. * * N.B. recordClosureMutated places a reference to the mutated object on ===================================== rts/sm/NonMovingMark.c ===================================== @@ -681,8 +681,9 @@ void updateRemembSetPushThunkEager(Capability *cap, case IND: { StgInd *ind = (StgInd *) thunk; - if (check_in_nonmoving_heap(ind->indirectee)) { - push_closure(queue, ind->indirectee, NULL); + StgClosure *indirectee = ACQUIRE_LOAD(&ind->indirectee); + if (check_in_nonmoving_heap(indirectee)) { + push_closure(queue, indirectee, NULL); } break; } ===================================== utils/genapply/Main.hs ===================================== @@ -783,7 +783,11 @@ genApply regstatus args = text "case IND,", text " IND_STATIC: {", nest 4 (vcat [ - text "R1 = StgInd_indirectee(R1);", + -- N.B. annoyingly the %acquire syntax must place its result in a local register + -- as it is a Cmm prim call node. + text "P_ p;", + text "p = %acquire StgInd_indirectee(R1);", + text "R1 = p;", -- An indirection node might contain a tagged pointer text "goto again;" ]), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61646bbd8f67f97daa96c7450c00f2511d5ac1f7...ec7473e25d148e2386ca9bfe35c32e727cdea615 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61646bbd8f67f97daa96c7450c00f2511d5ac1f7...ec7473e25d148e2386ca9bfe35c32e727cdea615 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 14:26:02 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 11 Apr 2023 10:26:02 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] Revert bounds checking end index for JavaScript IndexByteArrayOp_Word8As*... Message-ID: <64356dfa922bc_35453063aa0d8897ef@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: 53fbf777 by Josh Meredith at 2023-04-11T14:25:43+00:00 Revert bounds checking end index for JavaScript IndexByteArrayOp_Word8As* primitives and add start indicies - - - - - 1 changed file: - compiler/GHC/StgToJS/Prim.hs Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -1031,8 +1031,8 @@ genPrim prof bound ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -1043,32 +1043,32 @@ genPrim prof bound ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_boff_f64 a i + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_boff_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_boff_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -1079,32 +1079,32 @@ genPrim prof bound ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_boff_f64 a i + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_boff_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_boff_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_boff_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty @@ -1112,11 +1112,11 @@ genPrim prof bound ty op = case op of a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ write_boff_f64 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_boff_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e2 + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i -- then write the higher 4 bytes to i+4 @@ -1124,15 +1124,15 @@ genPrim prof bound ty op = case op of $ mconcat [ write_boff_i32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_boff_u16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ write_boff_u32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ casOp read_i32 write_i32 r a i old new CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a i $ casOp read_i8 write_i8 r a i old new View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53fbf7770b7199397be405e5d13708722285d15e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53fbf7770b7199397be405e5d13708722285d15e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 18:27:49 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 11 Apr 2023 14:27:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/lfinfo-for-nullary-wrappers Message-ID: <6435a6a53032a_354530a5c02d81401c6@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/lfinfo-for-nullary-wrappers at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/lfinfo-for-nullary-wrappers You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 18:59:43 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 11 Apr 2023 14:59:43 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <6435ae1f69fa6_354530ae10820146534@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 14d53950 by Sebastian Graf at 2023-04-11T20:57:25+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 7 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/stranal/should_compile/T18894.stderr - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,33 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> PlusDmdArg + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = keepAlive env (filter is_root ids) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +keepAlive :: AnalEnv -> [Id] -> PlusDmdArg +-- See Note [Absence analysis for stable unfoldings and RULES] +keepAlive _ [] = (emptyVarEnv, topDiv) +keepAlive env ids + = foldl1' plusDmdArg $ fmap (fst . dmdAnalStar env topDmd . Var) ids + +keepAliveSet :: AnalEnv -> IdSet -> PlusDmdArg +keepAliveSet env ids = keepAlive env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +348,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` keepAliveSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -415,7 +420,7 @@ dmdAnalStar env (n :* sd) e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -532,7 +537,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +574,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1103,7 +1108,8 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs NonRecursive -> rhs_fv -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + -- Since the result of keepAliveSet will have topDiv, rhs_div == _rhs_div' + (rhs_fv2, _rhs_div') = (rhs_fv1, rhs_div) `plusDmdArg` keepAliveSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 @@ -1365,8 +1371,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to do +absence analysis for stable unfoldings. Consider g = blah @@ -1383,9 +1389,8 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. +SOLUTION: if f has a stable unfolding, analyse every free variable as if it +was a variable occuring in a 'topDmd' context. This is done in `keepAlive`. ALSO: do the same for Ids free in the RHS of any RULES for f. @@ -1401,6 +1406,28 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +PPS: You might wonder why we don't simply take the free vars of the +unfolding/RULE and map them to topDmd. The reason is that any of the free vars +might have demand signatures themselves that in turn keep transitive free +variables alive and that we hence need to unleash! This came up in #23208. +Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + +Here, `err` is only kept alive by `sg`'s demand signature: It doesn't occur +in the lazy_fvs of `sg`'s RHS at all. Hence when we `keepAlive` `sg` because it +occurs in the RULEs of `g` (which is exported), we better unleash the demand +signature of `sg`, too! In #23208 we failed to do so and observed an absent +error instead of the `really important message`. + Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We give DataCon wrappers a (necessarily flat) demand signature in ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -44,8 +44,7 @@ module GHC.Types.Demand ( unboxDeeplyDmd, -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, + DmdEnv, emptyDmdEnv, reuseEnv, -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, @@ -56,10 +55,9 @@ module GHC.Types.Demand ( nopDmdType, botDmdType, lubDmdType, plusDmdType, multDmdType, -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + PlusDmdArg, mkPlusDmdArg, discardArgDmds, plusDmdArg, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +83,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1466,7 +1463,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1750,23 +1747,6 @@ multDmdEnv n env = mapVarEnv (multDmd n) env reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd - - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd - -- | Characterises how an expression -- -- * Evaluates its free variables ('dt_env') @@ -1811,20 +1791,27 @@ type PlusDmdArg = (DmdEnv, Divergence) mkPlusDmdArg :: DmdEnv -> PlusDmdArg mkPlusDmdArg env = (env, topDiv) -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) +discardArgDmds :: DmdType -> PlusDmdArg +discardArgDmds (DmdType fv _ r) = (fv, r) plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient +plusDmdType (DmdType fv ds d) pda + -- See Note [Asymmetry of plusDmdType] + -- 'plus' takes the argument demands from its *first* arg, using its second + -- arg just for its free-var info and divergence. + | (fv', d') <- plusDmdArg (fv,d) pda + = DmdType fv' ds d' + +plusDmdArg :: PlusDmdArg -> PlusDmdArg -> PlusDmdArg +plusDmdArg (fv1, d1) (fv2, d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = (fv1, d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = (fv2, d1 `plusDivergence` d2) -- another very common case that is much more efficient | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) + = ( plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + , d1 `plusDivergence` d2) botDmdType :: DmdType botDmdType = DmdType emptyDmdEnv [] botDiv @@ -1914,11 +1901,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1999,7 +1981,7 @@ Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14d53950b9314842b3665ea2d953334a27a6698d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14d53950b9314842b3665ea2d953334a27a6698d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 20:34:50 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 16:34:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add support for -debug in the testsuite Message-ID: <6435c46ac48b7_354530c744d2815761a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 08567a83 by Krzysztof Gogolewski at 2023-04-11T16:34:37-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - d415ffa2 by Krzysztof Gogolewski at 2023-04-11T16:34:37-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - fd75e294 by Cheng Shao at 2023-04-11T16:34:38-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - f2484e92 by Cheng Shao at 2023-04-11T16:34:39-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - 8500bf14 by Bodigrim at 2023-04-11T16:34:42-04:00 Set base 'maintainer' field to CLC - - - - - e6ab90e6 by Simon Peyton Jones at 2023-04-11T16:34:42-04:00 Clarify a couple of Notes about 'nospec' - - - - - 17 changed files: - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Wasm/ControlFlow/FromCmm.hs - hadrian/src/Oracles/TestSettings.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/base.cabal - rts/Printer.c - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/ghc-config/ghc-config.hs - testsuite/mk/test.mk - testsuite/tests/rts/Makefile - + testsuite/tests/rts/T23142.hs - + testsuite/tests/rts/T23142.stdout - testsuite/tests/rts/all.T Changes: ===================================== compiler/GHC/CmmToAsm/Wasm/FromCmm.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Types.ForeignCall import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Map +import GHC.Types.Unique.Supply import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Wasm.ControlFlow.FromCmm @@ -1328,7 +1329,7 @@ lower_CmmUnsafeForeignCall_Drop :: [CmmActual] -> WasmCodeGenM w (WasmStatements w) lower_CmmUnsafeForeignCall_Drop lbl sym_callee ret_cmm_ty arg_exprs = do - ret_uniq <- wasmUniq + ret_uniq <- getUniqueM let ret_local = LocalReg ret_uniq ret_cmm_ty lower_CmmUnsafeForeignCall lbl @@ -1528,9 +1529,11 @@ lower_CmmGraph :: CLabel -> CmmGraph -> WasmCodeGenM w (FuncBody w) lower_CmmGraph lbl g = do ty_word <- wasmWordTypeM platform <- wasmPlatformM + us <- getUniqueSupplyM body <- structuredControl platform + us (\_ -> lower_CmmExpr_Typed lbl ty_word) (lower_CmmActions lbl) g ===================================== compiler/GHC/CmmToAsm/Wasm/Types.hs ===================================== @@ -45,7 +45,6 @@ module GHC.CmmToAsm.Wasm.Types wasmStateM, wasmModifyM, wasmExecM, - wasmUniq, ) where @@ -466,10 +465,18 @@ wasmStateM = coerce . State wasmModifyM :: (WasmCodeGenState w -> WasmCodeGenState w) -> WasmCodeGenM w () wasmModifyM = coerce . modify +wasmEvalM :: WasmCodeGenM w a -> WasmCodeGenState w -> a +wasmEvalM (WasmCodeGenM s) = evalState s + wasmExecM :: WasmCodeGenM w a -> WasmCodeGenState w -> WasmCodeGenState w wasmExecM (WasmCodeGenM s) = execState s -wasmUniq :: WasmCodeGenM w Unique -wasmUniq = wasmStateM $ - \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of - (u, us) -> (# u, s {wasmUniqSupply = us} #) +instance MonadUnique (WasmCodeGenM w) where + getUniqueSupplyM = wasmGetsM wasmUniqSupply + getUniqueM = wasmStateM $ + \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of + (u, us) -> (# u, s {wasmUniqSupply = us} #) + getUniquesM = do + u <- getUniqueM + s <- WasmCodeGenM get + pure $ u:(wasmEvalM getUniquesM s) ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -849,8 +849,10 @@ Here are the moving parts: * `GHC.HsToCore.Binds.dsHsWrapper` desugars the evidence application (f d) into (nospec f d) if `d` is incoherent. It has to do a dependency analysis to - determine transitive dependencies, but we need to do that anway. + determine transitive dependencies, but we need to do that anyway. See Note [Desugaring incoherent evidence] in GHC.HsToCore.Binds. + + See also Note [nospecId magic] in GHC.Types.Id.Make. -} type DFunInstType = Maybe Type ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -2002,10 +2002,15 @@ Note that this happens *after* unfoldings are exposed in the interface file. This is crucial: otherwise, we could import an unfolding in which 'nospec' has been inlined (= erased), and we would lose the benefit. -'nospec' is used in the implementation of 'withDict': we insert 'nospec' -so that the typeclass specialiser doesn't assume any two evidence terms -of the same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, -and see test case T21575b for an example. +'nospec' is used: + +* In the implementation of 'withDict': we insert 'nospec' so that the + typeclass specialiser doesn't assume any two evidence terms of the + same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, + and see test case T21575b for an example. + +* To defeat the specialiser when we have incoherent instances. + See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. Note [The oneShot function] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Wasm/ControlFlow/FromCmm.hs ===================================== @@ -19,12 +19,13 @@ import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dominators import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label +import GHC.Cmm.Reducibility import GHC.Cmm.Switch import GHC.CmmToAsm.Wasm.Types import GHC.Platform - +import GHC.Types.Unique.Supply import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable ( Outputable, text, (<+>), ppr @@ -140,15 +141,19 @@ emptyPost _ = False structuredControl :: forall expr stmt m . Applicative m => Platform -- ^ needed for offset calculation + -> UniqSupply -> (Label -> CmmExpr -> m expr) -- ^ translator for expressions -> (Label -> CmmActions -> m stmt) -- ^ translator for straight-line code -> CmmGraph -- ^ CFG to be translated -> m (WasmControl stmt expr '[] '[ 'I32]) -structuredControl platform txExpr txBlock g = +structuredControl platform us txExpr txBlock g' = doTree returns dominatorTree emptyContext where + g :: CmmGraph + g = gwd_graph gwd + gwd :: GraphWithDominators CmmNode - gwd = graphWithDominators g + gwd = initUs_ us $ asReducible $ graphWithDominators g' dominatorTree :: Tree.Tree CmmBlock-- Dominator tree in which children are sorted -- with highest reverse-postorder number first ===================================== hadrian/src/Oracles/TestSettings.hs ===================================== @@ -25,8 +25,9 @@ data TestSetting = TestHostOS | TestTARGETPLATFORM | TestTargetOS_CPP | TestTargetARCH_CPP + | TestRTSWay | TestGhcStage - | TestGhcDebugged + | TestGhcDebugAssertions | TestGhcWithNativeCodeGen | TestGhcWithInterpreter | TestGhcWithRtsLinker @@ -56,8 +57,9 @@ testSetting key = do TestTARGETPLATFORM -> "TARGETPLATFORM" TestTargetOS_CPP -> "TargetOS_CPP" TestTargetARCH_CPP -> "TargetARCH_CPP" + TestRTSWay -> "RTSWay" TestGhcStage -> "GhcStage" - TestGhcDebugged -> "GhcDebugged" + TestGhcDebugAssertions -> "GhcDebugAssertions" TestGhcWithNativeCodeGen -> "GhcWithNativeCodeGen" TestGhcWithInterpreter -> "GhcWithInterpreter" TestGhcWithRtsLinker -> "GhcWithRtsLinker" ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -69,6 +69,9 @@ data TestCompilerArgs = TestCompilerArgs{ , unregisterised :: Bool , tables_next_to_code :: Bool , targetWithSMP :: Bool -- does the target support SMP + , debugged :: Bool + -- ^ Whether the compiler has the debug RTS, + -- corresponding to the -debug option. , debugAssertions :: Bool -- ^ Whether the compiler has debug assertions enabled, -- corresponding to the -DDEBUG option. @@ -104,6 +107,7 @@ inTreeCompilerArgs stg = do let ghcStage = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage + debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage os <- setting HostOs @@ -149,12 +153,14 @@ outOfTreeCompilerArgs = do unregisterised <- getBooleanSetting TestGhcUnregisterised tables_next_to_code <- getBooleanSetting TestGhcTablesNextToCode targetWithSMP <- targetSupportsSMP - debugAssertions <- getBooleanSetting TestGhcDebugged + debugAssertions <- getBooleanSetting TestGhcDebugAssertions os <- getTestSetting TestHostOS arch <- getTestSetting TestTargetARCH_CPP platform <- getTestSetting TestTARGETPLATFORM wordsize <- getTestSetting TestWORDSIZE + rtsWay <- getTestSetting TestRTSWay + let debugged = "debug" `isInfixOf` rtsWay llc_cmd <- getTestSetting TestLLC have_llvm <- liftIO (isJust <$> findExecutable llc_cmd) @@ -243,6 +249,7 @@ runTestBuilderArgs = builder Testsuite ? do , arg "-e", arg $ "config.accept_os=" ++ show acceptOS , arg "-e", arg $ "config.exeext=" ++ quote (if null exe then "" else "."<>exe) , arg "-e", arg $ "config.compiler_debugged=" ++ show debugAssertions + , arg "-e", arg $ "config.debug_rts=" ++ show debugged -- MP: TODO, we do not need both, they get aliased to the same thing. , arg "-e", arg $ asBool "ghc_with_native_codegen=" withNativeCodeGen ===================================== libraries/base/base.cabal ===================================== @@ -5,8 +5,8 @@ version: 4.18.0.0 license: BSD-3-Clause license-file: LICENSE -maintainer: libraries at haskell.org -bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +maintainer: Core Libraries Committee +bug-reports: https://github.com/haskell/core-libraries-committee/issues synopsis: Basic libraries category: Prelude build-type: Configure ===================================== rts/Printer.c ===================================== @@ -297,6 +297,45 @@ printClosure( const StgClosure *obj ) break; } + case ATOMICALLY_FRAME: + { + StgAtomicallyFrame* u = (StgAtomicallyFrame*)obj; + debugBelch("ATOMICALLY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->result); + debugBelch(")\n"); + break; + } + + case CATCH_RETRY_FRAME: + { + StgCatchRetryFrame* u = (StgCatchRetryFrame*)obj; + debugBelch("CATCH_RETRY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->first_code); + debugBelch(","); + printPtr((StgPtr)u->alt_code); + debugBelch(")\n"); + break; + } + + case CATCH_STM_FRAME: + { + StgCatchSTMFrame* u = (StgCatchSTMFrame*)obj; + debugBelch("CATCH_STM_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->handler); + debugBelch(")\n"); + break; + } + case ARR_WORDS: { StgWord i; @@ -319,6 +358,10 @@ printClosure( const StgClosure *obj ) debugBelch("MUT_ARR_PTRS_FROZEN_CLEAN(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); break; + case MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); + break; + case SMALL_MUT_ARR_PTRS_CLEAN: debugBelch("SMALL_MUT_ARR_PTRS_CLEAN(size=%" FMT_Word ")\n", (W_)((StgSmallMutArrPtrs *)obj)->ptrs); @@ -334,6 +377,11 @@ printClosure( const StgClosure *obj ) (W_)((StgSmallMutArrPtrs *)obj)->ptrs); break; + case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("SMALL_MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", + (W_)((StgSmallMutArrPtrs *)obj)->ptrs); + break; + case MVAR_CLEAN: case MVAR_DIRTY: { @@ -533,6 +581,9 @@ printStackChunk( StgPtr sp, StgPtr spBottom ) case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: + case ATOMICALLY_FRAME: + case CATCH_RETRY_FRAME: + case CATCH_STM_FRAME: printClosure((StgClosure*)sp); continue; ===================================== testsuite/driver/testglobals.py ===================================== @@ -64,6 +64,9 @@ class TestConfig: # Was the compiler compiled with DEBUG? self.compiler_debugged = False + # Was the compiler compiled with -debug? + self.debug_rts = False + # Was the compiler compiled with LLVM? self.ghc_built_by_llvm = False ===================================== testsuite/driver/testlib.py ===================================== @@ -681,6 +681,9 @@ def compiler_profiled( ) -> bool: def compiler_debugged( ) -> bool: return config.compiler_debugged +def debug_rts( ) -> bool: + return config.debug_rts + def have_gdb( ) -> bool: return config.have_gdb ===================================== testsuite/ghc-config/ghc-config.hs ===================================== @@ -13,12 +13,13 @@ main = do getGhcFieldOrFail fields "TARGETPLATFORM" "Target platform" getGhcFieldOrFail fields "TargetOS_CPP" "Target OS" getGhcFieldOrFail fields "TargetARCH_CPP" "Target architecture" + getGhcFieldOrFail fields "RTSWay" "RTS way" info <- readProcess ghc ["--info"] "" let fields = read info :: [(String,String)] getGhcFieldOrFail fields "GhcStage" "Stage" - getGhcFieldOrFail fields "GhcDebugged" "Debug on" + getGhcFieldOrFail fields "GhcDebugAssertions" "Debug on" getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator" getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter" getGhcFieldOrFail fields "GhcWithRtsLinker" "target has RTS linker" ===================================== testsuite/mk/test.mk ===================================== @@ -78,7 +78,7 @@ endif RUNTEST_OPTS += -e "ghc_compiler_always_flags='$(TEST_HC_OPTS)'" -ifeq "$(GhcDebugged)" "YES" +ifeq "$(GhcDebugAssertions)" "YES" RUNTEST_OPTS += -e "config.compiler_debugged=True" else RUNTEST_OPTS += -e "config.compiler_debugged=False" ===================================== testsuite/tests/rts/Makefile ===================================== @@ -147,3 +147,13 @@ EventlogOutput_IPE: "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log + +.PHONY: T23142 +T23142: + # Test that the -Di output contains different frames + "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + grep -m1 -c "ATOMICALLY_FRAME" T23142.log + grep -m1 -c "CATCH_RETRY_FRAME" T23142.log + grep -m1 -c "CATCH_STM_FRAME" T23142.log + grep -m1 -c "MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log + grep -m1 -c "SMALL_MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log ===================================== testsuite/tests/rts/T23142.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE UnboxedTuples, MagicHash #-} +module T23142 where + +import GHC.IO +import GHC.Exts + +main :: IO () +main = IO (\s -> case newArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (\s -> case newSmallArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeSmallArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (atomically# (\s -> catchSTM# (\s -> (# s, () #)) (\_ s -> (# s, () #)) s)) + >> + IO (atomically# (\s -> catchRetry# (\s -> (# s, () #)) (\s -> (# s, () #)) s)) ===================================== testsuite/tests/rts/T23142.stdout ===================================== @@ -0,0 +1,5 @@ +1 +1 +1 +1 +1 ===================================== testsuite/tests/rts/all.T ===================================== @@ -575,3 +575,5 @@ test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-thr test('T22795c', [only_ways(['normal']), js_skip], compile_and_run, ['-threaded -single-threaded']) test('T17574', [js_skip], compile_and_run, ['-with-rtsopts -T']) + +test('T23142', [unless(debug_rts(), skip), req_interp], makefile_test, ['T23142']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3cf6809efb65a286349c4b453bc38ccaed03c90c...e6ab90e6a4dd8902d8f785f5e6a421f1d95cb844 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3cf6809efb65a286349c4b453bc38ccaed03c90c...e6ab90e6a4dd8902d8f785f5e6a421f1d95cb844 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 21:23:03 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 11 Apr 2023 17:23:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23247 Message-ID: <6435cfb74c061_354530d04efb8168040@gitlab.mail> Ben Gamari pushed new branch wip/T23247 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23247 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 23:25:13 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 19:25:13 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Add support for -debug in the testsuite Message-ID: <6435ec5922859_354530f01e9ec1789c3@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 11 changed files: - hadrian/src/Oracles/TestSettings.hs - hadrian/src/Settings/Builders/RunTest.hs - rts/Printer.c - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/ghc-config/ghc-config.hs - testsuite/mk/test.mk - testsuite/tests/rts/Makefile - + testsuite/tests/rts/T23142.hs - + testsuite/tests/rts/T23142.stdout - testsuite/tests/rts/all.T Changes: ===================================== hadrian/src/Oracles/TestSettings.hs ===================================== @@ -25,8 +25,9 @@ data TestSetting = TestHostOS | TestTARGETPLATFORM | TestTargetOS_CPP | TestTargetARCH_CPP + | TestRTSWay | TestGhcStage - | TestGhcDebugged + | TestGhcDebugAssertions | TestGhcWithNativeCodeGen | TestGhcWithInterpreter | TestGhcWithRtsLinker @@ -56,8 +57,9 @@ testSetting key = do TestTARGETPLATFORM -> "TARGETPLATFORM" TestTargetOS_CPP -> "TargetOS_CPP" TestTargetARCH_CPP -> "TargetARCH_CPP" + TestRTSWay -> "RTSWay" TestGhcStage -> "GhcStage" - TestGhcDebugged -> "GhcDebugged" + TestGhcDebugAssertions -> "GhcDebugAssertions" TestGhcWithNativeCodeGen -> "GhcWithNativeCodeGen" TestGhcWithInterpreter -> "GhcWithInterpreter" TestGhcWithRtsLinker -> "GhcWithRtsLinker" ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -69,6 +69,9 @@ data TestCompilerArgs = TestCompilerArgs{ , unregisterised :: Bool , tables_next_to_code :: Bool , targetWithSMP :: Bool -- does the target support SMP + , debugged :: Bool + -- ^ Whether the compiler has the debug RTS, + -- corresponding to the -debug option. , debugAssertions :: Bool -- ^ Whether the compiler has debug assertions enabled, -- corresponding to the -DDEBUG option. @@ -104,6 +107,7 @@ inTreeCompilerArgs stg = do let ghcStage = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage + debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage os <- setting HostOs @@ -149,12 +153,14 @@ outOfTreeCompilerArgs = do unregisterised <- getBooleanSetting TestGhcUnregisterised tables_next_to_code <- getBooleanSetting TestGhcTablesNextToCode targetWithSMP <- targetSupportsSMP - debugAssertions <- getBooleanSetting TestGhcDebugged + debugAssertions <- getBooleanSetting TestGhcDebugAssertions os <- getTestSetting TestHostOS arch <- getTestSetting TestTargetARCH_CPP platform <- getTestSetting TestTARGETPLATFORM wordsize <- getTestSetting TestWORDSIZE + rtsWay <- getTestSetting TestRTSWay + let debugged = "debug" `isInfixOf` rtsWay llc_cmd <- getTestSetting TestLLC have_llvm <- liftIO (isJust <$> findExecutable llc_cmd) @@ -243,6 +249,7 @@ runTestBuilderArgs = builder Testsuite ? do , arg "-e", arg $ "config.accept_os=" ++ show acceptOS , arg "-e", arg $ "config.exeext=" ++ quote (if null exe then "" else "."<>exe) , arg "-e", arg $ "config.compiler_debugged=" ++ show debugAssertions + , arg "-e", arg $ "config.debug_rts=" ++ show debugged -- MP: TODO, we do not need both, they get aliased to the same thing. , arg "-e", arg $ asBool "ghc_with_native_codegen=" withNativeCodeGen ===================================== rts/Printer.c ===================================== @@ -297,6 +297,45 @@ printClosure( const StgClosure *obj ) break; } + case ATOMICALLY_FRAME: + { + StgAtomicallyFrame* u = (StgAtomicallyFrame*)obj; + debugBelch("ATOMICALLY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->result); + debugBelch(")\n"); + break; + } + + case CATCH_RETRY_FRAME: + { + StgCatchRetryFrame* u = (StgCatchRetryFrame*)obj; + debugBelch("CATCH_RETRY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->first_code); + debugBelch(","); + printPtr((StgPtr)u->alt_code); + debugBelch(")\n"); + break; + } + + case CATCH_STM_FRAME: + { + StgCatchSTMFrame* u = (StgCatchSTMFrame*)obj; + debugBelch("CATCH_STM_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->handler); + debugBelch(")\n"); + break; + } + case ARR_WORDS: { StgWord i; @@ -319,6 +358,10 @@ printClosure( const StgClosure *obj ) debugBelch("MUT_ARR_PTRS_FROZEN_CLEAN(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); break; + case MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); + break; + case SMALL_MUT_ARR_PTRS_CLEAN: debugBelch("SMALL_MUT_ARR_PTRS_CLEAN(size=%" FMT_Word ")\n", (W_)((StgSmallMutArrPtrs *)obj)->ptrs); @@ -334,6 +377,11 @@ printClosure( const StgClosure *obj ) (W_)((StgSmallMutArrPtrs *)obj)->ptrs); break; + case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("SMALL_MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", + (W_)((StgSmallMutArrPtrs *)obj)->ptrs); + break; + case MVAR_CLEAN: case MVAR_DIRTY: { @@ -533,6 +581,9 @@ printStackChunk( StgPtr sp, StgPtr spBottom ) case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: + case ATOMICALLY_FRAME: + case CATCH_RETRY_FRAME: + case CATCH_STM_FRAME: printClosure((StgClosure*)sp); continue; ===================================== testsuite/driver/testglobals.py ===================================== @@ -64,6 +64,9 @@ class TestConfig: # Was the compiler compiled with DEBUG? self.compiler_debugged = False + # Was the compiler compiled with -debug? + self.debug_rts = False + # Was the compiler compiled with LLVM? self.ghc_built_by_llvm = False ===================================== testsuite/driver/testlib.py ===================================== @@ -681,6 +681,9 @@ def compiler_profiled( ) -> bool: def compiler_debugged( ) -> bool: return config.compiler_debugged +def debug_rts( ) -> bool: + return config.debug_rts + def have_gdb( ) -> bool: return config.have_gdb ===================================== testsuite/ghc-config/ghc-config.hs ===================================== @@ -13,12 +13,13 @@ main = do getGhcFieldOrFail fields "TARGETPLATFORM" "Target platform" getGhcFieldOrFail fields "TargetOS_CPP" "Target OS" getGhcFieldOrFail fields "TargetARCH_CPP" "Target architecture" + getGhcFieldOrFail fields "RTSWay" "RTS way" info <- readProcess ghc ["--info"] "" let fields = read info :: [(String,String)] getGhcFieldOrFail fields "GhcStage" "Stage" - getGhcFieldOrFail fields "GhcDebugged" "Debug on" + getGhcFieldOrFail fields "GhcDebugAssertions" "Debug on" getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator" getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter" getGhcFieldOrFail fields "GhcWithRtsLinker" "target has RTS linker" ===================================== testsuite/mk/test.mk ===================================== @@ -78,7 +78,7 @@ endif RUNTEST_OPTS += -e "ghc_compiler_always_flags='$(TEST_HC_OPTS)'" -ifeq "$(GhcDebugged)" "YES" +ifeq "$(GhcDebugAssertions)" "YES" RUNTEST_OPTS += -e "config.compiler_debugged=True" else RUNTEST_OPTS += -e "config.compiler_debugged=False" ===================================== testsuite/tests/rts/Makefile ===================================== @@ -147,3 +147,13 @@ EventlogOutput_IPE: "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log + +.PHONY: T23142 +T23142: + # Test that the -Di output contains different frames + "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + grep -m1 -c "ATOMICALLY_FRAME" T23142.log + grep -m1 -c "CATCH_RETRY_FRAME" T23142.log + grep -m1 -c "CATCH_STM_FRAME" T23142.log + grep -m1 -c "MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log + grep -m1 -c "SMALL_MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log ===================================== testsuite/tests/rts/T23142.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE UnboxedTuples, MagicHash #-} +module T23142 where + +import GHC.IO +import GHC.Exts + +main :: IO () +main = IO (\s -> case newArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (\s -> case newSmallArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeSmallArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (atomically# (\s -> catchSTM# (\s -> (# s, () #)) (\_ s -> (# s, () #)) s)) + >> + IO (atomically# (\s -> catchRetry# (\s -> (# s, () #)) (\s -> (# s, () #)) s)) ===================================== testsuite/tests/rts/T23142.stdout ===================================== @@ -0,0 +1,5 @@ +1 +1 +1 +1 +1 ===================================== testsuite/tests/rts/all.T ===================================== @@ -575,3 +575,5 @@ test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-thr test('T22795c', [only_ways(['normal']), js_skip], compile_and_run, ['-threaded -single-threaded']) test('T17574', [js_skip], compile_and_run, ['-with-rtsopts -T']) + +test('T23142', [unless(debug_rts(), skip), req_interp], makefile_test, ['T23142']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ba77b369a170ba68f4eb5c8f3ae13e03dcbb28d...b7474b57830261a94903da61bb2df33022c11357 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ba77b369a170ba68f4eb5c8f3ae13e03dcbb28d...b7474b57830261a94903da61bb2df33022c11357 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 23:25:49 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 19:25:49 -0400 Subject: [Git][ghc/ghc][master] 2 commits: compiler: make WasmCodeGenM an instance of MonadUnique Message-ID: <6435ec7d65361_354530f154e101841f5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - 3 changed files: - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/Wasm/ControlFlow/FromCmm.hs Changes: ===================================== compiler/GHC/CmmToAsm/Wasm/FromCmm.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Types.ForeignCall import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Map +import GHC.Types.Unique.Supply import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Wasm.ControlFlow.FromCmm @@ -1328,7 +1329,7 @@ lower_CmmUnsafeForeignCall_Drop :: [CmmActual] -> WasmCodeGenM w (WasmStatements w) lower_CmmUnsafeForeignCall_Drop lbl sym_callee ret_cmm_ty arg_exprs = do - ret_uniq <- wasmUniq + ret_uniq <- getUniqueM let ret_local = LocalReg ret_uniq ret_cmm_ty lower_CmmUnsafeForeignCall lbl @@ -1528,9 +1529,11 @@ lower_CmmGraph :: CLabel -> CmmGraph -> WasmCodeGenM w (FuncBody w) lower_CmmGraph lbl g = do ty_word <- wasmWordTypeM platform <- wasmPlatformM + us <- getUniqueSupplyM body <- structuredControl platform + us (\_ -> lower_CmmExpr_Typed lbl ty_word) (lower_CmmActions lbl) g ===================================== compiler/GHC/CmmToAsm/Wasm/Types.hs ===================================== @@ -45,7 +45,6 @@ module GHC.CmmToAsm.Wasm.Types wasmStateM, wasmModifyM, wasmExecM, - wasmUniq, ) where @@ -466,10 +465,18 @@ wasmStateM = coerce . State wasmModifyM :: (WasmCodeGenState w -> WasmCodeGenState w) -> WasmCodeGenM w () wasmModifyM = coerce . modify +wasmEvalM :: WasmCodeGenM w a -> WasmCodeGenState w -> a +wasmEvalM (WasmCodeGenM s) = evalState s + wasmExecM :: WasmCodeGenM w a -> WasmCodeGenState w -> WasmCodeGenState w wasmExecM (WasmCodeGenM s) = execState s -wasmUniq :: WasmCodeGenM w Unique -wasmUniq = wasmStateM $ - \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of - (u, us) -> (# u, s {wasmUniqSupply = us} #) +instance MonadUnique (WasmCodeGenM w) where + getUniqueSupplyM = wasmGetsM wasmUniqSupply + getUniqueM = wasmStateM $ + \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of + (u, us) -> (# u, s {wasmUniqSupply = us} #) + getUniquesM = do + u <- getUniqueM + s <- WasmCodeGenM get + pure $ u:(wasmEvalM getUniquesM s) ===================================== compiler/GHC/Wasm/ControlFlow/FromCmm.hs ===================================== @@ -19,12 +19,13 @@ import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dominators import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label +import GHC.Cmm.Reducibility import GHC.Cmm.Switch import GHC.CmmToAsm.Wasm.Types import GHC.Platform - +import GHC.Types.Unique.Supply import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable ( Outputable, text, (<+>), ppr @@ -140,15 +141,19 @@ emptyPost _ = False structuredControl :: forall expr stmt m . Applicative m => Platform -- ^ needed for offset calculation + -> UniqSupply -> (Label -> CmmExpr -> m expr) -- ^ translator for expressions -> (Label -> CmmActions -> m stmt) -- ^ translator for straight-line code -> CmmGraph -- ^ CFG to be translated -> m (WasmControl stmt expr '[] '[ 'I32]) -structuredControl platform txExpr txBlock g = +structuredControl platform us txExpr txBlock g' = doTree returns dominatorTree emptyContext where + g :: CmmGraph + g = gwd_graph gwd + gwd :: GraphWithDominators CmmNode - gwd = graphWithDominators g + gwd = initUs_ us $ asReducible $ graphWithDominators g' dominatorTree :: Tree.Tree CmmBlock-- Dominator tree in which children are sorted -- with highest reverse-postorder number first View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7474b57830261a94903da61bb2df33022c11357...05d26a650b6e9e1169b42376fe54bb00850722f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7474b57830261a94903da61bb2df33022c11357...05d26a650b6e9e1169b42376fe54bb00850722f2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 23:26:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 19:26:25 -0400 Subject: [Git][ghc/ghc][master] Set base 'maintainer' field to CLC Message-ID: <6435eca1a5e56_354530f36881418795c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - 1 changed file: - libraries/base/base.cabal Changes: ===================================== libraries/base/base.cabal ===================================== @@ -5,8 +5,8 @@ version: 4.18.0.0 license: BSD-3-Clause license-file: LICENSE -maintainer: libraries at haskell.org -bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +maintainer: Core Libraries Committee +bug-reports: https://github.com/haskell/core-libraries-committee/issues synopsis: Basic libraries category: Prelude build-type: Configure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1892cc0c142e74640c320795493161d9321387f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1892cc0c142e74640c320795493161d9321387f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 11 23:26:59 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 11 Apr 2023 19:26:59 -0400 Subject: [Git][ghc/ghc][master] Clarify a couple of Notes about 'nospec' Message-ID: <6435ecc3d71d1_354530f21d1801910f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - 2 changed files: - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -849,8 +849,10 @@ Here are the moving parts: * `GHC.HsToCore.Binds.dsHsWrapper` desugars the evidence application (f d) into (nospec f d) if `d` is incoherent. It has to do a dependency analysis to - determine transitive dependencies, but we need to do that anway. + determine transitive dependencies, but we need to do that anyway. See Note [Desugaring incoherent evidence] in GHC.HsToCore.Binds. + + See also Note [nospecId magic] in GHC.Types.Id.Make. -} type DFunInstType = Maybe Type ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -2002,10 +2002,15 @@ Note that this happens *after* unfoldings are exposed in the interface file. This is crucial: otherwise, we could import an unfolding in which 'nospec' has been inlined (= erased), and we would lose the benefit. -'nospec' is used in the implementation of 'withDict': we insert 'nospec' -so that the typeclass specialiser doesn't assume any two evidence terms -of the same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, -and see test case T21575b for an example. +'nospec' is used: + +* In the implementation of 'withDict': we insert 'nospec' so that the + typeclass specialiser doesn't assume any two evidence terms of the + same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, + and see test case T21575b for an example. + +* To defeat the specialiser when we have incoherent instances. + See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. Note [The oneShot function] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf22da3c6d992d76fbb8e970b4ffbabb445d38a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf22da3c6d992d76fbb8e970b4ffbabb445d38a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 07:02:23 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Wed, 12 Apr 2023 03:02:23 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 9 commits: base: Remove HAVE_* CPP guards Message-ID: <6436577f7931d_35453016cda3a02050e1@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: a86389fa by Zubin Duggal at 2023-04-12T11:03:47+05:30 base: Remove HAVE_* CPP guards - - - - - 19ed0ca7 by Tamar Christina at 2023-04-12T11:03:47+05:30 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. (cherry picked from commit 48e391952c17ff7eab10b0b1456e3f2a2af28a9b) - - - - - 686c30f6 by Ben Gamari at 2023-04-12T11:03:48+05:30 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - c243cbdd by Zubin Duggal at 2023-04-12T11:03:48+05:30 lint-notes: accept output - - - - - 013436a2 by Ben Gamari at 2023-04-12T11:03:48+05:30 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit 78d04cfadfd728bb088b08b1e88905b43cc0360c) - - - - - 79998418 by Zubin Duggal at 2023-04-12T11:03:48+05:30 Bump submodules: text, parsec, bytestring, containers - - - - - ce5b0a64 by Zubin Duggal at 2023-04-12T11:03:48+05:30 Bump base to 4.17.1.0 and add release notes - - - - - ae2aecca by Zubin Duggal at 2023-04-12T12:31:45+05:30 Prepare release 9.4.5 - - - - - cc4e2482 by Zubin Duggal at 2023-04-12T12:31:45+05:30 Allow LLVM 14 - - - - - 23 changed files: - .gitlab-ci.yml - configure.ac - docs/users_guide/release-notes.rst - hadrian/bindist/Makefile - libraries/base/System/Posix/Internals.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/bytestring - libraries/containers - libraries/parsec - libraries/text - mk/get-win32-tarballs.py - rts/Linker.c - rts/LinkerInternals.h - rts/linker/PEi386.c - testsuite/tests/ghci/linking/dyn/Makefile - testsuite/tests/ghci/linking/dyn/all.T - + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll - + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a - testsuite/tests/ghci/scripts/T9881.stdout - testsuite/tests/ghci/scripts/ghci025.stdout - testsuite/tests/linters/notes.stdout - testsuite/tests/rts/all.T Changes: ===================================== .gitlab-ci.yml ===================================== @@ -6,7 +6,7 @@ variables: # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. - CACHE_REV: 8 + CACHE_REV: 10 # Disable shallow clones; they break our linting rules GIT_DEPTH: 0 ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are @@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-has AC_CONFIG_MACRO_DIRS([m4]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=NO} +: ${RELEASE=YES} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the @@ -582,7 +582,7 @@ AC_SUBST(InstallNameToolCmd) # versions of LLVM simultaneously, but that stopped working around # 3.5/3.6 release of LLVM. LlvmMinVersion=10 # inclusive -LlvmMaxVersion=14 # not inclusive +LlvmMaxVersion=15 # not inclusive AC_SUBST([LlvmMinVersion]) AC_SUBST([LlvmMaxVersion]) sUPPORTED_LLVM_VERSION_MIN=$(echo \($LlvmMinVersion\) | sed 's/\./,/') ===================================== docs/users_guide/release-notes.rst ===================================== @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 1 + 9.4.5-notes 9.4.4-notes 9.4.3-notes 9.4.2-notes ===================================== hadrian/bindist/Makefile ===================================== @@ -147,7 +147,9 @@ install_bin_libdir: fi; \ done # Work around #17418 on Darwin - if [ -e "${XATTR}" ]; then "${XATTR}" -c -r "$(DESTDIR)$(ActualBinsDir)"; fi + if [ -e "${XATTR}" ]; then \ + "${XATTR}" -c -r "$(DESTDIR)$(ActualBinsDir)"; \ + fi install_bin_direct: @echo "Copying binaries to $(DESTDIR)$(WrapperBinsDir)" @@ -181,6 +183,10 @@ install_lib: lib/settings for i in $(DOCS); do \ cp -R $$i "$(DESTDIR)$(docdir)/"; \ done + # Work around #17418 on Darwin + if [ -e "${XATTR}" ]; then \ + "${XATTR}" -c -r "$(DESTDIR)$(ActualLibsDir)"; \ + fi install_docs: @echo "Copying docs to $(DESTDIR)$(docdir)" ===================================== libraries/base/System/Posix/Internals.hs ===================================== @@ -36,7 +36,9 @@ import Foreign.C -- import Data.Bits import Data.Maybe +#if !defined(HTYPE_TCFLAG_T) import System.IO.Error +#endif import GHC.Base import GHC.Num @@ -457,13 +459,8 @@ foreign import capi unsafe "HsBase.h _lseeki64" foreign import capi unsafe "HsBase.h _access" c_access :: CString -> CInt -> IO CInt -#if !defined(HAVE_CHMOD) -c_chmod :: CString -> CMode -> IO CInt -c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "_chmod") -#else foreign import ccall unsafe "HsBase.h _chmod" c_chmod :: CString -> CMode -> IO CInt -#endif foreign import capi unsafe "HsBase.h _close" c_close :: CInt -> IO CInt @@ -471,19 +468,11 @@ foreign import capi unsafe "HsBase.h _close" foreign import capi unsafe "HsBase.h _creat" c_creat :: CString -> CMode -> IO CInt -#if !defined(HAVE_DUP) -c_dup :: CInt -> IO CInt -c_dup _ = ioError (ioeSetLocation unsupportedOperation "_dup") - -c_dup2 :: CInt -> CInt -> IO CInt -c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "_dup2") -#else foreign import ccall unsafe "HsBase.h _dup" c_dup :: CInt -> IO CInt foreign import ccall unsafe "HsBase.h _dup2" c_dup2 :: CInt -> CInt -> IO CInt -#endif foreign import capi unsafe "HsBase.h _isatty" c_isatty :: CInt -> IO CInt @@ -521,13 +510,8 @@ foreign import capi unsafe "HsBase.h write" foreign import capi safe "HsBase.h write" c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize -#if !defined(HAVE_PIPE) -c_pipe :: Ptr CInt -> IO CInt -c_pipe _ = ioError (ioeSetLocation unsupportedOperation "pipe") -#else foreign import ccall unsafe "HsBase.h pipe" c_pipe :: Ptr CInt -> IO CInt -#endif foreign import capi unsafe "unistd.h lseek" c_lseek :: CInt -> COff -> CInt -> IO COff @@ -535,13 +519,8 @@ foreign import capi unsafe "unistd.h lseek" foreign import ccall unsafe "HsBase.h access" c_access :: CString -> CInt -> IO CInt -#if !defined(HAVE_CHMOD) -c_chmod :: CString -> CMode -> IO CInt -c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "chmod") -#else foreign import ccall unsafe "HsBase.h chmod" c_chmod :: CString -> CMode -> IO CInt -#endif foreign import ccall unsafe "HsBase.h close" c_close :: CInt -> IO CInt @@ -549,19 +528,11 @@ foreign import ccall unsafe "HsBase.h close" foreign import ccall unsafe "HsBase.h creat" c_creat :: CString -> CMode -> IO CInt -#if !defined(HAVE_DUP) -c_dup :: CInt -> IO CInt -c_dup _ = ioError (ioeSetLocation unsupportedOperation "dup") - -c_dup2 :: CInt -> CInt -> IO CInt -c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "dup2") -#else foreign import ccall unsafe "HsBase.h dup" c_dup :: CInt -> IO CInt foreign import ccall unsafe "HsBase.h dup2" c_dup2 :: CInt -> CInt -> IO CInt -#endif foreign import ccall unsafe "HsBase.h isatty" c_isatty :: CInt -> IO CInt @@ -572,14 +543,9 @@ foreign import ccall unsafe "HsBase.h unlink" foreign import capi unsafe "HsBase.h utime" c_utime :: CString -> Ptr CUtimbuf -> IO CInt -#if !defined(HAVE_GETPID) -c_getpid :: IO CPid -c_getpid = pure 1 -#else foreign import ccall unsafe "HsBase.h getpid" c_getpid :: IO CPid #endif -#endif foreign import ccall unsafe "HsBase.h __hscore_stat" c_stat :: CFilePath -> Ptr CStat -> IO CInt @@ -707,6 +673,7 @@ foreign import capi unsafe "stdio.h value SEEK_END" sEEK_END :: CInt {- Note [Windows types] +~~~~~~~~~~~~~~~~~~~~ Windows' _read and _write have types that differ from POSIX. They take an unsigned int for length and return a signed int where POSIX uses size_t and ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.17.0.0 +version: 4.17.1.0 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause ===================================== libraries/base/changelog.md ===================================== @@ -1,5 +1,11 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.17.1.0 *April 2023* + + * Remove `mingwex` dependency on Windows (#22166). + + * Fix inconsistency with decoding terminal input on Windows (#21488). + ## 4.17.0.0 *August 2022* * Add explicitly bidirectional `pattern TypeRep` to `Type.Reflection`. ===================================== libraries/bytestring ===================================== @@ -1 +1 @@ -Subproject commit 1543e054a314865d89a259065921d5acba03d966 +Subproject commit 9cab76dc861f651c3940e873ce921d9e09733cc8 ===================================== libraries/containers ===================================== @@ -1 +1 @@ -Subproject commit 50175b72dc781f82a419bddafba1bdd758fbee4b +Subproject commit 9f4a93604c66a5e605ce46fc30003b71802b3cfd ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit a74c68e948c99621100447014f48ccac7ee0448e +Subproject commit 1f542120d9adc5e22f8791a6d595210e93c6c389 ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit fdb06ff327519f3c0fc6cc9997b7cb7fe8ab8178 +Subproject commit e815d4d9bc362f4a3a36a850931fd3504eda967e ===================================== mk/get-win32-tarballs.py ===================================== @@ -8,7 +8,7 @@ import argparse import sys from sys import stderr -TARBALL_VERSION = '0.7' +TARBALL_VERSION = '0.8' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['x86_64', 'sources'] ===================================== rts/Linker.c ===================================== @@ -135,8 +135,7 @@ extern void iconv(); This is to enable lazy loading of symbols. Eager loading is problematic as it means that all symbols must be available, even those which we will never use. This is especially painful on Windows, where the number of - libraries required to link things like mingwex (TODO: We no longer depend - on mingwex, so think of a different example here) grows to be quite high. + libraries required to link things like QT or WxWidgets grows to be quite high. We proceed through these stages as follows, @@ -194,8 +193,7 @@ extern void iconv(); 1) Dependency chains, if A.o required a .o in libB but A.o isn't required to link then we don't need to load libB. This means the dependency chain for libraries - such as mingw32 and mingwex (TODO: We no longer depend on mingwex, so think of - a different example here) can be broken down. + such as ucrt can be broken down. 2) The number of duplicate symbols, since now only symbols that are true duplicates will display the error. @@ -228,7 +226,7 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key, static const char * symbolTypeString (SymType type) { - switch (type) { + switch (type & ~SYM_TYPE_DUP_DISCARD) { case SYM_TYPE_CODE: return "code"; case SYM_TYPE_DATA: return "data"; case SYM_TYPE_INDIRECT_DATA: return "indirect-data"; @@ -277,14 +275,18 @@ int ghciInsertSymbolTable( insertStrHashTable(table, key, pinfo); return 1; } - else if (pinfo->type != type) + else if (pinfo->type ^ type) { - debugBelch("Symbol type mismatch.\n"); - debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n", - key, obj_name, symbolTypeString(type)); - debugBelch(" yet was defined by %" PATH_FMT " to be a %s symbol.\n", - pinfo->owner ? pinfo->owner->fileName : WSTR(""), - symbolTypeString(pinfo->type)); + /* We were asked to discard the symbol on duplicates, do so quietly. */ + if (!(type & SYM_TYPE_DUP_DISCARD)) + { + debugBelch("Symbol type mismatch.\n"); + debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n", + key, obj_name, symbolTypeString(type)); + debugBelch(" yet was defined by %" PATH_FMT " to be a %s symbol.\n", + pinfo->owner ? pinfo->owner->fileName : WSTR(""), + symbolTypeString(pinfo->type)); + } return 1; } else if (pinfo->strength == STRENGTH_STRONG) ===================================== rts/LinkerInternals.h ===================================== @@ -52,11 +52,16 @@ typedef struct _Section Section; */ /* What kind of thing a symbol identifies. We need to know this to determine how - * to process overflowing relocations. See Note [Processing overflowed relocations]. */ + * to process overflowing relocations. See Note [Processing overflowed relocations]. + * This is bitfield however only the option SYM_TYPE_DUP_DISCARD can be combined + * with the other values. */ typedef enum _SymType { - SYM_TYPE_CODE, /* the symbol is a function and can be relocated via a jump island */ - SYM_TYPE_DATA, /* the symbol is data */ - SYM_TYPE_INDIRECT_DATA, /* see Note [_iob_func symbol] */ + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ } SymType; ===================================== rts/linker/PEi386.c ===================================== @@ -261,6 +261,54 @@ .asciiz "libfoo_data" + Note [GHC Linking model and import libraries] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + The above describes how import libraries work for static linking. + Fundamentally this does not apply to dynamic linking as we do in GHC. + The issue is two-folds: + + 1. In the linking model above it is expected that the .idata sections be + materialized into PLTs during linking. However in GHC we never create + PLTs, but have out own mechanism for this which is the jump island + machinery. This is required for efficiency. For one materializing the + .idata sections would result in wasting pages. We'd use one page for + every ~100 bytes. This is extremely wasteful and also fragments the + memory. Secondly the dynamic linker is lazy. We only perform the final + loading if the symbol is used, however with an import library we can + discard the actual OC immediately after reading it. This prevents us from + keeping ~1k in memory per symbol for no reason. + + 2. GHC itself does not observe symbol visibility correctly during NGC. This + in itself isn't an academic exercise. The issue stems from GHC using one + mechanism for providing two incompatible linking modes: + a) The first mode is generating Haskell shared libraries which are + intended to be used by other Haskell code. This requires us to + export the info, data and closures. For this GHC just re-exports + all symbols. But it doesn't correcly mark data/code. Symbol + visibility is overwritten by telling the linker to export all + symbols. + b) The second code is producing code that's supposed to be call-able + through a C insterface. This in reality does not require the + export of closures and info tables. But also does not require the + inclusion of the RTS inside the DLL. Hover this is done today + because we don't properly have the RTS as a dynamic library. + i.e. GHC does not only export symbols denoted by foreign export. + Also GHC should depend on an RTS library, but at the moment it + cannot because of TNTC is incompatible with dynamic linking. + + These two issues mean that for GHC we need to take a different approach + to handling import libraries. For normal C libraries we have proper + differentiation between CODE and DATA. For GHC produced import libraries + we do not. As such the SYM_TYPE_DUP_DISCARD tells the linker that if a + duplicate symbol is found, and we were going to discard it anyway, just do + so quitely. This works because the RTS symbols themselves are provided by + the currently loaded RTS as built-in symbols. + + Secondly we cannot rely on a text symbol being available. As such we + should only depend on the symbols as defined in the .idata sections, + otherwise we would not be able to correctly link against GHC produced + import libraries. + Note [Memory allocation] ~~~~~~~~~~~~~~~~~~~~~~~~ The loading of an object begins in `preloadObjectFile`, which allocates a buffer, @@ -1700,7 +1748,10 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if ( secNumber != IMAGE_SYM_UNDEFINED && secNumber > 0 && section - && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY) { + /* Skip all BFD import sections. */ + && section->kind != SECTIONKIND_IMPORT + && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY + && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY_HEAD) { /* This symbol is global and defined, viz, exported */ /* for IMAGE_SYMCLASS_EXTERNAL && !IMAGE_SYM_UNDEFINED, @@ -1733,12 +1784,49 @@ ocGetNames_PEi386 ( ObjectCode* oc ) IF_DEBUG(linker_verbose, debugBelch("bss symbol @ %p %u\n", addr, symValue)); } else if (section && section->kind == SECTIONKIND_BFD_IMPORT_LIBRARY) { - setImportSymbol(oc, sname); + /* Disassembly of section .idata$5: + + 0000000000000000 <__imp_Insert>: + ... + 0: IMAGE_REL_AMD64_ADDR32NB .idata$6 + + The first two bytes contain the ordinal of the function + in the format of lowpart highpart. The two bytes combined + for the total range of 16 bits which is the function export limit + of DLLs. See note [GHC Linking model and import libraries]. */ + sname = (SymbolName*)section->start+2; + COFF_symbol* sym = &oc->info->symbols[info->numberOfSymbols-1]; + addr = get_sym_name( getSymShortName (info, sym), oc); + + IF_DEBUG(linker, + debugBelch("addImportSymbol `%s' => `%s'\n", + sname, (char*)addr)); + /* We're going to free the any data associated with the import + library without copying the sections. So we have to duplicate + the symbol name and values before the pointers become invalid. */ + sname = strdup (sname); + addr = strdup (addr); + type = has_code_section ? SYM_TYPE_CODE : SYM_TYPE_DATA; + type |= SYM_TYPE_DUP_DISCARD; + if (!ghciInsertSymbolTable(oc->fileName, symhash, sname, + addr, false, type, oc)) { + releaseOcInfo (oc); + stgFree (oc->image); + oc->image = NULL; + return false; + } + setImportSymbol (oc, sname); + + /* Don't process this oc any further. Just exit. */ + oc->n_symbols = 0; + oc->symbols = NULL; + stgFree (oc->image); + oc->image = NULL; + releaseOcInfo (oc); // There is nothing that we need to resolve in this object since we // will never call the import stubs in its text section oc->status = OBJECT_DONT_RESOLVE; - - IF_DEBUG(linker_verbose, debugBelch("import symbol %s\n", sname)); + return true; } else if (secNumber > 0 && section ===================================== testsuite/tests/ghci/linking/dyn/Makefile ===================================== @@ -88,10 +88,6 @@ compile_libAB_dyn: .PHONY: compile_libAS_impl_gcc compile_libAS_impl_gcc: - rm -rf bin_impl_gcc - mkdir bin_impl_gcc - '$(TEST_HC)' $(MY_TEST_HC_OPTS) -odir "bin_impl_gcc" -shared A.c -o "bin_impl_gcc/$(call DLL,ASimpL)" - mv bin_impl_gcc/libASimpL.dll.a bin_impl_gcc/libASx.dll.a echo "main" | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) T11072.hs -lASx -L./bin_impl_gcc .PHONY: compile_libAS_impl_msvc ===================================== testsuite/tests/ghci/linking/dyn/all.T ===================================== @@ -33,9 +33,9 @@ test('T10458', extra_hc_opts('-L"$PWD/T10458dir" -lAS')], ghci_script, ['T10458.script']) -test('T11072gcc', [extra_files(['A.c', 'T11072.hs']), - expect_broken(18718), - unless(doing_ghci, skip), unless(opsys('mingw32'), skip)], +test('T11072gcc', [extra_files(['A.c', 'T11072.hs', 'bin_impl_gcc/']), + unless(doing_ghci, skip), unless(opsys('mingw32'), skip), + unless(arch('x86_64'), skip)], makefile_test, ['compile_libAS_impl_gcc']) test('T11072msvc', [extra_files(['A.c', 'T11072.hs', 'libAS.def', 'i686/', 'x86_64/']), ===================================== testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll ===================================== Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll differ ===================================== testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a ===================================== Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a differ ===================================== testsuite/tests/ghci/scripts/T9881.stdout ===================================== @@ -19,19 +19,19 @@ instance Ord Data.ByteString.Lazy.ByteString type Data.ByteString.ByteString :: * data Data.ByteString.ByteString - = Data.ByteString.Internal.BS {-# UNPACK #-}(GHC.ForeignPtr.ForeignPtr - GHC.Word.Word8) - {-# UNPACK #-}Int - -- Defined in ‘Data.ByteString.Internal’ + = bytestring-0.11.4.0:Data.ByteString.Internal.Type.BS {-# UNPACK #-}(GHC.ForeignPtr.ForeignPtr + GHC.Word.Word8) + {-# UNPACK #-}Int + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Monoid Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Read Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Semigroup Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Show Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Eq Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ instance Ord Data.ByteString.ByteString - -- Defined in ‘Data.ByteString.Internal’ + -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’ ===================================== testsuite/tests/ghci/scripts/ghci025.stdout ===================================== @@ -53,7 +53,9 @@ Prelude.length :: Data.Foldable.Foldable t => t a -> GHC.Types.Int -- imported via T type T.Integer :: * data T.Integer = ... -T.length :: Data.ByteString.Internal.ByteString -> GHC.Types.Int +T.length :: + bytestring-0.11.4.0:Data.ByteString.Internal.Type.ByteString + -> GHC.Types.Int :browse! T -- defined locally T.length :: T.Integer ===================================== testsuite/tests/linters/notes.stdout ===================================== @@ -1,138 +1,153 @@ +ref compiler/GHC/Builtin/PrimOps.hs:329:7: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:178:10: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:189:10: Note [Core let/app invariant] +ref compiler/GHC/Core.hs:520:3: Note [exprOkForSpeculation and type classes] ref compiler/GHC/Core/Coercion/Axiom.hs:458:2: Note [RoughMap and rm_empty] -ref compiler/GHC/Core/Opt/Arity.hs:: Note [Combining case branches] -ref compiler/GHC/Core/Opt/Arity.hs:: Note [ArityType for let-bindings] +ref compiler/GHC/Core/Lint.hs:635:15: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:120:47: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:146:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:161:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:175:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Make.hs:190:9: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Arity.hs:610:5: Note [Combining case branches] +ref compiler/GHC/Core/Opt/Arity.hs:1298:0: Note [ArityType for let-bindings] +ref compiler/GHC/Core/Opt/ConstantFold.hs:1413:15: Note [Core let/app invariant] ref compiler/GHC/Core/Opt/OccurAnal.hs:851:15: Note [Loop breaking] ref compiler/GHC/Core/Opt/SetLevels.hs:1598:30: Note [Top level scope] -ref compiler/GHC/Core/Opt/Simplify.hs:2618:13: Note [Case binder next] -ref compiler/GHC/Core/Opt/Simplify.hs:3239:0: Note [Suppressing binder-swaps on linear case] -ref compiler/GHC/Core/Opt/Simplify.hs:3767:8: Note [Lambda-bound unfoldings] -ref compiler/GHC/Core/Opt/Simplify.hs:4123:33: Note [Do not eta-expand trivial expressions] -ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1225:37: Note [Gentle mode] -ref compiler/GHC/Core/Opt/Specialise.hs:1593:28: Note [Arity decrease] +ref compiler/GHC/Core/Opt/Simplify.hs:1708:17: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Simplify.hs:2672:13: Note [Case binder next] +ref compiler/GHC/Core/Opt/Simplify.hs:3294:0: Note [Suppressing binder-swaps on linear case] +ref compiler/GHC/Core/Opt/Simplify.hs:3844:8: Note [Lambda-bound unfoldings] +ref compiler/GHC/Core/Opt/Simplify.hs:4200:33: Note [Do not eta-expand trivial expressions] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1240:37: Note [Gentle mode] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1294:7: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1420:7: Note [Core let/app invariant] +ref compiler/GHC/Core/Opt/Specialise.hs:1588:28: Note [Arity decrease] ref compiler/GHC/Core/RoughMap.hs:183:35: Note [RoughMatch and beta reduction] ref compiler/GHC/Core/Subst.hs:100:60: Note [Apply once] ref compiler/GHC/Core/Subst.hs:111:16: Note [Extending the TCvSubst] -ref compiler/GHC/Core/TyCo/FVs.hs:289:7: Note [Free variables of Coercions] +ref compiler/GHC/Core/TyCo/FVs.hs:286:7: Note [Free variables of Coercions] ref compiler/GHC/Core/TyCo/Ppr.hs:71:23: Note [IfaceType and pretty-printing] -ref compiler/GHC/Core/TyCo/Rep.hs:1711:31: Note [What prevents a constraint from floating] +ref compiler/GHC/Core/TyCo/Rep.hs:1748:31: Note [What prevents a constraint from floating] ref compiler/GHC/Core/TyCo/Subst.hs:784:15: Note [Extending the TCvSubst] ref compiler/GHC/Core/TyCo/Subst.hs:1001:15: Note [Extending the TCvSubst] -ref compiler/GHC/Core/TyCon.hs:961:35: Note [Promoted GADT data construtors] -ref compiler/GHC/Core/TyCon.hs:2442:62: Note [Sharing nullary TyCons] -ref compiler/GHC/Core/Unfold.hs:1171:23: Note [INLINE for small functions (3)] -ref compiler/GHC/Core/Unfold.hs:1242:50: Note [Unfold info lazy contexts] +ref compiler/GHC/Core/TyCon.hs:966:35: Note [Promoted GADT data construtors] +ref compiler/GHC/Core/TyCon.hs:2472:62: Note [Sharing nullary TyCons] +ref compiler/GHC/Core/Unfold.hs:1174:23: Note [INLINE for small functions (3)] +ref compiler/GHC/Core/Unfold.hs:1245:50: Note [Unfold info lazy contexts] ref compiler/GHC/Core/Unfold/Make.hs:157:34: Note [DFunUnfoldings] -ref compiler/GHC/Core/Unify.hs:1390:9: Note [INLINE pragmas and (>>)] -ref compiler/GHC/Core/Utils.hs:947:40: Note [ _ -> [con1] -ref compiler/GHC/CoreToStg.hs:462:15: Note [Nullary unboxed tuple] -ref compiler/GHC/Driver/Main.hs:1566:34: Note [simpleTidyPgm - mkBootModDetailsTc] -ref compiler/GHC/Driver/Session.hs:1947:36: Note [GHC.Driver.Main . Safe Haskell Inference] -ref compiler/GHC/Driver/Session.hs:3916:49: Note [Eta-reduction in -O0] +ref compiler/GHC/Core/Unify.hs:1492:9: Note [INLINE pragmas and (>>)] +ref compiler/GHC/Core/Utils.hs:952:40: Note [ _ -> [con1] +ref compiler/GHC/CoreToStg.hs:463:15: Note [Nullary unboxed tuple] +ref compiler/GHC/Driver/Main.hs:1594:34: Note [simpleTidyPgm - mkBootModDetailsTc] +ref compiler/GHC/Driver/Session.hs:1997:36: Note [GHC.Driver.Main . Safe Haskell Inference] +ref compiler/GHC/Driver/Session.hs:3991:49: Note [Eta-reduction in -O0] ref compiler/GHC/Hs/Extension.hs:140:5: Note [Strict argument type constraints] ref compiler/GHC/HsToCore/Binds.hs:313:33: Note [AbsBinds wrappers] -ref compiler/GHC/HsToCore/Binds.hs:849:46: Note [Free dictionaries] -ref compiler/GHC/HsToCore/Binds.hs:883:36: Note [Free tyvars in rule LHS] -ref compiler/GHC/HsToCore/Binds.hs:884:35: Note [Free dictionaries in rule LHS] -ref compiler/GHC/HsToCore/Binds.hs:942:24: Note [Free dictionaries] -ref compiler/GHC/HsToCore/Binds.hs:999:34: Note [Dead spec binders] -ref compiler/GHC/HsToCore/Docs.hs:126:70: Note [1] -ref compiler/GHC/HsToCore/Docs.hs:130:0: Note [1] -ref compiler/GHC/HsToCore/Pmc/Solver.hs:853:20: Note [COMPLETE sets on data families] +ref compiler/GHC/HsToCore/Binds.hs:850:46: Note [Free dictionaries] +ref compiler/GHC/HsToCore/Binds.hs:884:36: Note [Free tyvars in rule LHS] +ref compiler/GHC/HsToCore/Binds.hs:885:35: Note [Free dictionaries in rule LHS] +ref compiler/GHC/HsToCore/Binds.hs:943:24: Note [Free dictionaries] +ref compiler/GHC/HsToCore/Binds.hs:1000:34: Note [Dead spec binders] +ref compiler/GHC/HsToCore/Docs.hs:272:70: Note [1] +ref compiler/GHC/HsToCore/Docs.hs:276:0: Note [1] +ref compiler/GHC/HsToCore/Pmc/Solver.hs:855:20: Note [COMPLETE sets on data families] ref compiler/GHC/HsToCore/Types.hs:61:13: Note [Generating fresh names for FFI wrappers] -ref compiler/GHC/HsToCore/Utils.hs:939:62: Note [Don't CPR join points] +ref compiler/GHC/HsToCore/Utils.hs:942:62: Note [Don't CPR join points] ref compiler/GHC/Iface/Syntax.hs:708:0: Note [Minimal complete definition] ref compiler/GHC/Iface/Syntax.hs:768:44: Note [Minimal complete definition] -ref compiler/GHC/Parser/Lexer.x:185:7: Note [Lexing NumericUnderscores extension] -ref compiler/GHC/Parser/Lexer.x:502:3: Note [Lexing NumericUnderscores extension] -ref compiler/GHC/Rename/Expr.hs:2013:9: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2046:12: Note [ApplicativeDo and refutable patterns] -ref compiler/GHC/Rename/Expr.hs:2130:18: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2148:0: Note [ApplicativeDo and strict patterns] -ref compiler/GHC/Rename/Expr.hs:2203:0: Note [ApplicativeDo and refutable patterns] +ref compiler/GHC/Parser/Lexer.x:188:7: Note [Lexing NumericUnderscores extension] +ref compiler/GHC/Parser/Lexer.x:505:3: Note [Lexing NumericUnderscores extension] +ref compiler/GHC/Rename/Expr.hs:2043:9: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2082:12: Note [ApplicativeDo and refutable patterns] +ref compiler/GHC/Rename/Expr.hs:2166:18: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2184:0: Note [ApplicativeDo and strict patterns] +ref compiler/GHC/Rename/Expr.hs:2239:0: Note [ApplicativeDo and refutable patterns] ref compiler/GHC/Rename/Pat.hs:888:29: Note [Disambiguating record fields] -ref compiler/GHC/Rename/Splice.hs:450:27: Note [Splices] -ref compiler/GHC/Runtime/Eval.hs:996:2: Note [Querying instances for a type] +ref compiler/GHC/Rename/Splice.hs:478:27: Note [Splices] +ref compiler/GHC/Runtime/Eval.hs:995:2: Note [Querying instances for a type] ref compiler/GHC/Runtime/Interpreter.hs:198:30: Note [uninterruptibleMask_] -ref compiler/GHC/StgToCmm.hs:108:18: Note [codegen-split-init] -ref compiler/GHC/StgToCmm.hs:111:18: Note [pipeline-split-init] -ref compiler/GHC/StgToCmm/Expr.hs:585:4: Note [case on bool] -ref compiler/GHC/StgToCmm/Expr.hs:848:3: Note [alg-alt heap check] -ref compiler/GHC/Tc/Errors.hs:180:13: Note [Fail fast on kind errors] -ref compiler/GHC/Tc/Errors.hs:2016:0: Note [Highlighting ambiguous type variables] -ref compiler/GHC/Tc/Errors/Ppr.hs:1760:11: Note [Highlighting ambiguous type variables] -ref compiler/GHC/Tc/Gen/Arrow.hs:435:29: Note [RecStmt] -ref compiler/GHC/Tc/Gen/Bind.hs:1397:19: Note [Existentials in pattern bindings] -ref compiler/GHC/Tc/Gen/Export.hs:187:15: Note [Modules without a module header] -ref compiler/GHC/Tc/Gen/Export.hs:418:0: Note [Modules without a module header] -ref compiler/GHC/Tc/Gen/Export.hs:576:7: Note [Typing Pattern Synonym Exports] -ref compiler/GHC/Tc/Gen/Export.hs:615:16: Note [Types of TyCon] -ref compiler/GHC/Tc/Gen/Expr.hs:670:24: Note [Disambiguating record fields] -ref compiler/GHC/Tc/Gen/Expr.hs:687:15: Note [Mixed Record Selectors] +ref compiler/GHC/Stg/Lint.hs:9:56: Note [Core let/app invariant] +ref compiler/GHC/StgToCmm.hs:106:18: Note [codegen-split-init] +ref compiler/GHC/StgToCmm.hs:109:18: Note [pipeline-split-init] +ref compiler/GHC/StgToCmm/Expr.hs:579:4: Note [case on bool] +ref compiler/GHC/StgToCmm/Expr.hs:847:3: Note [alg-alt heap check] +ref compiler/GHC/Tc/Errors.hs:178:13: Note [Fail fast on kind errors] +ref compiler/GHC/Tc/Errors.hs:2239:0: Note [Highlighting ambiguous type variables] +ref compiler/GHC/Tc/Errors/Ppr.hs:2074:11: Note [Highlighting ambiguous type variables] +ref compiler/GHC/Tc/Gen/Arrow.hs:438:29: Note [RecStmt] +ref compiler/GHC/Tc/Gen/Bind.hs:1368:19: Note [Existentials in pattern bindings] +ref compiler/GHC/Tc/Gen/Export.hs:188:15: Note [Modules without a module header] +ref compiler/GHC/Tc/Gen/Export.hs:423:0: Note [Modules without a module header] +ref compiler/GHC/Tc/Gen/Export.hs:581:7: Note [Typing Pattern Synonym Exports] +ref compiler/GHC/Tc/Gen/Export.hs:620:16: Note [Types of TyCon] +ref compiler/GHC/Tc/Gen/Expr.hs:662:24: Note [Disambiguating record fields] +ref compiler/GHC/Tc/Gen/Expr.hs:679:15: Note [Mixed Record Selectors] ref compiler/GHC/Tc/Gen/Expr.hs:1195:7: Note [Disambiguating record fields] ref compiler/GHC/Tc/Gen/Expr.hs:1298:11: Note [Deprecating ambiguous fields] ref compiler/GHC/Tc/Gen/Foreign.hs:149:26: Note [Expanding newtypes] -ref compiler/GHC/Tc/Gen/HsType.hs:552:56: Note [Skolem escape prevention] -ref compiler/GHC/Tc/Gen/HsType.hs:2623:7: Note [Matching a kind sigature with a declaration] -ref compiler/GHC/Tc/Gen/Match.hs:553:20: Note [GroupStmt binder map] -ref compiler/GHC/Tc/Gen/Match.hs:746:20: Note [GroupStmt binder map] -ref compiler/GHC/Tc/Gen/Match.hs:1011:0: Note [typechecking ApplicativeStmt] -ref compiler/GHC/Tc/Gen/Pat.hs:169:20: Note [Typing patterns in pattern bindings] -ref compiler/GHC/Tc/Gen/Pat.hs:476:7: Note [Pattern coercions] -ref compiler/GHC/Tc/Gen/Pat.hs:1077:7: Note [Matching polytyped patterns] -ref compiler/GHC/Tc/Gen/Pat.hs:1376:16: Note [Pattern coercions] +ref compiler/GHC/Tc/Gen/HsType.hs:551:56: Note [Skolem escape prevention] +ref compiler/GHC/Tc/Gen/HsType.hs:2632:7: Note [Matching a kind sigature with a declaration] +ref compiler/GHC/Tc/Gen/Match.hs:541:20: Note [GroupStmt binder map] +ref compiler/GHC/Tc/Gen/Match.hs:734:20: Note [GroupStmt binder map] +ref compiler/GHC/Tc/Gen/Match.hs:999:0: Note [typechecking ApplicativeStmt] +ref compiler/GHC/Tc/Gen/Pat.hs:171:20: Note [Typing patterns in pattern bindings] +ref compiler/GHC/Tc/Gen/Pat.hs:480:7: Note [Pattern coercions] +ref compiler/GHC/Tc/Gen/Pat.hs:1107:7: Note [Matching polytyped patterns] +ref compiler/GHC/Tc/Gen/Pat.hs:1407:16: Note [Pattern coercions] ref compiler/GHC/Tc/Gen/Sig.hs:78:10: Note [Overview of type signatures] ref compiler/GHC/Tc/Instance/Family.hs:515:35: Note [Constrained family instances] -ref compiler/GHC/Tc/Module.hs:698:15: Note [Extra dependencies from .hs-boot files] -ref compiler/GHC/Tc/Module.hs:1904:19: Note [Root-main id] -ref compiler/GHC/Tc/Module.hs:1974:6: Note [Root-main id] -ref compiler/GHC/Tc/Solver/Canonical.hs:1229:33: Note [Canonical LHS] -ref compiler/GHC/Tc/Solver/Interact.hs:1638:9: Note [No touchables as FunEq RHS] -ref compiler/GHC/Tc/Solver/Interact.hs:2292:12: Note [The equality class story] -ref compiler/GHC/Tc/Solver/Rewrite.hs:1032:7: Note [Stability of rewriting] +ref compiler/GHC/Tc/Module.hs:705:15: Note [Extra dependencies from .hs-boot files] +ref compiler/GHC/Tc/Module.hs:1916:19: Note [Root-main id] +ref compiler/GHC/Tc/Module.hs:1986:6: Note [Root-main id] +ref compiler/GHC/Tc/Solver/Canonical.hs:1087:33: Note [Canonical LHS] +ref compiler/GHC/Tc/Solver/Interact.hs:1619:9: Note [No touchables as FunEq RHS] +ref compiler/GHC/Tc/Solver/Interact.hs:2305:12: Note [The equality class story] +ref compiler/GHC/Tc/Solver/Rewrite.hs:988:7: Note [Stability of rewriting] ref compiler/GHC/Tc/TyCl.hs:627:3: Note [Single function non-recursive binding special-case] ref compiler/GHC/Tc/TyCl.hs:1106:6: Note [Unification variables need fresh Names] ref compiler/GHC/Tc/TyCl.hs:1895:13: Note [TyConBinders for the result kind signatures of a data type] -ref compiler/GHC/Tc/TyCl.hs:4366:16: Note [rejigCon and c.f. Note [Check role annotations in a second pass] +ref compiler/GHC/Tc/TyCl.hs:4362:16: Note [rejigCon and c.f. Note [Check role annotations in a second pass] ref compiler/GHC/Tc/TyCl/Instance.hs:947:26: Note [Generalising in tcFamTyPatsGuts] -ref compiler/GHC/Tc/Types.hs:647:17: Note [Generating fresh names for FFI wrappers] -ref compiler/GHC/Tc/Types.hs:696:33: Note [Extra dependencies from .hs-boot files] -ref compiler/GHC/Tc/Types.hs:1154:28: Note [Don't promote data constructors with non-equality contexts] -ref compiler/GHC/Tc/Types.hs:1230:36: Note [Bindings with closed types] -ref compiler/GHC/Tc/Types.hs:1466:47: Note [Care with plugin imports] -ref compiler/GHC/Tc/Types/Constraint.hs:238:34: Note [NonCanonical Semantics] +ref compiler/GHC/Tc/Types.hs:653:17: Note [Generating fresh names for FFI wrappers] +ref compiler/GHC/Tc/Types.hs:702:33: Note [Extra dependencies from .hs-boot files] +ref compiler/GHC/Tc/Types.hs:1160:28: Note [Don't promote data constructors with non-equality contexts] +ref compiler/GHC/Tc/Types.hs:1236:36: Note [Bindings with closed types] +ref compiler/GHC/Tc/Types.hs:1472:47: Note [Care with plugin imports] +ref compiler/GHC/Tc/Types/Constraint.hs:254:34: Note [NonCanonical Semantics] ref compiler/GHC/Tc/Utils/Env.hs:556:7: Note [Bindings with closed types] ref compiler/GHC/Tc/Utils/Env.hs:1128:7: Note [Generating fresh names for ccall wrapper] ref compiler/GHC/Tc/Utils/Env.hs:1141:0: Note [Generating fresh names for FFI wrappers] ref compiler/GHC/Tc/Utils/Env.hs:1192:7: Note [Placeholder PatSyn kinds] -ref compiler/GHC/Tc/Utils/TcMType.hs:793:7: Note [Kind checking for GADTs] -ref compiler/GHC/Tc/Utils/TcType.hs:529:7: Note [TyVars and TcTyVars] -ref compiler/GHC/ThToHs.hs:1738:11: Note [Adding parens for splices] -ref compiler/GHC/ThToHs.hs:1749:3: Note [Adding parens for splices] -ref compiler/GHC/Types/Basic.hs:619:17: Note [Safe Haskell isSafeOverlap] -ref compiler/GHC/Types/Basic.hs:1359:7: Note [Activation competition] -ref compiler/GHC/Types/Demand.hs:307:25: Note [Preserving Boxity of results is rarely a win] -ref compiler/GHC/Types/Demand.hs:1100:4: Note [Use one-shot information] +ref compiler/GHC/Tc/Utils/TcMType.hs:750:7: Note [Kind checking for GADTs] +ref compiler/GHC/Tc/Utils/TcType.hs:591:7: Note [TyVars and TcTyVars] +ref compiler/GHC/ThToHs.hs:1788:11: Note [Adding parens for splices] +ref compiler/GHC/ThToHs.hs:1799:3: Note [Adding parens for splices] +ref compiler/GHC/Types/Basic.hs:624:17: Note [Safe Haskell isSafeOverlap] +ref compiler/GHC/Types/Basic.hs:1370:7: Note [Activation competition] +ref compiler/GHC/Types/Demand.hs:310:25: Note [Preserving Boxity of results is rarely a win] +ref compiler/GHC/Types/Demand.hs:1142:4: Note [Use one-shot information] ref compiler/GHC/Types/Error.hs:358:3: Note [Suppressing Messages] ref compiler/GHC/Types/Error.hs:393:28: Note [Suppressing Messages] ref compiler/GHC/Types/Name/Occurrence.hs:301:4: Note [Unique OccNames from Template Haskell] ref compiler/GHC/Types/Unique.hs:78:25: Note [Uniques-prelude - Uniques for wired-in Prelude things] -ref compiler/GHC/Unit/Module/Deps.hs:79:13: Note [Structure of dep_boot_mods] +ref compiler/GHC/Unit/Module/Deps.hs:82:13: Note [Structure of dep_boot_mods] ref compiler/GHC/Utils/Monad.hs:391:34: Note [multiShotIO] -ref compiler/Language/Haskell/Syntax/Binds.hs:226:31: Note [fun_id in Match] -ref compiler/Language/Haskell/Syntax/Expr.hs:1561:32: Note [Quasi-quote overview] +ref compiler/Language/Haskell/Syntax/Binds.hs:204:31: Note [fun_id in Match] +ref compiler/Language/Haskell/Syntax/Expr.hs:1571:32: Note [Quasi-quote overview] ref compiler/Language/Haskell/Syntax/Pat.hs:336:12: Note [Disambiguating record fields] -ref configure.ac:212:10: Note [Linking ghc-bin against threaded stage0 RTS] +ref configure.ac:213:10: Note [Linking ghc-bin against threaded stage0 RTS] ref docs/core-spec/core-spec.mng:177:6: Note [TyBinders] -ref ghc/GHCi/UI.hs:3646:25: Note [ModBreaks.decls] -ref ghc/ghc.mk:62:6: Note [Linking ghc-bin against threaded stage0 RTS] -ref hadrian/src/Expression.hs:130:30: Note [Linking ghc-bin against threaded stage0 RTS] -ref libraries/base/GHC/ST.hs:139:7: Note [Definition of runRW#] +ref ghc/GHCi/UI.hs:3648:25: Note [ModBreaks.decls] +ref ghc/ghc.mk:57:6: Note [Linking ghc-bin against threaded stage0 RTS] +ref hadrian/src/Expression.hs:134:30: Note [Linking ghc-bin against threaded stage0 RTS] +ref libraries/base/GHC/ST.hs:134:7: Note [Definition of runRW#] ref linters/lint-notes/Notes.hs:32:29: Note [" <> T.unpack x <> "] ref linters/lint-notes/Notes.hs:69:22: Note [...] -ref testsuite/config/ghc:212:10: Note [WayFlags] +ref testsuite/config/ghc:243:10: Note [WayFlags] ref testsuite/driver/testlib.py:152:10: Note [Why is there no stage1 setup function?] ref testsuite/driver/testlib.py:156:2: Note [Why is there no stage1 setup function?] -ref testsuite/mk/boilerplate.mk:263:2: Note [WayFlags] +ref testsuite/mk/boilerplate.mk:267:2: Note [WayFlags] ref testsuite/tests/indexed-types/should_fail/ExtraTcsUntch.hs:30:27: Note [Extra TcS Untouchables] ref testsuite/tests/perf/join_points/join005.hs:19:63: Note [Don't CPR join points] ref testsuite/tests/perf/should_run/all.T:3:6: Note [Solving from instances when interacting Dicts] ===================================== testsuite/tests/rts/all.T ===================================== @@ -368,7 +368,7 @@ test('T10296b', [only_ways(['threaded2'])], compile_and_run, ['']) test('numa001', [ extra_run_opts('8'), unless(unregisterised(), extra_ways(['debug_numa'])) ] , compile_and_run, ['']) -test('T12497', [ unless(opsys('mingw32'), skip) +test('T12497', [ unless(opsys('mingw32'), skip), expect_broken(22694) ], makefile_test, ['T12497']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02e1f7a104f7aae90da19bcc3e74f15cdd582d86...cc4e2482ca3e32308cbe5beb43c898a5bbe5e540 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/02e1f7a104f7aae90da19bcc3e74f15cdd582d86...cc4e2482ca3e32308cbe5beb43c898a5bbe5e540 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 08:37:31 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 12 Apr 2023 04:37:31 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 2 commits: Wibble error messages Message-ID: <64366dcb65a41_354530185218dc2158e0@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: e98151ce by Simon Peyton Jones at 2023-04-12T09:37:50+01:00 Wibble error messages - - - - - 8e27d540 by Simon Peyton Jones at 2023-04-12T09:38:13+01:00 Experimental change: coercion holes Experiment with making a constraint non-canonical if it has a coercion hole on the RHS. Simplifies T22707 a lot! - - - - - 11 changed files: - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/polykinds/T9017.stderr - testsuite/tests/typecheck/should_fail/T21530a.stderr - testsuite/tests/typecheck/should_fail/T3950.stderr - testsuite/tests/typecheck/should_fail/T7368.stderr - testsuite/tests/typecheck/should_fail/T7368a.stderr Changes: ===================================== compiler/GHC/Tc/Solver/InertSet.hs ===================================== @@ -8,7 +8,8 @@ module GHC.Tc.Solver.InertSet ( -- * The work list WorkList(..), isEmptyWorkList, emptyWorkList, extendWorkListNonEq, extendWorkListCt, - extendWorkListCts, extendWorkListEq, extendWorkListEqs, + extendWorkListCts, extendWorkListCtList, + extendWorkListEq, extendWorkListEqs, appendWorkList, extendWorkListImplic, workListSize, selectWorkItem, @@ -192,7 +193,7 @@ extendWorkListImplic :: Implication -> WorkList -> WorkList extendWorkListImplic implic wl = wl { wl_implics = implic `consBag` wl_implics wl } extendWorkListCt :: Ct -> WorkList -> WorkList --- Agnostic +-- Agnostic about what kind of constraint extendWorkListCt ct wl = case classifyPredType (ctPred ct) of EqPred {} @@ -204,8 +205,10 @@ extendWorkListCt ct wl _ -> extendWorkListNonEq ct wl -extendWorkListCts :: [Ct] -> WorkList -> WorkList --- Agnostic +extendWorkListCtList :: [Ct] -> WorkList -> WorkList +extendWorkListCtList cts wl = foldr extendWorkListCt wl cts + +extendWorkListCts :: Cts -> WorkList -> WorkList extendWorkListCts cts wl = foldr extendWorkListCt wl cts isEmptyWorkList :: WorkList -> Bool @@ -1331,11 +1334,11 @@ kickOutRewritableLHS new_fr new_lhs -- constraints, which perhaps may have become soluble after new_lhs -- is substituted; ditto the dictionaries, which may include (a~b) -- or (a~~b) constraints. - kicked_out = foldr extendWorkListCt - (emptyWorkList { wl_eqs = map CEqCan tv_eqs_out ++ - map CEqCan feqs_out }) + kicked_out = extendWorkListCts ((dicts_out `andCts` irs_out) `extendCtsList` insts_out) + (emptyWorkList { wl_eqs = map CEqCan tv_eqs_out ++ + map CEqCan feqs_out }) (tv_eqs_out, tv_eqs_in) = partitionInertEqs kick_out_eq tv_eqs (feqs_out, feqs_in) = partitionFunEqs kick_out_eq funeqmap ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -153,7 +153,7 @@ solveSimples :: Cts -> TcS () solveSimples cts = {-# SCC "solveSimples" #-} - do { updWorkListTcS (\wl -> foldr extendWorkListCt wl cts) + do { updWorkListTcS (extendWorkListCts cts) ; solve_loop } where solve_loop ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -168,6 +168,7 @@ import GHC.Types.Name.Reader import GHC.Types.Var import GHC.Types.Var.Set import GHC.Types.Unique.Supply +import GHC.Types.Unique.Set( elementOfUniqSet ) import GHC.Unit.Module ( HasModule, getModule, extractModule ) import qualified GHC.Rename.Env as TcM @@ -422,10 +423,10 @@ kickOutAfterFillingCoercionHole :: CoercionHole -> TcS () kickOutAfterFillingCoercionHole hole = do { ics <- getInertCans ; let (kicked_out, ics') = kick_out ics - n_kicked = workListSize kicked_out + n_kicked = lengthBag kicked_out ; unless (n_kicked == 0) $ - do { updWorkListTcS (appendWorkList kicked_out) + do { updWorkListTcS (extendWorkListCts kicked_out) ; csTraceTcS $ hang (text "Kick out, hole =" <+> ppr hole) 2 (vcat [ text "n-kicked =" <+> int n_kicked @@ -434,19 +435,39 @@ kickOutAfterFillingCoercionHole hole ; setInertCans ics' } where + kick_out :: InertCans -> (Cts, InertCans) + kick_out ics@(IC { inert_irreds = irreds }) + = (irreds_to_kick, ics { inert_irreds = irreds_to_keep }) + where + (irreds_to_kick, irreds_to_keep) = partitionBag kick_ct irreds + + kick_ct :: Ct -> Bool + -- True: kick out; False: keep. + kick_ct ct + | CIrredCan { cc_ev = ev, cc_reason = reason } <- ct + , CtWanted { ctev_rewriters = RewriterSet rewriters } <- ev + , NonCanonicalReason ctyeq <- reason + , ctyeq `cterHasProblem` cteCoercionHole + , hole `elementOfUniqSet` rewriters + = True + | otherwise + = False + +{- kick_out :: InertCans -> (WorkList, InertCans) kick_out ics@(IC { inert_eqs = eqs, inert_funeqs = funeqs }) = (kicked_out, ics { inert_eqs = eqs_to_keep, inert_funeqs = funeqs_to_keep }) where (eqs_to_kick, eqs_to_keep) = partitionInertEqs kick_ct eqs (funeqs_to_kick, funeqs_to_keep) = partitionFunEqs kick_ct funeqs - kicked_out = extendWorkListCts (map CEqCan (eqs_to_kick ++ funeqs_to_kick)) emptyWorkList + kicked_out = extendWorkListCtList (map CEqCan (eqs_to_kick ++ funeqs_to_kick)) emptyWorkList kick_ct :: EqCt -> Bool -- True: kick out; False: keep. kick_ct (EqCt { eq_rhs = rhs, eq_ev = ctev }) = isWanted ctev && -- optimisation: givens don't have coercion holes anyway rhs `hasThisCoercionHoleTy` hole +-} -------------- addInertSafehask :: InertCans -> Ct -> InertCans @@ -1259,7 +1280,7 @@ emitWork :: [Ct] -> TcS () emitWork [] = return () -- avoid printing, among other work emitWork cts = do { traceTcS "Emitting fresh work" (vcat (map ppr cts)) - ; updWorkListTcS (extendWorkListCts cts) } + ; updWorkListTcS (extendWorkListCtList cts) } emitImplication :: Implication -> TcS () emitImplication implic ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -1000,6 +1000,11 @@ data FixedRuntimeRepOrigin -- ^ What context requires a fixed runtime representation? } +instance Outputable FixedRuntimeRepOrigin where + ppr (FixedRuntimeRepOrigin { frr_type = ty, frr_context = cxt }) + = text "FrOrigin" <> braces (vcat [ text "frr_type:" <+> ppr ty + , text "frr_context:" <+> ppr cxt ]) + -- | The context in which a representation-polymorphism check was performed. -- -- Does not include the type on which the check was performed; see ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -524,7 +524,8 @@ ensureConcrete :: HasDebugCallStack -> TcType -> TcM TcType ensureConcrete frr_orig ty - = do { (ty', errs) <- makeTypeConcrete conc_orig ty + = do { traceTc "ensureConcrete {" (ppr frr_orig $$ ppr ty) + ; (ty', errs) <- makeTypeConcrete conc_orig ty ; case errs of { err:errs -> do { traceTc "ensureConcrete } failure" $ ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -2931,8 +2931,8 @@ checkCo (TEF { tef_lhs = TyVarLHS lhs_tv , tef_occurs = occ_prob }) co -- Check for coercion holes, if unifying -- See (COERCION-HOLE) in Note [Unification preconditions] - | Unifying {} <- unifying - , hasCoercionHoleCo co + | -- Unifying {} <- unifying + hasCoercionHoleCo co = failCheckWith (cteProblem cteCoercionHole) -- Occurs check (can promote) ===================================== testsuite/tests/polykinds/T9017.stderr ===================================== @@ -1,12 +1,12 @@ T9017.hs:8:7: error: [GHC-25897] - • Couldn't match kind ‘k2’ with ‘*’ + • Couldn't match kind ‘k1’ with ‘*’ When matching types a0 :: * -> * -> * a :: k1 -> k2 -> * Expected: a b (m b) Actual: a0 b0 (m0 b0) - ‘k2’ is a rigid type variable bound by + ‘k1’ is a rigid type variable bound by the type signature for: foo :: forall {k1} {k2} (a :: k1 -> k2 -> *) (b :: k1) (m :: k1 -> k2). ===================================== testsuite/tests/typecheck/should_fail/T21530a.stderr ===================================== @@ -1,6 +1,6 @@ T21530a.hs:14:7: error: [GHC-18872] - • Couldn't match kind ‘*’ with ‘Constraint’ + • Couldn't match kind ‘Constraint’ with ‘*’ When matching types a0 :: * Eq Int :: Constraint ===================================== testsuite/tests/typecheck/should_fail/T3950.stderr ===================================== @@ -1,6 +1,6 @@ T3950.hs:16:13: error: [GHC-18872] - • Couldn't match kind ‘* -> *’ with ‘*’ + • Couldn't match kind ‘*’ with ‘* -> *’ When matching types w :: (* -> * -> *) -> * Sealed :: (* -> *) -> * ===================================== testsuite/tests/typecheck/should_fail/T7368.stderr ===================================== @@ -1,6 +1,6 @@ T7368.hs:3:10: error: [GHC-18872] - • Couldn't match kind ‘*’ with ‘* -> *’ + • Couldn't match kind ‘* -> *’ with ‘*’ When matching types b0 :: * Maybe :: * -> * ===================================== testsuite/tests/typecheck/should_fail/T7368a.stderr ===================================== @@ -1,6 +1,6 @@ T7368a.hs:8:6: error: [GHC-18872] - • Couldn't match kind ‘*’ with ‘* -> *’ + • Couldn't match kind ‘* -> *’ with ‘*’ When matching types f :: * -> * Bad :: (* -> *) -> * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ab0c9d2e30e2e25f78e5dfa6f2f76e891c8dcfe...8e27d5409352d6c268d33d43c2b5c30fa42a2f43 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ab0c9d2e30e2e25f78e5dfa6f2f76e891c8dcfe...8e27d5409352d6c268d33d43c2b5c30fa42a2f43 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 09:01:31 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Apr 2023 05:01:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: Add support for -debug in the testsuite Message-ID: <6436736bcb37a_35453018dbabb0230652@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - e8617a2f by Sebastian Graf at 2023-04-12T05:01:14-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 3b3a7c83 by Rodrigo Mesquita at 2023-04-12T05:01:15-04:00 Add regression test for #23229 - - - - - 27 changed files: - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Wasm/ControlFlow/FromCmm.hs - hadrian/src/Oracles/TestSettings.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/base.cabal - rts/Printer.c - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/ghc-config/ghc-config.hs - testsuite/mk/test.mk - + testsuite/tests/ghci/should_run/T23229.hs - + testsuite/tests/ghci/should_run/T23229.script - testsuite/tests/ghci/should_run/all.T - testsuite/tests/rts/Makefile - + testsuite/tests/rts/T23142.hs - + testsuite/tests/rts/T23142.stdout - testsuite/tests/rts/all.T - testsuite/tests/stranal/should_compile/T18894.stderr - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/Wasm/FromCmm.hs ===================================== @@ -48,6 +48,7 @@ import GHC.Types.ForeignCall import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Map +import GHC.Types.Unique.Supply import GHC.Utils.Outputable hiding ((<>)) import GHC.Utils.Panic import GHC.Wasm.ControlFlow.FromCmm @@ -1328,7 +1329,7 @@ lower_CmmUnsafeForeignCall_Drop :: [CmmActual] -> WasmCodeGenM w (WasmStatements w) lower_CmmUnsafeForeignCall_Drop lbl sym_callee ret_cmm_ty arg_exprs = do - ret_uniq <- wasmUniq + ret_uniq <- getUniqueM let ret_local = LocalReg ret_uniq ret_cmm_ty lower_CmmUnsafeForeignCall lbl @@ -1528,9 +1529,11 @@ lower_CmmGraph :: CLabel -> CmmGraph -> WasmCodeGenM w (FuncBody w) lower_CmmGraph lbl g = do ty_word <- wasmWordTypeM platform <- wasmPlatformM + us <- getUniqueSupplyM body <- structuredControl platform + us (\_ -> lower_CmmExpr_Typed lbl ty_word) (lower_CmmActions lbl) g ===================================== compiler/GHC/CmmToAsm/Wasm/Types.hs ===================================== @@ -45,7 +45,6 @@ module GHC.CmmToAsm.Wasm.Types wasmStateM, wasmModifyM, wasmExecM, - wasmUniq, ) where @@ -466,10 +465,18 @@ wasmStateM = coerce . State wasmModifyM :: (WasmCodeGenState w -> WasmCodeGenState w) -> WasmCodeGenM w () wasmModifyM = coerce . modify +wasmEvalM :: WasmCodeGenM w a -> WasmCodeGenState w -> a +wasmEvalM (WasmCodeGenM s) = evalState s + wasmExecM :: WasmCodeGenM w a -> WasmCodeGenState w -> WasmCodeGenState w wasmExecM (WasmCodeGenM s) = execState s -wasmUniq :: WasmCodeGenM w Unique -wasmUniq = wasmStateM $ - \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of - (u, us) -> (# u, s {wasmUniqSupply = us} #) +instance MonadUnique (WasmCodeGenM w) where + getUniqueSupplyM = wasmGetsM wasmUniqSupply + getUniqueM = wasmStateM $ + \s at WasmCodeGenState {..} -> case takeUniqFromSupply wasmUniqSupply of + (u, us) -> (# u, s {wasmUniqSupply = us} #) + getUniquesM = do + u <- getUniqueM + s <- WasmCodeGenM get + pure $ u:(wasmEvalM getUniquesM s) ===================================== compiler/GHC/Core/InstEnv.hs ===================================== @@ -849,8 +849,10 @@ Here are the moving parts: * `GHC.HsToCore.Binds.dsHsWrapper` desugars the evidence application (f d) into (nospec f d) if `d` is incoherent. It has to do a dependency analysis to - determine transitive dependencies, but we need to do that anway. + determine transitive dependencies, but we need to do that anyway. See Note [Desugaring incoherent evidence] in GHC.HsToCore.Binds. + + See also Note [nospecId magic] in GHC.Types.Id.Make. -} type DFunInstType = Maybe Type ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,33 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> PlusDmdArg + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = keepAlive env (filter is_root ids) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +keepAlive :: AnalEnv -> [Id] -> PlusDmdArg +-- See Note [Absence analysis for stable unfoldings and RULES] +keepAlive _ [] = (emptyVarEnv, topDiv) +keepAlive env ids + = foldl1' plusDmdArg $ fmap (fst . dmdAnalStar env topDmd . Var) ids + +keepAliveSet :: AnalEnv -> IdSet -> PlusDmdArg +keepAliveSet env ids = keepAlive env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +348,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` keepAliveSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -415,7 +420,7 @@ dmdAnalStar env (n :* sd) e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -532,7 +537,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +574,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1103,7 +1108,8 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs NonRecursive -> rhs_fv -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + -- Since the result of keepAliveSet will have topDiv, rhs_div == _rhs_div' + (rhs_fv2, _rhs_div') = (rhs_fv1, rhs_div) `plusDmdArg` keepAliveSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 @@ -1365,8 +1371,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to do +absence analysis for stable unfoldings. Consider g = blah @@ -1383,9 +1389,8 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. +SOLUTION: if f has a stable unfolding, analyse every free variable as if it +was a variable occuring in a 'topDmd' context. This is done in `keepAlive`. ALSO: do the same for Ids free in the RHS of any RULES for f. @@ -1401,6 +1406,28 @@ Now f's optimised RHS will be \x.a, but if we change g to (error "..") disaster. But regardless, #18638 was a more complicated version of this, that actually happened in practice. +PPS: You might wonder why we don't simply take the free vars of the +unfolding/RULE and map them to topDmd. The reason is that any of the free vars +might have demand signatures themselves that in turn keep transitive free +variables alive and that we hence need to unleash! This came up in #23208. +Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + +Here, `err` is only kept alive by `sg`'s demand signature: It doesn't occur +in the lazy_fvs of `sg`'s RHS at all. Hence when we `keepAlive` `sg` because it +occurs in the RULEs of `g` (which is exported), we better unleash the demand +signature of `sg`, too! In #23208 we failed to do so and observed an absent +error instead of the `really important message`. + Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We give DataCon wrappers a (necessarily flat) demand signature in ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -44,8 +44,7 @@ module GHC.Types.Demand ( unboxDeeplyDmd, -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, + DmdEnv, emptyDmdEnv, reuseEnv, -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, @@ -56,10 +55,9 @@ module GHC.Types.Demand ( nopDmdType, botDmdType, lubDmdType, plusDmdType, multDmdType, -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + PlusDmdArg, mkPlusDmdArg, discardArgDmds, plusDmdArg, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +83,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1466,7 +1463,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1750,23 +1747,6 @@ multDmdEnv n env = mapVarEnv (multDmd n) env reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd - - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd - -- | Characterises how an expression -- -- * Evaluates its free variables ('dt_env') @@ -1811,20 +1791,27 @@ type PlusDmdArg = (DmdEnv, Divergence) mkPlusDmdArg :: DmdEnv -> PlusDmdArg mkPlusDmdArg env = (env, topDiv) -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) +discardArgDmds :: DmdType -> PlusDmdArg +discardArgDmds (DmdType fv _ r) = (fv, r) plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient +plusDmdType (DmdType fv ds d) pda + -- See Note [Asymmetry of plusDmdType] + -- 'plus' takes the argument demands from its *first* arg, using its second + -- arg just for its free-var info and divergence. + | (fv', d') <- plusDmdArg (fv,d) pda + = DmdType fv' ds d' + +plusDmdArg :: PlusDmdArg -> PlusDmdArg -> PlusDmdArg +plusDmdArg (fv1, d1) (fv2, d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = (fv1, d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = (fv2, d1 `plusDivergence` d2) -- another very common case that is much more efficient | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) + = ( plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + , d1 `plusDivergence` d2) botDmdType :: DmdType botDmdType = DmdType emptyDmdEnv [] botDiv @@ -1914,11 +1901,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1999,7 +1981,7 @@ Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -2002,10 +2002,15 @@ Note that this happens *after* unfoldings are exposed in the interface file. This is crucial: otherwise, we could import an unfolding in which 'nospec' has been inlined (= erased), and we would lose the benefit. -'nospec' is used in the implementation of 'withDict': we insert 'nospec' -so that the typeclass specialiser doesn't assume any two evidence terms -of the same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, -and see test case T21575b for an example. +'nospec' is used: + +* In the implementation of 'withDict': we insert 'nospec' so that the + typeclass specialiser doesn't assume any two evidence terms of the + same type are equal. See Note [withDict] in GHC.Tc.Instance.Class, + and see test case T21575b for an example. + +* To defeat the specialiser when we have incoherent instances. + See Note [Coherence and specialisation: overview] in GHC.Core.InstEnv. Note [The oneShot function] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Wasm/ControlFlow/FromCmm.hs ===================================== @@ -19,12 +19,13 @@ import GHC.Cmm.Dataflow.Collections import GHC.Cmm.Dominators import GHC.Cmm.Dataflow.Graph import GHC.Cmm.Dataflow.Label +import GHC.Cmm.Reducibility import GHC.Cmm.Switch import GHC.CmmToAsm.Wasm.Types import GHC.Platform - +import GHC.Types.Unique.Supply import GHC.Utils.Misc import GHC.Utils.Panic import GHC.Utils.Outputable ( Outputable, text, (<+>), ppr @@ -140,15 +141,19 @@ emptyPost _ = False structuredControl :: forall expr stmt m . Applicative m => Platform -- ^ needed for offset calculation + -> UniqSupply -> (Label -> CmmExpr -> m expr) -- ^ translator for expressions -> (Label -> CmmActions -> m stmt) -- ^ translator for straight-line code -> CmmGraph -- ^ CFG to be translated -> m (WasmControl stmt expr '[] '[ 'I32]) -structuredControl platform txExpr txBlock g = +structuredControl platform us txExpr txBlock g' = doTree returns dominatorTree emptyContext where + g :: CmmGraph + g = gwd_graph gwd + gwd :: GraphWithDominators CmmNode - gwd = graphWithDominators g + gwd = initUs_ us $ asReducible $ graphWithDominators g' dominatorTree :: Tree.Tree CmmBlock-- Dominator tree in which children are sorted -- with highest reverse-postorder number first ===================================== hadrian/src/Oracles/TestSettings.hs ===================================== @@ -25,8 +25,9 @@ data TestSetting = TestHostOS | TestTARGETPLATFORM | TestTargetOS_CPP | TestTargetARCH_CPP + | TestRTSWay | TestGhcStage - | TestGhcDebugged + | TestGhcDebugAssertions | TestGhcWithNativeCodeGen | TestGhcWithInterpreter | TestGhcWithRtsLinker @@ -56,8 +57,9 @@ testSetting key = do TestTARGETPLATFORM -> "TARGETPLATFORM" TestTargetOS_CPP -> "TargetOS_CPP" TestTargetARCH_CPP -> "TargetARCH_CPP" + TestRTSWay -> "RTSWay" TestGhcStage -> "GhcStage" - TestGhcDebugged -> "GhcDebugged" + TestGhcDebugAssertions -> "GhcDebugAssertions" TestGhcWithNativeCodeGen -> "GhcWithNativeCodeGen" TestGhcWithInterpreter -> "GhcWithInterpreter" TestGhcWithRtsLinker -> "GhcWithRtsLinker" ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -69,6 +69,9 @@ data TestCompilerArgs = TestCompilerArgs{ , unregisterised :: Bool , tables_next_to_code :: Bool , targetWithSMP :: Bool -- does the target support SMP + , debugged :: Bool + -- ^ Whether the compiler has the debug RTS, + -- corresponding to the -debug option. , debugAssertions :: Bool -- ^ Whether the compiler has debug assertions enabled, -- corresponding to the -DDEBUG option. @@ -104,6 +107,7 @@ inTreeCompilerArgs stg = do let ghcStage = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage + debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage os <- setting HostOs @@ -149,12 +153,14 @@ outOfTreeCompilerArgs = do unregisterised <- getBooleanSetting TestGhcUnregisterised tables_next_to_code <- getBooleanSetting TestGhcTablesNextToCode targetWithSMP <- targetSupportsSMP - debugAssertions <- getBooleanSetting TestGhcDebugged + debugAssertions <- getBooleanSetting TestGhcDebugAssertions os <- getTestSetting TestHostOS arch <- getTestSetting TestTargetARCH_CPP platform <- getTestSetting TestTARGETPLATFORM wordsize <- getTestSetting TestWORDSIZE + rtsWay <- getTestSetting TestRTSWay + let debugged = "debug" `isInfixOf` rtsWay llc_cmd <- getTestSetting TestLLC have_llvm <- liftIO (isJust <$> findExecutable llc_cmd) @@ -243,6 +249,7 @@ runTestBuilderArgs = builder Testsuite ? do , arg "-e", arg $ "config.accept_os=" ++ show acceptOS , arg "-e", arg $ "config.exeext=" ++ quote (if null exe then "" else "."<>exe) , arg "-e", arg $ "config.compiler_debugged=" ++ show debugAssertions + , arg "-e", arg $ "config.debug_rts=" ++ show debugged -- MP: TODO, we do not need both, they get aliased to the same thing. , arg "-e", arg $ asBool "ghc_with_native_codegen=" withNativeCodeGen ===================================== libraries/base/base.cabal ===================================== @@ -5,8 +5,8 @@ version: 4.18.0.0 license: BSD-3-Clause license-file: LICENSE -maintainer: libraries at haskell.org -bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new +maintainer: Core Libraries Committee +bug-reports: https://github.com/haskell/core-libraries-committee/issues synopsis: Basic libraries category: Prelude build-type: Configure ===================================== rts/Printer.c ===================================== @@ -297,6 +297,45 @@ printClosure( const StgClosure *obj ) break; } + case ATOMICALLY_FRAME: + { + StgAtomicallyFrame* u = (StgAtomicallyFrame*)obj; + debugBelch("ATOMICALLY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->result); + debugBelch(")\n"); + break; + } + + case CATCH_RETRY_FRAME: + { + StgCatchRetryFrame* u = (StgCatchRetryFrame*)obj; + debugBelch("CATCH_RETRY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->first_code); + debugBelch(","); + printPtr((StgPtr)u->alt_code); + debugBelch(")\n"); + break; + } + + case CATCH_STM_FRAME: + { + StgCatchSTMFrame* u = (StgCatchSTMFrame*)obj; + debugBelch("CATCH_STM_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)u)); + debugBelch(","); + printPtr((StgPtr)u->code); + debugBelch(","); + printPtr((StgPtr)u->handler); + debugBelch(")\n"); + break; + } + case ARR_WORDS: { StgWord i; @@ -319,6 +358,10 @@ printClosure( const StgClosure *obj ) debugBelch("MUT_ARR_PTRS_FROZEN_CLEAN(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); break; + case MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", (W_)((StgMutArrPtrs *)obj)->ptrs); + break; + case SMALL_MUT_ARR_PTRS_CLEAN: debugBelch("SMALL_MUT_ARR_PTRS_CLEAN(size=%" FMT_Word ")\n", (W_)((StgSmallMutArrPtrs *)obj)->ptrs); @@ -334,6 +377,11 @@ printClosure( const StgClosure *obj ) (W_)((StgSmallMutArrPtrs *)obj)->ptrs); break; + case SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: + debugBelch("SMALL_MUT_ARR_PTRS_FROZEN_DIRTY(size=%" FMT_Word ")\n", + (W_)((StgSmallMutArrPtrs *)obj)->ptrs); + break; + case MVAR_CLEAN: case MVAR_DIRTY: { @@ -533,6 +581,9 @@ printStackChunk( StgPtr sp, StgPtr spBottom ) case CATCH_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: + case ATOMICALLY_FRAME: + case CATCH_RETRY_FRAME: + case CATCH_STM_FRAME: printClosure((StgClosure*)sp); continue; ===================================== testsuite/driver/testglobals.py ===================================== @@ -64,6 +64,9 @@ class TestConfig: # Was the compiler compiled with DEBUG? self.compiler_debugged = False + # Was the compiler compiled with -debug? + self.debug_rts = False + # Was the compiler compiled with LLVM? self.ghc_built_by_llvm = False ===================================== testsuite/driver/testlib.py ===================================== @@ -681,6 +681,9 @@ def compiler_profiled( ) -> bool: def compiler_debugged( ) -> bool: return config.compiler_debugged +def debug_rts( ) -> bool: + return config.debug_rts + def have_gdb( ) -> bool: return config.have_gdb ===================================== testsuite/ghc-config/ghc-config.hs ===================================== @@ -13,12 +13,13 @@ main = do getGhcFieldOrFail fields "TARGETPLATFORM" "Target platform" getGhcFieldOrFail fields "TargetOS_CPP" "Target OS" getGhcFieldOrFail fields "TargetARCH_CPP" "Target architecture" + getGhcFieldOrFail fields "RTSWay" "RTS way" info <- readProcess ghc ["--info"] "" let fields = read info :: [(String,String)] getGhcFieldOrFail fields "GhcStage" "Stage" - getGhcFieldOrFail fields "GhcDebugged" "Debug on" + getGhcFieldOrFail fields "GhcDebugAssertions" "Debug on" getGhcFieldOrFail fields "GhcWithNativeCodeGen" "Have native code generator" getGhcFieldOrFail fields "GhcWithInterpreter" "Have interpreter" getGhcFieldOrFail fields "GhcWithRtsLinker" "target has RTS linker" ===================================== testsuite/mk/test.mk ===================================== @@ -78,7 +78,7 @@ endif RUNTEST_OPTS += -e "ghc_compiler_always_flags='$(TEST_HC_OPTS)'" -ifeq "$(GhcDebugged)" "YES" +ifeq "$(GhcDebugAssertions)" "YES" RUNTEST_OPTS += -e "config.compiler_debugged=True" else RUNTEST_OPTS += -e "config.compiler_debugged=False" ===================================== testsuite/tests/ghci/should_run/T23229.hs ===================================== @@ -0,0 +1 @@ +instance Num Bool ===================================== testsuite/tests/ghci/should_run/T23229.script ===================================== @@ -0,0 +1 @@ +:l T23229 ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -88,3 +88,4 @@ test('UnliftedDataType2', just_ghci, compile_and_run, ['']) test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) +test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) ===================================== testsuite/tests/rts/Makefile ===================================== @@ -147,3 +147,13 @@ EventlogOutput_IPE: "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log + +.PHONY: T23142 +T23142: + # Test that the -Di output contains different frames + "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + grep -m1 -c "ATOMICALLY_FRAME" T23142.log + grep -m1 -c "CATCH_RETRY_FRAME" T23142.log + grep -m1 -c "CATCH_STM_FRAME" T23142.log + grep -m1 -c "MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log + grep -m1 -c "SMALL_MUT_ARR_PTRS_FROZEN_DIRTY" T23142.log ===================================== testsuite/tests/rts/T23142.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE UnboxedTuples, MagicHash #-} +module T23142 where + +import GHC.IO +import GHC.Exts + +main :: IO () +main = IO (\s -> case newArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (\s -> case newSmallArray# 10# (2 :: Int) s of + (# s', a #) -> case unsafeFreezeSmallArray# a s' of + (# s'', _ #) -> (# s'', () #)) + >> + IO (atomically# (\s -> catchSTM# (\s -> (# s, () #)) (\_ s -> (# s, () #)) s)) + >> + IO (atomically# (\s -> catchRetry# (\s -> (# s, () #)) (\s -> (# s, () #)) s)) ===================================== testsuite/tests/rts/T23142.stdout ===================================== @@ -0,0 +1,5 @@ +1 +1 +1 +1 +1 ===================================== testsuite/tests/rts/all.T ===================================== @@ -575,3 +575,5 @@ test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-thr test('T22795c', [only_ways(['normal']), js_skip], compile_and_run, ['-threaded -single-threaded']) test('T17574', [js_skip], compile_and_run, ['-with-rtsopts -T']) + +test('T23142', [unless(debug_rts(), skip), req_interp], makefile_test, ['T23142']) ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6ab90e6a4dd8902d8f785f5e6a421f1d95cb844...3b3a7c83711ea7479f02ec5271cfc0e0b686cc34 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6ab90e6a4dd8902d8f785f5e6a421f1d95cb844...3b3a7c83711ea7479f02ec5271cfc0e0b686cc34 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 10:09:03 2023 From: gitlab at gitlab.haskell.org (David (@knothed)) Date: Wed, 12 Apr 2023 06:09:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/or-pats-amendment Message-ID: <6436833f1c5b7_35453019e99b20255445@gitlab.mail> David pushed new branch wip/or-pats-amendment at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/or-pats-amendment You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 10:45:40 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 06:45:40 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] Fix thunk update ordering Message-ID: <64368bd459e55_3545301a80c004259110@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 589a4dc3 by Ben Gamari at 2023-04-12T06:45:32-04:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - 16 changed files: - compiler/GHC/StgToCmm/Bind.hs - rts/Apply.cmm - rts/Compact.cmm - rts/Heap.c - rts/Interpreter.c - rts/PrimOps.cmm - rts/StableName.c - rts/StgMiscClosures.cmm - rts/ThreadPaused.c - rts/Threads.c - rts/Updates.cmm - rts/Updates.h - rts/include/Cmm.h - rts/include/stg/SMP.h - rts/sm/NonMovingMark.c - utils/genapply/Main.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -702,11 +702,19 @@ emitBlackHoleCode node = do when eager_blackholing $ do whenUpdRemSetEnabled $ emitUpdRemSetPushThunk node - emitStore (cmmOffsetW platform node (fixedHdrSizeW profile)) (currentTSOExpr platform) + emitAtomicStore platform MemOrderSeqCst + (cmmOffsetW platform node (fixedHdrSizeW profile)) + (currentTSOExpr platform) -- See Note [Heap memory barriers] in SMP.h. - let w = wordWidth platform - emitPrimCall [] (MO_AtomicWrite w MemOrderRelease) - [node, CmmReg (CmmGlobal $ GlobalRegUse EagerBlackholeInfo $ bWord platform)] + emitAtomicStore platform MemOrderRelaxed + node + (CmmReg (CmmGlobal $ GlobalRegUse EagerBlackholeInfo $ bWord platform)) + +emitAtomicStore :: Platform -> MemoryOrdering -> CmmExpr -> CmmExpr -> FCode () +emitAtomicStore platform mord addr val = + emitPrimCall [] (MO_AtomicWrite w mord) [addr, val] + where + w = typeWidth $ cmmExprType platform val setupUpdate :: ClosureInfo -> LocalReg -> FCode () -> FCode () -- Nota Bene: this function does not change Node (even if it's a CAF), ===================================== rts/Apply.cmm ===================================== @@ -108,7 +108,7 @@ again: IND, IND_STATIC: { - fun = StgInd_indirectee(fun); + fun = %acquire StgInd_indirectee(fun); goto again; } case BCO: @@ -693,7 +693,7 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK") } // Can't add StgInd_indirectee(ap) to UpdRemSet here because the old value is // not reachable. - StgInd_indirectee(ap) = CurrentTSO; + %release StgInd_indirectee(ap) = CurrentTSO; SET_INFO_RELEASE(ap, __stg_EAGER_BLACKHOLE_info); /* ensure there is at least AP_STACK_SPLIM words of headroom available ===================================== rts/Compact.cmm ===================================== @@ -100,7 +100,7 @@ eval: // Follow indirections: case IND, IND_STATIC: { - p = StgInd_indirectee(p); + p = %acquire StgInd_indirectee(p); goto eval; } ===================================== rts/Heap.c ===================================== @@ -173,7 +173,7 @@ StgWord collect_pointers(StgClosure *closure, StgClosure *ptrs[]) { case IND: case IND_STATIC: case BLACKHOLE: - ptrs[nptrs++] = (StgClosure *)(((StgInd *)closure)->indirectee); + ptrs[nptrs++] = (StgClosure *) ACQUIRE_LOAD(&((StgInd *)closure)->indirectee); break; case MUT_ARR_PTRS_CLEAN: ===================================== rts/Interpreter.c ===================================== @@ -401,7 +401,7 @@ eval_obj: case IND: case IND_STATIC: { - tagged_obj = ((StgInd*)obj)->indirectee; + tagged_obj = ACQUIRE_LOAD(&((StgInd*)obj)->indirectee); goto eval_obj; } ===================================== rts/PrimOps.cmm ===================================== @@ -1770,7 +1770,7 @@ loop: qinfo = GET_INFO_ACQUIRE(q); if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -1838,7 +1838,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -1940,7 +1940,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -2029,7 +2029,7 @@ loop: if (qinfo == stg_IND_info || qinfo == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } @@ -2309,7 +2309,7 @@ loop: //Possibly IND added by removeFromMVarBlockedQueue if (StgHeader_info(q) == stg_IND_info || StgHeader_info(q) == stg_MSG_NULL_info) { - q = StgInd_indirectee(q); + q = %acquire StgInd_indirectee(q); goto loop; } ===================================== rts/StableName.c ===================================== @@ -156,11 +156,11 @@ removeIndirections (StgClosure* p) switch (get_itbl(q)->type) { case IND: case IND_STATIC: - p = ((StgInd *)q)->indirectee; + p = ACQUIRE_LOAD(&((StgInd *)q)->indirectee); continue; case BLACKHOLE: - p = ((StgInd *)q)->indirectee; + p = ACQUIRE_LOAD(&((StgInd *)q)->indirectee); if (GET_CLOSURE_TAG(p) != 0) { continue; } else { ===================================== rts/StgMiscClosures.cmm ===================================== @@ -521,8 +521,8 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") (P_ node) { TICK_ENT_DYN_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - node = UNTAG(StgInd_indirectee(node)); + node = %acquire StgInd_indirectee(node); + node = UNTAG(node); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(node) (node); } @@ -530,8 +530,9 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") /* explicit stack */ { TICK_ENT_DYN_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - R1 = UNTAG(StgInd_indirectee(R1)); + P_ p; + p = %acquire StgInd_indirectee(R1); + R1 = UNTAG(p); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(R1) [R1]; } @@ -541,8 +542,9 @@ INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC") /* explicit stack */ { TICK_ENT_STATIC_IND(); /* tick */ - ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); - R1 = UNTAG(StgInd_indirectee(R1)); + P_ p; + p = %acquire StgInd_indirectee(R1); + R1 = UNTAG(p); TICK_ENT_VIA_NODE(); jump %GET_ENTRY(R1) [R1]; } @@ -567,8 +569,7 @@ INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE") retry: // Synchronizes with the release-store in updateWithIndirection. // See Note [Heap memory barriers] in SMP.h. - ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info); - p = %relaxed StgInd_indirectee(node); + p = %acquire StgInd_indirectee(node); if (GETTAG(p) != 0) { return (p); } ===================================== rts/ThreadPaused.c ===================================== @@ -352,7 +352,7 @@ threadPaused(Capability *cap, StgTSO *tso) OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info))); // The payload of the BLACKHOLE points to the TSO - ((StgInd *)bh)->indirectee = (StgClosure *)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: ===================================== rts/Threads.c ===================================== @@ -437,7 +437,7 @@ checkBlockingQueues (Capability *cap, StgTSO *tso) p = UNTAG_CLOSURE(bq->bh); const StgInfoTable *pinfo = ACQUIRE_LOAD(&p->header.info); if (pinfo != &stg_BLACKHOLE_info || - ((StgInd *)p)->indirectee != (StgClosure*)bq) + (RELAXED_LOAD(&((StgInd *)p)->indirectee) != (StgClosure*)bq)) { wakeBlockingQueue(cap,bq); } ===================================== rts/Updates.cmm ===================================== @@ -59,7 +59,7 @@ INFO_TABLE_RET ( stg_marked_upd_frame, UPDATE_FRAME, ASSERT(HpAlloc == 0); // Note [HpAlloc] // we know the closure is a BLACKHOLE - v = StgInd_indirectee(updatee); + v = %acquire StgInd_indirectee(updatee); if (GETTAG(v) != 0) (likely: False) { // updated by someone else: discard our value and use the ===================================== rts/Updates.h ===================================== @@ -59,8 +59,8 @@ } \ \ OVERWRITING_CLOSURE(p1); \ - %relaxed StgInd_indirectee(p1) = p2; \ - SET_INFO_RELEASE(p1, stg_BLACKHOLE_info); \ + %release StgInd_indirectee(p1) = p2; \ + %relaxed SET_INFO(p1, stg_BLACKHOLE_info); \ LDV_RECORD_CREATE(p1); \ and_then; ===================================== rts/include/Cmm.h ===================================== @@ -309,7 +309,7 @@ #define ENTER(x) ENTER_(return,x) #endif -#define ENTER_R1() ENTER_(RET_R1,R1) +#define ENTER_R1() P_ _r1; _r1 = R1; ENTER_(RET_R1, _r1) #define RET_R1(x) jump %ENTRY_CODE(Sp(0)) [R1] @@ -324,7 +324,7 @@ IND, \ IND_STATIC: \ { \ - x = StgInd_indirectee(x); \ + x = %acquire StgInd_indirectee(x); \ goto again; \ } \ case \ ===================================== rts/include/stg/SMP.h ===================================== @@ -178,6 +178,7 @@ EXTERN_INLINE void load_load_barrier(void); * - StgSmallMutArrPtrs: payload * - StgThunk although this is a somewhat special case; see below * - StgTSO: block_info + * - StgInd: indirectee * * Writing to a mutable pointer field must be done via a release-store. * Reading from such a field is done via an acquire-load. @@ -222,9 +223,9 @@ EXTERN_INLINE void load_load_barrier(void); * can see the indirectee. Consequently, a thunk update (see rts/Updates.h) * does the following: * - * 1. Use a relaxed-store to place the new indirectee into the thunk's + * 1. Use a release-store to place the new indirectee into the thunk's * indirectee field - * 2. use a release-store to set the info table to stg_BLACKHOLE (which + * 2. use a relaxed-store to set the info table to stg_BLACKHOLE (which * represents an indirection) * * Blackholing a thunk (either eagerly, by GHC.StgToCmm.Bind.emitBlackHoleCode, @@ -237,13 +238,10 @@ EXTERN_INLINE void load_load_barrier(void); * 1. We jump into the entry code of the indirection (e.g. stg_BLACKHOLE); * this of course implies that we have already read the thunk's info table * pointer, which is done with a relaxed load. - * 2. use an acquire-fence to ensure that our view on the thunk is - * up-to-date. This synchronizes with step (2) in the update - * procedure. - * 3. relaxed-load the indirectee. Since thunks are updated at most + * 2. acquire-load the indirectee. Since thunks are updated at most * once we know that the fence in the last step has given us * an up-to-date view of the indirectee closure. - * 4. enter the indirectee (or block if the indirectee is a TSO) + * 3. enter the indirectee (or block if the indirectee is a TSO) * * Other closures * -------------- @@ -270,7 +268,7 @@ EXTERN_INLINE void load_load_barrier(void); * in this primops. * * - Sending a Message to another capability: - * This is protected by the acquition and release of the target capability's + * This is protected by the acquision and release of the target capability's * lock in Messages.c:sendMessage. * * N.B. recordClosureMutated places a reference to the mutated object on ===================================== rts/sm/NonMovingMark.c ===================================== @@ -681,8 +681,9 @@ void updateRemembSetPushThunkEager(Capability *cap, case IND: { StgInd *ind = (StgInd *) thunk; - if (check_in_nonmoving_heap(ind->indirectee)) { - push_closure(queue, ind->indirectee, NULL); + StgClosure *indirectee = ACQUIRE_LOAD(&ind->indirectee); + if (check_in_nonmoving_heap(indirectee)) { + push_closure(queue, indirectee, NULL); } break; } ===================================== utils/genapply/Main.hs ===================================== @@ -783,7 +783,11 @@ genApply regstatus args = text "case IND,", text " IND_STATIC: {", nest 4 (vcat [ - text "R1 = StgInd_indirectee(R1);", + -- N.B. annoyingly the %acquire syntax must place its result in a local register + -- as it is a Cmm prim call node. + text "P_ p;", + text "p = %acquire StgInd_indirectee(R1);", + text "R1 = p;", -- An indirection node might contain a tagged pointer text "goto again;" ]), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/589a4dc3c0caac8ffeb6dd260e6e5defacf5e224 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/589a4dc3c0caac8ffeb6dd260e6e5defacf5e224 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 12:07:43 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 08:07:43 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc-backports-9.4 Message-ID: <64369f0f51a93_10a80d1935f84953f6@gitlab.mail> Ben Gamari pushed new branch wip/gc-backports-9.4 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc-backports-9.4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 12:52:54 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Apr 2023 08:52:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Allow generation of TTH syntax with TH Message-ID: <6436a9a612f00_10a80d22dbc7810934a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 981f94a2 by Oleg Grenrus at 2023-04-12T08:52:47-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 006cd8bd by Rodrigo Mesquita at 2023-04-12T08:52:48-04:00 Add regression test for #23229 - - - - - 20 changed files: - compiler/GHC/ThToHs.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/ghci/should_run/T23229.hs - + testsuite/tests/ghci/should_run/T23229.script - testsuite/tests/ghci/should_run/all.T - + testsuite/tests/th/TH_typed1.hs - + testsuite/tests/th/TH_typed1.stdout - + testsuite/tests/th/TH_typed2.hs - + testsuite/tests/th/TH_typed2.stdout - + testsuite/tests/th/TH_typed3.hs - + testsuite/tests/th/TH_typed3.stderr - + testsuite/tests/th/TH_typed4.hs - + testsuite/tests/th/TH_typed4.stderr - + testsuite/tests/th/TH_typed5.hs - + testsuite/tests/th/TH_typed5.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1157,6 +1157,10 @@ cvtl e = wrapLA (cvt e) (L noSrcSpanA (DotFieldOcc noAnn (L noSrcSpanA (FieldLabelString (fsLit f))))) } cvt (ProjectionE xs) = return $ HsProjection noAnn $ fmap (L noSrcSpanA . DotFieldOcc noAnn . L noSrcSpanA . FieldLabelString . fsLit) xs + cvt (TypedSpliceE e) = do { e' <- parenthesizeHsExpr appPrec <$> cvtl e + ; return $ HsTypedSplice (noAnn, noAnn) e' } + cvt (TypedBracketE e) = do { e' <- cvtl e + ; return $ HsTypedBracket noAnn e' } {- | #16895 Ensure an infix expression's operator is a variable/constructor. Consider this example: ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -44,7 +44,7 @@ module Language.Haskell.TH.Lib ( appE, appTypeE, uInfixE, parensE, infixE, infixApp, sectionL, sectionR, lamE, lam1E, lamCaseE, lamCasesE, tupE, unboxedTupE, unboxedSumE, condE, multiIfE, letE, caseE, appsE, listE, sigE, recConE, recUpdE, stringE, - fieldExp, getFieldE, projectionE, + fieldExp, getFieldE, projectionE, typedSpliceE, typedBracketE, -- **** Ranges fromE, fromThenE, fromToE, fromThenToE, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -380,6 +380,12 @@ getFieldE e f = do projectionE :: Quote m => NonEmpty String -> m Exp projectionE xs = pure (ProjectionE xs) +typedSpliceE :: Quote m => m Exp -> m Exp +typedSpliceE = fmap TypedSpliceE + +typedBracketE :: Quote m => m Exp -> m Exp +typedBracketE = fmap TypedBracketE + -- ** 'arithSeqE' Shortcuts fromE :: Quote m => m Exp -> m Exp fromE x = do { a <- x; pure (ArithSeqE (FromR a)) } ===================================== libraries/template-haskell/Language/Haskell/TH/Ppr.hs ===================================== @@ -232,6 +232,8 @@ pprExp _ (LabelE s) = text "#" <> text s pprExp _ (ImplicitParamVarE n) = text ('?' : n) pprExp _ (GetFieldE e f) = pprExp appPrec e <> text ('.': f) pprExp _ (ProjectionE xs) = parens $ hcat $ map ((char '.'<>) . text) $ toList xs +pprExp _ (TypedBracketE e) = text "[||" <> ppr e <> text "||]" +pprExp _ (TypedSpliceE e) = text "$$" <> pprExp appPrec e pprFields :: [(Name,Exp)] -> Doc pprFields = sep . punctuate comma . map (\(s,e) -> pprName' Applied s <+> equals <+> ppr e) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -2385,6 +2385,8 @@ data Exp | ImplicitParamVarE String -- ^ @{ ?x }@ ( Implicit parameter ) | GetFieldE Exp String -- ^ @{ exp.field }@ ( Overloaded Record Dot ) | ProjectionE (NonEmpty String) -- ^ @(.x)@ or @(.x.y)@ (Record projections) + | TypedBracketE Exp -- ^ @[|| e ||]@ + | TypedSpliceE Exp -- ^ @$$e@ deriving( Show, Eq, Ord, Data, Generic ) type FieldExp = (Name,Exp) ===================================== libraries/template-haskell/changelog.md ===================================== @@ -8,6 +8,10 @@ This change enables TemplateHaskell support for `DuplicateRecordFields`. + * Add support for generating typed splices and brackets in untyped Template Haskell + Introduces `typedSpliceE :: Quote m => m Exp -> m Exp` and + `typedBracketE :: Quote m => m Exp -> m Exp` + ## 2.20.0.0 * The `Ppr.pprInfixT` function has gained a `Precedence` argument. ===================================== testsuite/tests/ghci/should_run/T23229.hs ===================================== @@ -0,0 +1 @@ +instance Num Bool ===================================== testsuite/tests/ghci/should_run/T23229.script ===================================== @@ -0,0 +1 @@ +:l T23229 ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -88,3 +88,4 @@ test('UnliftedDataType2', just_ghci, compile_and_run, ['']) test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) +test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) ===================================== testsuite/tests/th/TH_typed1.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $$( $(typedBracketE [| 'x' |]) ) ===================================== testsuite/tests/th/TH_typed1.stdout ===================================== @@ -0,0 +1 @@ +'x' ===================================== testsuite/tests/th/TH_typed2.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $( typedSpliceE $ typedBracketE [| 'y' |] ) ===================================== testsuite/tests/th/TH_typed2.stdout ===================================== @@ -0,0 +1 @@ +'y' ===================================== testsuite/tests/th/TH_typed3.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +-- test parenthesis around splice +main = do + print $( typedSpliceE $ typedBracketE [| 'z' |] ) + print $( typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |]) ) ===================================== testsuite/tests/th/TH_typed3.stderr ===================================== @@ -0,0 +1,9 @@ +TH_typed3.hs:9:12-53: Splicing expression + typedSpliceE $ typedBracketE [| 'z' |] ======> $$[|| 'z' ||] +TH_typed3.hs:10:12-69: Splicing expression + typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |]) + ======> + $$(id [|| 'z' ||]) +TH_typed3.hs:9:12-53: Splicing expression [|| 'z' ||] ======> 'z' +TH_typed3.hs:10:12-69: Splicing expression + id [|| 'z' ||] ======> 'z' ===================================== testsuite/tests/th/TH_typed4.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $$( $$(unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: Code Q (Code Q Char)) ) ===================================== testsuite/tests/th/TH_typed4.stderr ===================================== @@ -0,0 +1,10 @@ +TH_typed4.hs:7:20-96: Splicing expression + unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: + Code Q (Code Q Char) + ======> + [|| 'a' ||] +TH_typed4.hs:7:16-98: Splicing expression + $$(unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: + Code Q (Code Q Char)) + ======> + 'a' ===================================== testsuite/tests/th/TH_typed5.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH +import Language.Haskell.TH.Ppr + +main = do + putStrLn =<< fmap pprint (typedSpliceE $ typedBracketE [| 'z' |]) + putStrLn =<< fmap pprint (typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |])) ===================================== testsuite/tests/th/TH_typed5.stdout ===================================== @@ -0,0 +1,2 @@ +$$[||'z'||] +$$(GHC.Base.id [||'z'||]) ===================================== testsuite/tests/th/all.T ===================================== @@ -559,3 +559,8 @@ test('T22819', normal, compile, ['-v0']) test('TH_fun_par', normal, compile, ['']) test('T23036', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T23203', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed1', normal, compile_and_run, ['']) +test('TH_typed2', normal, compile_and_run, ['']) +test('TH_typed3', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed4', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed5', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b3a7c83711ea7479f02ec5271cfc0e0b686cc34...006cd8bd7d0f37f8eb281d52e41f21ea7c678502 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b3a7c83711ea7479f02ec5271cfc0e0b686cc34...006cd8bd7d0f37f8eb281d52e41f21ea7c678502 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 15:42:39 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 11:42:39 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/orig-thunk-info Message-ID: <6436d16f5b557_10a80d53643181352d4@gitlab.mail> Ben Gamari pushed new branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/orig-thunk-info You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 15:43:53 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 11:43:53 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/isNullaryRepDataCon Message-ID: <6436d1b9ab5c0_10a80d5362018137254@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/isNullaryRepDataCon You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 15:59:26 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 11:59:26 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6436d55e9b016_10a80d561c5c414383a@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: f9598a2c by Rodrigo Mesquita at 2023-04-12T16:59:17+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,24 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types + , all (isZeroBitTy . scaledThing) (dataConRepArgTys con) + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `arity > 0` (which will be 'True' of the wrapper and 'False' of the +worker) and only then for `isDataConId_maybe && isNullaryRepDataCon` (which is +true of both). This makes the order of the guards in `mkLFImported` crucial to +the correctness! + +-} + ------------- mkLFStringLit :: LambdaFormInfo mkLFStringLit = LFUnlifted ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -161,7 +161,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9598a2c1ade8d0e4cde8d99ad832f38cd992831 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9598a2c1ade8d0e4cde8d99ad832f38cd992831 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:03:11 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 12:03:11 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] compiler: Record original thunk info tables on stack Message-ID: <6436d63fae31d_10a80d56c1ee8144377@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: 21ccc687 by Ben Gamari at 2023-04-12T12:03:04-04:00 compiler: Record original thunk info tables on stack - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - rts/StgMiscClosures.cmm - rts/include/rts/storage/Closures.h - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -53,6 +53,7 @@ module GHC.Cmm.CLabel ( mkDirty_MUT_VAR_Label, mkMUT_VAR_CLEAN_infoLabel, mkNonmovingWriteBarrierEnabledLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, @@ -641,7 +642,7 @@ mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable -- Constructing Cmm Labels mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, - mkUpdInfoLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel, mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel, mkMAP_DIRTY_infoLabel, @@ -655,6 +656,7 @@ mkDirty_MUT_VAR_Label, mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData +mkOrigThunkInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_orig_thunk_info_frame") CmmInfo mkUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_upd_frame") CmmInfo mkBHUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_bh_upd_frame" ) CmmInfo mkIndStaticInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_IND_STATIC") CmmInfo ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -754,12 +754,33 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - let + let platform = profilePlatform profile + + let push_orig_thunk_info = True hdr = fixedHdrSize profile - frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + orig_info_frame_sz + | push_orig_thunk_info + = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + | otherwise = 0 + frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + frame2 = frame1 + orig_info_frame_sz -- - emitUpdateFrame (CmmStackSlot Old frame) lbl updatee - withUpdFrameOff frame body + emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee + when push_orig_thunk_info $ emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee + withUpdFrameOff frame2 body + +emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () +emitOrigThunkInfoFrame frame updatee = do + profile <- getProfile + cfg <- getStgToCmmConfig + let platform = profilePlatform profile + hdr = fixedHdrSize profile + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_orig_info (profileConstants profile) + align_check = stgToCmmAlignCheck cfg + info_ptr = cmmLoadBWord platform (closureInfoPtr platform align_check updatee) + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) info_ptr + initUpdFrameProf frame emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do ===================================== rts/StgMiscClosures.cmm ===================================== @@ -45,6 +45,16 @@ import CLOSURE stg_ret_t_info; import CLOSURE stg_ret_v_info; #endif +INFO_TABLE_RET (stg_orig_thunk_info_frame, RET_SMALL, + W_ info_ptr, + W_ thunk_info_ptr) + /* no args => explicit stack */ +{ + unwind Sp = W_[Sp + WDS(2)]; + Sp_adj(2); + jump %ENTRY_CODE(Sp(0)) [*]; // NB. all registers live! +} + /* ---------------------------------------------------------------------------- Stack underflow ------------------------------------------------------------------------- */ ===================================== rts/include/rts/storage/Closures.h ===================================== @@ -261,6 +261,13 @@ typedef struct _StgUpdateFrame { StgClosure *updatee; } StgUpdateFrame; +// Thunk update frame +// +// Closure types: RET_SMALL +typedef struct _StgOrigThunkInfoFrame { + StgHeader header; + StgInfoTable *info_ptr; +} StgOrigThunkInfoFrame; // Closure types: RET_SMALL typedef struct { ===================================== utils/deriveConstants/Main.hs ===================================== @@ -438,6 +438,7 @@ wanteds os = concat ,structField Both "StgEntCounter" "entry_count" ,closureSize Both "StgUpdateFrame" + ,closureSize Both "StgOrigThunkInfoFrame" ,closureSize C "StgCatchFrame" ,closureSize C "StgStopFrame" ,closureSize C "StgDeadThreadFrame" @@ -480,6 +481,7 @@ wanteds os = concat ,structSize C "StgTSOProfInfo" ,closureField Both "StgUpdateFrame" "updatee" + ,closureField Both "StgOrigThunkInfoFrame" "orig_info" ,closureField C "StgCatchFrame" "handler" ,closureField C "StgCatchFrame" "exceptions_blocked" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21ccc687996f0f8e6ff504644ad2339adba886af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/21ccc687996f0f8e6ff504644ad2339adba886af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:04:06 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 12:04:06 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] compiler: Record original thunk info tables on stack Message-ID: <6436d676bce61_10a80d56c1f3814482@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: 11da4583 by Ben Gamari at 2023-04-12T12:04:00-04:00 compiler: Record original thunk info tables on stack - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - rts/StgMiscClosures.cmm - rts/include/rts/storage/Closures.h - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -53,6 +53,7 @@ module GHC.Cmm.CLabel ( mkDirty_MUT_VAR_Label, mkMUT_VAR_CLEAN_infoLabel, mkNonmovingWriteBarrierEnabledLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, @@ -641,7 +642,7 @@ mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable -- Constructing Cmm Labels mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, - mkUpdInfoLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel, mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel, mkMAP_DIRTY_infoLabel, @@ -655,6 +656,7 @@ mkDirty_MUT_VAR_Label, mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData +mkOrigThunkInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_orig_thunk_info_frame") CmmInfo mkUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_upd_frame") CmmInfo mkBHUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_bh_upd_frame" ) CmmInfo mkIndStaticInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_IND_STATIC") CmmInfo ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -754,12 +754,31 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - let + let push_orig_thunk_info = True hdr = fixedHdrSize profile - frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + orig_info_frame_sz + | push_orig_thunk_info + = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + | otherwise = 0 + frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + frame2 = frame1 + orig_info_frame_sz -- - emitUpdateFrame (CmmStackSlot Old frame) lbl updatee - withUpdFrameOff frame body + emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee + when push_orig_thunk_info $ emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee + withUpdFrameOff frame2 body + +emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () +emitOrigThunkInfoFrame frame updatee = do + profile <- getProfile + cfg <- getStgToCmmConfig + let platform = profilePlatform profile + hdr = fixedHdrSize profile + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_orig_info (profileConstants profile) + align_check = stgToCmmAlignCheck cfg + info_ptr = cmmLoadBWord platform (closureInfoPtr platform align_check updatee) + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) info_ptr + initUpdFrameProf frame emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do ===================================== rts/StgMiscClosures.cmm ===================================== @@ -45,6 +45,16 @@ import CLOSURE stg_ret_t_info; import CLOSURE stg_ret_v_info; #endif +INFO_TABLE_RET (stg_orig_thunk_info_frame, RET_SMALL, + W_ info_ptr, + W_ thunk_info_ptr) + /* no args => explicit stack */ +{ + unwind Sp = W_[Sp + WDS(2)]; + Sp_adj(2); + jump %ENTRY_CODE(Sp(0)) [*]; // NB. all registers live! +} + /* ---------------------------------------------------------------------------- Stack underflow ------------------------------------------------------------------------- */ ===================================== rts/include/rts/storage/Closures.h ===================================== @@ -261,6 +261,13 @@ typedef struct _StgUpdateFrame { StgClosure *updatee; } StgUpdateFrame; +// Thunk update frame +// +// Closure types: RET_SMALL +typedef struct _StgOrigThunkInfoFrame { + StgHeader header; + StgInfoTable *info_ptr; +} StgOrigThunkInfoFrame; // Closure types: RET_SMALL typedef struct { ===================================== utils/deriveConstants/Main.hs ===================================== @@ -438,6 +438,7 @@ wanteds os = concat ,structField Both "StgEntCounter" "entry_count" ,closureSize Both "StgUpdateFrame" + ,closureSize Both "StgOrigThunkInfoFrame" ,closureSize C "StgCatchFrame" ,closureSize C "StgStopFrame" ,closureSize C "StgDeadThreadFrame" @@ -480,6 +481,7 @@ wanteds os = concat ,structSize C "StgTSOProfInfo" ,closureField Both "StgUpdateFrame" "updatee" + ,closureField Both "StgOrigThunkInfoFrame" "orig_info" ,closureField C "StgCatchFrame" "handler" ,closureField C "StgCatchFrame" "exceptions_blocked" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11da4583383c2365c680313eaf055095e188a379 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11da4583383c2365c680313eaf055095e188a379 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:33:14 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Apr 2023 12:33:14 -0400 Subject: [Git][ghc/ghc][master] Allow generation of TTH syntax with TH Message-ID: <6436dd4aa035a_10a80d60e4ec01493aa@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 17 changed files: - compiler/GHC/ThToHs.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/th/TH_typed1.hs - + testsuite/tests/th/TH_typed1.stdout - + testsuite/tests/th/TH_typed2.hs - + testsuite/tests/th/TH_typed2.stdout - + testsuite/tests/th/TH_typed3.hs - + testsuite/tests/th/TH_typed3.stderr - + testsuite/tests/th/TH_typed4.hs - + testsuite/tests/th/TH_typed4.stderr - + testsuite/tests/th/TH_typed5.hs - + testsuite/tests/th/TH_typed5.stdout - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1157,6 +1157,10 @@ cvtl e = wrapLA (cvt e) (L noSrcSpanA (DotFieldOcc noAnn (L noSrcSpanA (FieldLabelString (fsLit f))))) } cvt (ProjectionE xs) = return $ HsProjection noAnn $ fmap (L noSrcSpanA . DotFieldOcc noAnn . L noSrcSpanA . FieldLabelString . fsLit) xs + cvt (TypedSpliceE e) = do { e' <- parenthesizeHsExpr appPrec <$> cvtl e + ; return $ HsTypedSplice (noAnn, noAnn) e' } + cvt (TypedBracketE e) = do { e' <- cvtl e + ; return $ HsTypedBracket noAnn e' } {- | #16895 Ensure an infix expression's operator is a variable/constructor. Consider this example: ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -44,7 +44,7 @@ module Language.Haskell.TH.Lib ( appE, appTypeE, uInfixE, parensE, infixE, infixApp, sectionL, sectionR, lamE, lam1E, lamCaseE, lamCasesE, tupE, unboxedTupE, unboxedSumE, condE, multiIfE, letE, caseE, appsE, listE, sigE, recConE, recUpdE, stringE, - fieldExp, getFieldE, projectionE, + fieldExp, getFieldE, projectionE, typedSpliceE, typedBracketE, -- **** Ranges fromE, fromThenE, fromToE, fromThenToE, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -380,6 +380,12 @@ getFieldE e f = do projectionE :: Quote m => NonEmpty String -> m Exp projectionE xs = pure (ProjectionE xs) +typedSpliceE :: Quote m => m Exp -> m Exp +typedSpliceE = fmap TypedSpliceE + +typedBracketE :: Quote m => m Exp -> m Exp +typedBracketE = fmap TypedBracketE + -- ** 'arithSeqE' Shortcuts fromE :: Quote m => m Exp -> m Exp fromE x = do { a <- x; pure (ArithSeqE (FromR a)) } ===================================== libraries/template-haskell/Language/Haskell/TH/Ppr.hs ===================================== @@ -232,6 +232,8 @@ pprExp _ (LabelE s) = text "#" <> text s pprExp _ (ImplicitParamVarE n) = text ('?' : n) pprExp _ (GetFieldE e f) = pprExp appPrec e <> text ('.': f) pprExp _ (ProjectionE xs) = parens $ hcat $ map ((char '.'<>) . text) $ toList xs +pprExp _ (TypedBracketE e) = text "[||" <> ppr e <> text "||]" +pprExp _ (TypedSpliceE e) = text "$$" <> pprExp appPrec e pprFields :: [(Name,Exp)] -> Doc pprFields = sep . punctuate comma . map (\(s,e) -> pprName' Applied s <+> equals <+> ppr e) ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -2385,6 +2385,8 @@ data Exp | ImplicitParamVarE String -- ^ @{ ?x }@ ( Implicit parameter ) | GetFieldE Exp String -- ^ @{ exp.field }@ ( Overloaded Record Dot ) | ProjectionE (NonEmpty String) -- ^ @(.x)@ or @(.x.y)@ (Record projections) + | TypedBracketE Exp -- ^ @[|| e ||]@ + | TypedSpliceE Exp -- ^ @$$e@ deriving( Show, Eq, Ord, Data, Generic ) type FieldExp = (Name,Exp) ===================================== libraries/template-haskell/changelog.md ===================================== @@ -8,6 +8,10 @@ This change enables TemplateHaskell support for `DuplicateRecordFields`. + * Add support for generating typed splices and brackets in untyped Template Haskell + Introduces `typedSpliceE :: Quote m => m Exp -> m Exp` and + `typedBracketE :: Quote m => m Exp -> m Exp` + ## 2.20.0.0 * The `Ppr.pprInfixT` function has gained a `Precedence` argument. ===================================== testsuite/tests/th/TH_typed1.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $$( $(typedBracketE [| 'x' |]) ) ===================================== testsuite/tests/th/TH_typed1.stdout ===================================== @@ -0,0 +1 @@ +'x' ===================================== testsuite/tests/th/TH_typed2.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $( typedSpliceE $ typedBracketE [| 'y' |] ) ===================================== testsuite/tests/th/TH_typed2.stdout ===================================== @@ -0,0 +1 @@ +'y' ===================================== testsuite/tests/th/TH_typed3.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +-- test parenthesis around splice +main = do + print $( typedSpliceE $ typedBracketE [| 'z' |] ) + print $( typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |]) ) ===================================== testsuite/tests/th/TH_typed3.stderr ===================================== @@ -0,0 +1,9 @@ +TH_typed3.hs:9:12-53: Splicing expression + typedSpliceE $ typedBracketE [| 'z' |] ======> $$[|| 'z' ||] +TH_typed3.hs:10:12-69: Splicing expression + typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |]) + ======> + $$(id [|| 'z' ||]) +TH_typed3.hs:9:12-53: Splicing expression [|| 'z' ||] ======> 'z' +TH_typed3.hs:10:12-69: Splicing expression + id [|| 'z' ||] ======> 'z' ===================================== testsuite/tests/th/TH_typed4.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH + +main = print $$( $$(unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: Code Q (Code Q Char)) ) ===================================== testsuite/tests/th/TH_typed4.stderr ===================================== @@ -0,0 +1,10 @@ +TH_typed4.hs:7:20-96: Splicing expression + unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: + Code Q (Code Q Char) + ======> + [|| 'a' ||] +TH_typed4.hs:7:16-98: Splicing expression + $$(unsafeCodeCoerce $ typedBracketE $ litE $ charL 'a' :: + Code Q (Code Q Char)) + ======> + 'a' ===================================== testsuite/tests/th/TH_typed5.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TemplateHaskell #-} + +module Main where + +import Language.Haskell.TH +import Language.Haskell.TH.Ppr + +main = do + putStrLn =<< fmap pprint (typedSpliceE $ typedBracketE [| 'z' |]) + putStrLn =<< fmap pprint (typedSpliceE $ appE [| id |] (typedBracketE [| 'z' |])) ===================================== testsuite/tests/th/TH_typed5.stdout ===================================== @@ -0,0 +1,2 @@ +$$[||'z'||] +$$(GHC.Base.id [||'z'||]) ===================================== testsuite/tests/th/all.T ===================================== @@ -559,3 +559,8 @@ test('T22819', normal, compile, ['-v0']) test('TH_fun_par', normal, compile, ['']) test('T23036', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T23203', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed1', normal, compile_and_run, ['']) +test('TH_typed2', normal, compile_and_run, ['']) +test('TH_typed3', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed4', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('TH_typed5', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebd8918b7c50ae51921664e24fac0de4376ffcf9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebd8918b7c50ae51921664e24fac0de4376ffcf9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:33:48 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 12 Apr 2023 12:33:48 -0400 Subject: [Git][ghc/ghc][master] Add regression test for #23229 Message-ID: <6436dd6ccfab6_10a80d60e4ec01527e0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 3 changed files: - + testsuite/tests/ghci/should_run/T23229.hs - + testsuite/tests/ghci/should_run/T23229.script - testsuite/tests/ghci/should_run/all.T Changes: ===================================== testsuite/tests/ghci/should_run/T23229.hs ===================================== @@ -0,0 +1 @@ +instance Num Bool ===================================== testsuite/tests/ghci/should_run/T23229.script ===================================== @@ -0,0 +1 @@ +:l T23229 ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -88,3 +88,4 @@ test('UnliftedDataType2', just_ghci, compile_and_run, ['']) test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) +test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/690d0225d297a8c5c423ec4e63ee709df9d96d47 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/690d0225d297a8c5c423ec4e63ee709df9d96d47 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:53:21 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 12:53:21 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6436e20154afd_10a80d6c20de8153177@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 06e4459e by Rodrigo Mesquita at 2023-04-12T17:53:08+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types + , hasNoNonZeroWidthArgs con + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `idFunRepArity id > 0` (which will be 'True' of the wrapper and 'False' +of the worker) and only then for `isDataConId_maybe && hasNoNonZeroWidthArgs` +(which is true of both). This makes the order of the guards in `mkLFImported` +crucial to the correctness! + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -161,7 +161,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06e4459ef49cc84da93ddd8bfde4f39b8db675ed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06e4459ef49cc84da93ddd8bfde4f39b8db675ed You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 16:54:18 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 12:54:18 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6436e23a5b7f4_10a80d6c21a181536ac@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 7f362914 by Rodrigo Mesquita at 2023-04-12T17:54:06+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types + , hasNoNonZeroWidthArgs con + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `idFunRepArity id > 0` (which will be 'True' of the wrapper and 'False' +of the worker) and only then for `isDataConId_maybe && hasNoNonZeroWidthArgs` +(which is true of both). This makes the order of the guards in `mkLFImported` +crucial to the correctness! + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f362914b95558aedd3108fd147183d438b8ae61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f362914b95558aedd3108fd147183d438b8ae61 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 17:04:01 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 13:04:01 -0400 Subject: [Git][ghc/ghc][wip/T23146] 2 commits: codeGen: Give proper LFInfo to datacon wrappers Message-ID: <6436e4812b66b_10a80d6f96dec1591ce@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 0459f242 by Ben Gamari at 2023-04-12T15:42:59+01:00 codeGen: Give proper LFInfo to datacon wrappers As noted in `Note [Conveying CAF-info and LFInfo between modules]`, when importing a binding from another module we must ensure that it gets the appropriate `LambdaFormInfo` if it is in WHNF to ensure that references to it are tagged correctly. However, the implementation responsible for doing this, `GHC.StgToCmm.Closure.mkLFImported`, only dealt with datacon workers and not wrappers. This lead to the crash of this program in #23146: module B where type NP :: [UnliftedType] -> UnliftedType data NP xs where UNil :: NP '[] module A where import B fieldsSam :: NP xs -> NP xs -> Bool fieldsSam UNil UNil = True x = fieldsSam UNil UNil Due to its GADT nature, `UNil` produces a trivial wrapper $WUNil :: NP '[] $WUNil = UNil @'[] @~(<co:1>) which is referenced in the RHS of `A.x`. Due to the above-mentioned bug in `mkLFImported`, the references to `$WUNil` passed to `fieldsSam` were not tagged. This is problematic as `fieldsSam` expected its arguments to be tagged as they are unlifted. The fix is straightforward: extend the logic in `mkLFImported` to cover (nullary) datacon wrappers as well as workers. This is safe because we know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). Thanks to @MangoIV for the great ticket and @alt-romes for his minimization and help debugging. Fixes #23146. - - - - - 7f362914 by Rodrigo Mesquita at 2023-04-12T17:54:06+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,21 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | Just con <- isDataConId_maybe id + , hasNoNonZeroWidthArgs con + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `idFunRepArity id > 0` (which will be 'True' of the wrapper and 'False' +of the worker) and only then for `isDataConId_maybe && hasNoNonZeroWidthArgs` +(which is true of both). This makes the order of the guards in `mkLFImported` +crucial to the correctness! + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -70,6 +70,51 @@ moving parts are: * We don't absolutely guarantee to serialise the CgInfo: we won't if you have -fomit-interface-pragmas or -fno-code; and we won't read it in if you have -fignore-interface-pragmas. (We could revisit this decision.) + +Note [Imported nullary datacon wrappers must have correct LFInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As described in `Note [Conveying CAF-info and LFInfo between modules]`, +imported nullary datacons must have their LambdaFormInfo set to reflect the +fact that they are evaluated . This is necessary are otherwise references +to them may be passed untagged to code that expects tagged references. + +What may be less obvious is that this must be done for not only datacon +workers but also *wrappers*. The reason is found in this program +from #23146: + + module B where + + type NP :: [UnliftedType] -> UnliftedType + data NP xs where + UNil :: NP '[] + + + module A where + import B + + fieldsSam :: NP xs -> NP xs -> Bool + fieldsSam UNil UNil = True + + x = fieldsSam UNil UNil + +Due to its GADT nature, `B.UNil` produces a trivial wrapper + + $WUNil :: NP '[] + $WUNil = UNil @'[] @~() + +which is referenced in the RHS of `A.x`. If we fail to give `$WUNil` the +correct `LFCon 0` `LambdaFormInfo` then we will end up passing an untagged +pointer to `fieldsSam`. This is problematic as `fieldsSam` may take advantage +of the unlifted nature of its arguments by omitting handling of the zero +tag when scrutinising them. + +The fix is straightforward: extend the logic in `mkLFImported` to cover +(nullary) datacon wrappers as well as workers. This is safe because we +know that the wrapper of a nullary datacon will be in WHNF, even if it +includes equalities evidence (since such equalities are not runtime +relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -118,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c2a8ae062abc6a5bb66b8b23881a0a10b568813...7f362914b95558aedd3108fd147183d438b8ae61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c2a8ae062abc6a5bb66b8b23881a0a10b568813...7f362914b95558aedd3108fd147183d438b8ae61 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 17:39:47 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 13:39:47 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6436ece347e57_10a80d7abddb0171962@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: ecf2e152 by Rodrigo Mesquita at 2023-04-12T18:39:23+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 13 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types + , hasNoNonZeroWidthArgs con + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `idFunRepArity id > 0` (which will be 'True' of the wrapper and 'False' +of the worker) and only then for `isDataConId_maybe && hasNoNonZeroWidthArgs` +(which is true of both). This makes the order of the guards in `mkLFImported` +crucial to the correctness! + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf2e1524fbf7c3b3b03ef45ed5d0fa52433e5af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf2e1524fbf7c3b3b03ef45ed5d0fa52433e5af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 17:40:10 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 12 Apr 2023 13:40:10 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6436ecfabf343_10a80d7aeb134172140@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: ecf2e152 by Rodrigo Mesquita at 2023-04-12T18:39:23+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary (no non-zero-width arguments) datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. First, we fix the nullary datacon predicate to one which considers constructors with no non-zero-width arguments to be nullary, unlike `isNullaryRepDataCon` which doesn't consider constructors with just zero-width to be nullary (since it is a predicate over the Core data con representation arity, for which zero-width arguments are relevant) Secondly, we failed to account for data con wrappers that received real arguments but whose worker received non-zero-width arguments. An example of such a data type was pointed out by @clyring: data T a where TCon :: {-# UNPACK #-} !(a :~: True) -> T a In this case, we were incorrectly tagging the TCon wrapper with `LFCon`, which is incorrect since it takes a lifted argument. The solution is simple: change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor with a nullary worker. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 13 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted! (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,79 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types + , hasNoNonZeroWidthArgs con + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below -> LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with a `RepArity > 0` are `LFReEntrant` and pointers to them are tagged +with the corresponding arity + +(2) Nullary data constructors should be given `LFCon`, since they are indeed +fully saturated data constructor applications; pointers to them should be +tagged with the constructor index. + +However, we must be very careful about what we consider to be nullary data +constructors. In particular, nullary data con *wrappers* must also be given +`LFCon` (see #23231 and #23146). That is: + - Data con *workers* with no non-zero-width arguments have LFCon + - Data con *wrappers* with no non-zero-width arguments also have LFCon + +(Note that before the patch to those issues we would already consider these +nullary wrappers to have `LFCon` lambda form info; but failed to re-construct +that information in `mkLFImported`) + +Finally, we must consider the case of a data constructor whose worker has no +non-zero-width arity whereas the wrapper has an argument. For example, + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + +`TCon` will have a wrapper with a lifted equality argument, which is +non-zero-width, while the worker will have an unlifted equality argument, which +is zero-width. + +We can (trivially) handle this situation in `mkLFImported` by *first* checking +whether `idFunRepArity id > 0` (which will be 'True' of the wrapper and 'False' +of the worker) and only then for `isDataConId_maybe && hasNoNonZeroWidthArgs` +(which is true of both). This makes the order of the guards in `mkLFImported` +crucial to the correctness! + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf2e1524fbf7c3b3b03ef45ed5d0fa52433e5af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecf2e1524fbf7c3b3b03ef45ed5d0fa52433e5af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 18:15:28 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 14:15:28 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] compiler: Record original thunk info tables on stack Message-ID: <6436f540a902f_10a80d878112817476@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: e6d15bb9 by Ben Gamari at 2023-04-12T14:15:21-04:00 compiler: Record original thunk info tables on stack - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Config.hs - rts/StgMiscClosures.cmm - rts/include/rts/storage/Closures.h - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -53,6 +53,7 @@ module GHC.Cmm.CLabel ( mkDirty_MUT_VAR_Label, mkMUT_VAR_CLEAN_infoLabel, mkNonmovingWriteBarrierEnabledLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, @@ -641,7 +642,7 @@ mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable -- Constructing Cmm Labels mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, - mkUpdInfoLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel, mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel, mkMAP_DIRTY_infoLabel, @@ -655,6 +656,7 @@ mkDirty_MUT_VAR_Label, mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData +mkOrigThunkInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_orig_thunk_info_frame") CmmInfo mkUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_upd_frame") CmmInfo mkBHUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_bh_upd_frame" ) CmmInfo mkIndStaticInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_IND_STATIC") CmmInfo ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -37,6 +37,7 @@ initStgToCmmConfig dflags mod = StgToCmmConfig , stgToCmmFastPAPCalls = gopt Opt_FastPAPCalls dflags , stgToCmmSCCProfiling = sccProfilingEnabled dflags , stgToCmmEagerBlackHole = gopt Opt_EagerBlackHoling dflags + , stgToCmmOrigThunkInfo = gopt Opt_OrigThunkInfo dflags , stgToCmmInfoTableMap = gopt Opt_InfoTableMap dflags , stgToCmmOmitYields = gopt Opt_OmitYields dflags , stgToCmmOmitIfPragmas = gopt Opt_OmitInterfacePragmas dflags ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -328,6 +328,7 @@ data GeneralFlag | Opt_IgnoreHpcChanges | Opt_ExcessPrecision | Opt_EagerBlackHoling + | Opt_OrigThunkInfo | Opt_NoHsMain | Opt_SplitSections | Opt_StgStats ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3468,6 +3468,7 @@ fFlagsDeps = [ flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, + flagSpec "orig-thunk-info" Opt_OrigThunkInfo, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, flagSpec "enable-th-splice-warnings" Opt_EnableThSpliceWarnings, ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -754,12 +754,31 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - let + cfg <- getStgToCmmConfig + let push_orig_thunk_info = stgToCmmOrigThunkInfo cfg hdr = fixedHdrSize profile - frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + orig_info_frame_sz + | push_orig_thunk_info + = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + | otherwise = 0 + frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + frame2 = frame1 + orig_info_frame_sz -- - emitUpdateFrame (CmmStackSlot Old frame) lbl updatee - withUpdFrameOff frame body + emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee + when push_orig_thunk_info $ emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee + withUpdFrameOff frame2 body + +emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () +emitOrigThunkInfoFrame frame updatee = do + profile <- getProfile + cfg <- getStgToCmmConfig + let platform = profilePlatform profile + hdr = fixedHdrSize profile + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) + align_check = stgToCmmAlignCheck cfg + info_ptr = cmmLoadBWord platform (closureInfoPtr platform align_check updatee) + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) info_ptr emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -49,6 +49,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmFastPAPCalls :: !Bool -- ^ , stgToCmmSCCProfiling :: !Bool -- ^ Check if cost-centre profiling is enabled , stgToCmmEagerBlackHole :: !Bool -- ^ + , stgToCmmOrigThunkInfo :: !Bool -- ^ Push @stg_orig_thunk_info@ frames during thunk update. , stgToCmmInfoTableMap :: !Bool -- ^ true means generate C Stub for IPE map, See note [Mapping -- Info Tables to Source Positions] , stgToCmmOmitYields :: !Bool -- ^ true means omit heap checks when no allocation is performed ===================================== rts/StgMiscClosures.cmm ===================================== @@ -45,6 +45,16 @@ import CLOSURE stg_ret_t_info; import CLOSURE stg_ret_v_info; #endif +INFO_TABLE_RET (stg_orig_thunk_info_frame, RET_SMALL, + W_ info_ptr, + W_ thunk_info_ptr) + /* no args => explicit stack */ +{ + unwind Sp = W_[Sp + WDS(2)]; + Sp_adj(2); + jump %ENTRY_CODE(Sp(0)) [*]; // NB. all registers live! +} + /* ---------------------------------------------------------------------------- Stack underflow ------------------------------------------------------------------------- */ ===================================== rts/include/rts/storage/Closures.h ===================================== @@ -261,6 +261,13 @@ typedef struct _StgUpdateFrame { StgClosure *updatee; } StgUpdateFrame; +// Thunk update frame +// +// Closure types: RET_SMALL +typedef struct _StgOrigThunkInfoFrame { + StgHeader header; + StgInfoTable *info_ptr; +} StgOrigThunkInfoFrame; // Closure types: RET_SMALL typedef struct { ===================================== utils/deriveConstants/Main.hs ===================================== @@ -438,6 +438,7 @@ wanteds os = concat ,structField Both "StgEntCounter" "entry_count" ,closureSize Both "StgUpdateFrame" + ,closureSize Both "StgOrigThunkInfoFrame" ,closureSize C "StgCatchFrame" ,closureSize C "StgStopFrame" ,closureSize C "StgDeadThreadFrame" @@ -480,6 +481,7 @@ wanteds os = concat ,structSize C "StgTSOProfInfo" ,closureField Both "StgUpdateFrame" "updatee" + ,closureField Both "StgOrigThunkInfoFrame" "info_ptr" ,closureField C "StgCatchFrame" "handler" ,closureField C "StgCatchFrame" "exceptions_blocked" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6d15bb92d0147aaff3fd0684c321f63a86a56b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6d15bb92d0147aaff3fd0684c321f63a86a56b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 18:19:19 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 14:19:19 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] compiler: Record original thunk info tables on stack Message-ID: <6436f627a43e0_10a80d8818d4817525a@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: 6c8f35aa by Ben Gamari at 2023-04-12T14:19:12-04:00 compiler: Record original thunk info tables on stack - - - - - 9 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Config.hs - rts/StgMiscClosures.cmm - rts/include/rts/storage/Closures.h - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -53,6 +53,7 @@ module GHC.Cmm.CLabel ( mkDirty_MUT_VAR_Label, mkMUT_VAR_CLEAN_infoLabel, mkNonmovingWriteBarrierEnabledLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, @@ -641,7 +642,7 @@ mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable -- Constructing Cmm Labels mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, - mkUpdInfoLabel, + mkOrigThunkInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel, mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel, mkMAP_DIRTY_infoLabel, @@ -655,6 +656,7 @@ mkDirty_MUT_VAR_Label, mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData +mkOrigThunkInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_orig_thunk_info_frame") CmmInfo mkUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_upd_frame") CmmInfo mkBHUpdInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_bh_upd_frame" ) CmmInfo mkIndStaticInfoLabel = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_IND_STATIC") CmmInfo ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -37,6 +37,7 @@ initStgToCmmConfig dflags mod = StgToCmmConfig , stgToCmmFastPAPCalls = gopt Opt_FastPAPCalls dflags , stgToCmmSCCProfiling = sccProfilingEnabled dflags , stgToCmmEagerBlackHole = gopt Opt_EagerBlackHoling dflags + , stgToCmmOrigThunkInfo = gopt Opt_OrigThunkInfo dflags , stgToCmmInfoTableMap = gopt Opt_InfoTableMap dflags , stgToCmmOmitYields = gopt Opt_OmitYields dflags , stgToCmmOmitIfPragmas = gopt Opt_OmitInterfacePragmas dflags ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -328,6 +328,7 @@ data GeneralFlag | Opt_IgnoreHpcChanges | Opt_ExcessPrecision | Opt_EagerBlackHoling + | Opt_OrigThunkInfo | Opt_NoHsMain | Opt_SplitSections | Opt_StgStats ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3468,6 +3468,7 @@ fFlagsDeps = [ flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, + flagSpec "orig-thunk-info" Opt_OrigThunkInfo, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, flagSpec "enable-th-splice-warnings" Opt_EnableThSpliceWarnings, ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -754,12 +754,32 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - let + cfg <- getStgToCmmConfig + let push_orig_thunk_info = stgToCmmOrigThunkInfo cfg hdr = fixedHdrSize profile - frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + orig_info_frame_sz + | push_orig_thunk_info + = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + | otherwise = 0 + frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) + frame2 = frame1 + orig_info_frame_sz -- - emitUpdateFrame (CmmStackSlot Old frame) lbl updatee - withUpdFrameOff frame body + emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee + when push_orig_thunk_info $ + emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee + withUpdFrameOff frame2 body + +emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () +emitOrigThunkInfoFrame frame updatee = do + profile <- getProfile + cfg <- getStgToCmmConfig + let platform = profilePlatform profile + hdr = fixedHdrSize profile + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) + align_check = stgToCmmAlignCheck cfg + info_ptr = closureInfoPtr platform align_check updatee + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) info_ptr emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -49,6 +49,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmFastPAPCalls :: !Bool -- ^ , stgToCmmSCCProfiling :: !Bool -- ^ Check if cost-centre profiling is enabled , stgToCmmEagerBlackHole :: !Bool -- ^ + , stgToCmmOrigThunkInfo :: !Bool -- ^ Push @stg_orig_thunk_info@ frames during thunk update. , stgToCmmInfoTableMap :: !Bool -- ^ true means generate C Stub for IPE map, See note [Mapping -- Info Tables to Source Positions] , stgToCmmOmitYields :: !Bool -- ^ true means omit heap checks when no allocation is performed ===================================== rts/StgMiscClosures.cmm ===================================== @@ -45,6 +45,16 @@ import CLOSURE stg_ret_t_info; import CLOSURE stg_ret_v_info; #endif +INFO_TABLE_RET (stg_orig_thunk_info_frame, RET_SMALL, + W_ info_ptr, + W_ thunk_info_ptr) + /* no args => explicit stack */ +{ + unwind Sp = W_[Sp + WDS(2)]; + Sp_adj(2); + jump %ENTRY_CODE(Sp(0)) [*]; // NB. all registers live! +} + /* ---------------------------------------------------------------------------- Stack underflow ------------------------------------------------------------------------- */ ===================================== rts/include/rts/storage/Closures.h ===================================== @@ -261,6 +261,13 @@ typedef struct _StgUpdateFrame { StgClosure *updatee; } StgUpdateFrame; +// Thunk update frame +// +// Closure types: RET_SMALL +typedef struct _StgOrigThunkInfoFrame { + StgHeader header; + StgInfoTable *info_ptr; +} StgOrigThunkInfoFrame; // Closure types: RET_SMALL typedef struct { ===================================== utils/deriveConstants/Main.hs ===================================== @@ -438,6 +438,7 @@ wanteds os = concat ,structField Both "StgEntCounter" "entry_count" ,closureSize Both "StgUpdateFrame" + ,closureSize Both "StgOrigThunkInfoFrame" ,closureSize C "StgCatchFrame" ,closureSize C "StgStopFrame" ,closureSize C "StgDeadThreadFrame" @@ -480,6 +481,7 @@ wanteds os = concat ,structSize C "StgTSOProfInfo" ,closureField Both "StgUpdateFrame" "updatee" + ,closureField Both "StgOrigThunkInfoFrame" "info_ptr" ,closureField C "StgCatchFrame" "handler" ,closureField C "StgCatchFrame" "exceptions_blocked" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c8f35aaa574343ca26cece51b87e7754d9ef90e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c8f35aaa574343ca26cece51b87e7754d9ef90e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 19:31:45 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 15:31:45 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] Refactor Message-ID: <6437072173f7d_10a80d99e73d017692d@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: 99e13be3 by Ben Gamari at 2023-04-12T15:30:39-04:00 Refactor - - - - - 1 changed file: - compiler/GHC/StgToCmm/Bind.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -730,7 +730,8 @@ setupUpdate closure_info node body lbl | bh = mkBHUpdInfoLabel | otherwise = mkUpdInfoLabel - pushUpdateFrame lbl (CmmReg (CmmLocal node)) body + pushOrigThunkInfoFrame closure_info + $ pushUpdateFrame lbl (CmmReg (CmmLocal node)) body | otherwise -- A static closure = do { tickyUpdateBhCaf closure_info @@ -738,7 +739,8 @@ setupUpdate closure_info node body ; if closureUpdReqd closure_info then do -- Blackhole the (updatable) CAF: { upd_closure <- link_caf node - ; pushUpdateFrame mkBHUpdInfoLabel upd_closure body } + ; pushOrigThunkInfoFrame closure_info + $ pushUpdateFrame mkBHUpdInfoLabel upd_closure body } else do {tickyUpdateFrameOmitted; body} } @@ -754,32 +756,11 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - cfg <- getStgToCmmConfig - let push_orig_thunk_info = stgToCmmOrigThunkInfo cfg - hdr = fixedHdrSize profile - orig_info_frame_sz - | push_orig_thunk_info - = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) - | otherwise = 0 - frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) - frame2 = frame1 + orig_info_frame_sz + let hdr = fixedHdrSize profile + frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) -- - emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee - when push_orig_thunk_info $ - emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee - withUpdFrameOff frame2 body - -emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () -emitOrigThunkInfoFrame frame updatee = do - profile <- getProfile - cfg <- getStgToCmmConfig - let platform = profilePlatform profile - hdr = fixedHdrSize profile - off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) - align_check = stgToCmmAlignCheck cfg - info_ptr = closureInfoPtr platform align_check updatee - emitStore frame (mkLblExpr mkOrigThunkInfoLabel) - emitStore (cmmOffset platform frame off_orig_info) info_ptr + emitUpdateFrame (CmmStackSlot Old frame) lbl updatee + withUpdFrameOff frame body emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do @@ -793,6 +774,34 @@ emitUpdateFrame frame lbl updatee = do emitStore (cmmOffset platform frame off_updatee) updatee initUpdFrameProf frame +----------------------------------------------------------------------------- +-- Original thunk info table frames +-- +-- Support for -forig-thunk-info + +pushOrigThunkInfoFrame :: ClosureInfo -> FCode () -> FCode () +pushOrigThunkInfoFrame closure_info body = do + cfg <- getStgToCmmConfig + if stgToCmmOrigThunkInfo cfg + then do_it + else body + where + orig_itbl = mkLblExpr (closureInfoLabel closure_info) + do_it = do + updfr <- getUpdFrameOff + profile <- getProfile + let platform = profilePlatform profile + hdr = fixedHdrSize profile + orig_info_frame_sz = + hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) + frame_off = updfr + orig_info_frame_sz + frame = CmmStackSlot Old frame_off + -- + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) orig_itbl + withUpdFrameOff frame_off body + ----------------------------------------------------------------------------- -- Entering a CAF -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99e13be360064f6c7ade9465e430d704ff91a2f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99e13be360064f6c7ade9465e430d704ff91a2f7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 12 19:55:10 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 12 Apr 2023 15:55:10 -0400 Subject: [Git][ghc/ghc][wip/orig-thunk-info] Refactor Message-ID: <64370c9e9f27a_10a80da184c50179486@gitlab.mail> Ben Gamari pushed to branch wip/orig-thunk-info at Glasgow Haskell Compiler / GHC Commits: fd91d387 by Ben Gamari at 2023-04-12T15:54:30-04:00 Refactor - - - - - 2 changed files: - compiler/GHC/StgToCmm/Bind.hs - docs/users_guide/debugging.rst Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -730,7 +730,8 @@ setupUpdate closure_info node body lbl | bh = mkBHUpdInfoLabel | otherwise = mkUpdInfoLabel - pushUpdateFrame lbl (CmmReg (CmmLocal node)) body + pushOrigThunkInfoFrame closure_info + $ pushUpdateFrame lbl (CmmReg (CmmLocal node)) body | otherwise -- A static closure = do { tickyUpdateBhCaf closure_info @@ -738,7 +739,8 @@ setupUpdate closure_info node body ; if closureUpdReqd closure_info then do -- Blackhole the (updatable) CAF: { upd_closure <- link_caf node - ; pushUpdateFrame mkBHUpdInfoLabel upd_closure body } + ; pushOrigThunkInfoFrame closure_info + $ pushUpdateFrame mkBHUpdInfoLabel upd_closure body } else do {tickyUpdateFrameOmitted; body} } @@ -754,32 +756,11 @@ pushUpdateFrame lbl updatee body = do updfr <- getUpdFrameOff profile <- getProfile - cfg <- getStgToCmmConfig - let push_orig_thunk_info = stgToCmmOrigThunkInfo cfg - hdr = fixedHdrSize profile - orig_info_frame_sz - | push_orig_thunk_info - = hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) - | otherwise = 0 - frame1 = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) - frame2 = frame1 + orig_info_frame_sz + let hdr = fixedHdrSize profile + frame = updfr + hdr + pc_SIZEOF_StgUpdateFrame_NoHdr (profileConstants profile) -- - emitUpdateFrame (CmmStackSlot Old frame1) lbl updatee - when push_orig_thunk_info $ - emitOrigThunkInfoFrame (CmmStackSlot Old frame2) updatee - withUpdFrameOff frame2 body - -emitOrigThunkInfoFrame :: CmmExpr -> CmmExpr -> FCode () -emitOrigThunkInfoFrame frame updatee = do - profile <- getProfile - cfg <- getStgToCmmConfig - let platform = profilePlatform profile - hdr = fixedHdrSize profile - off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) - align_check = stgToCmmAlignCheck cfg - info_ptr = closureInfoPtr platform align_check updatee - emitStore frame (mkLblExpr mkOrigThunkInfoLabel) - emitStore (cmmOffset platform frame off_orig_info) info_ptr + emitUpdateFrame (CmmStackSlot Old frame) lbl updatee + withUpdFrameOff frame body emitUpdateFrame :: CmmExpr -> CLabel -> CmmExpr -> FCode () emitUpdateFrame frame lbl updatee = do @@ -793,6 +774,34 @@ emitUpdateFrame frame lbl updatee = do emitStore (cmmOffset platform frame off_updatee) updatee initUpdFrameProf frame +----------------------------------------------------------------------------- +-- Original thunk info table frames +-- +-- Support for -forig-thunk-info + +pushOrigThunkInfoFrame :: ClosureInfo -> FCode () -> FCode () +pushOrigThunkInfoFrame closure_info body = do + cfg <- getStgToCmmConfig + if stgToCmmOrigThunkInfo cfg + then do_it + else body + where + orig_itbl = mkLblExpr (closureInfoLabel closure_info) + do_it = do + updfr <- getUpdFrameOff + profile <- getProfile + let platform = profilePlatform profile + hdr = fixedHdrSize profile + orig_info_frame_sz = + hdr + pc_SIZEOF_StgOrigThunkInfoFrame_NoHdr (profileConstants profile) + off_orig_info = hdr + pc_OFFSET_StgOrigThunkInfoFrame_info_ptr (profileConstants profile) + frame_off = updfr + orig_info_frame_sz + frame = CmmStackSlot Old frame_off + -- + emitStore frame (mkLblExpr mkOrigThunkInfoLabel) + emitStore (cmmOffset platform frame off_orig_info) orig_itbl + withUpdFrameOff frame_off body + ----------------------------------------------------------------------------- -- Entering a CAF -- ===================================== docs/users_guide/debugging.rst ===================================== @@ -1072,6 +1072,17 @@ Checking for consistency cases. This is helpful when debugging demand analysis or type checker bugs which can sometimes manifest as segmentation faults. +.. ghc-flag:: -forig-thunk-info + :shortdesc: Generate ``stg_orig_thunk_info`` stack frames on thunk entry + :type: dynamic + + When debugging cyclic thunks it can be helpful to know the original + info table of a thunk being evaluated. This flag enables code generation logic + to facilitate this, producing a ``stg_orig_thunk_info`` stack frame alongside + the usual update frame; such ``orig_thunk`` frames have no operational + effect but capture the original info table of the updated thunk for inspection + by debugging tools. + .. ghc-flag:: -fcheck-prim-bounds :shortdesc: Instrument array primops with bounds checks. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd91d3872914e8a813b08032ec4241114b0b0f35 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd91d3872914e8a813b08032ec4241114b0b0f35 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 07:09:52 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 13 Apr 2023 03:09:52 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 60 commits: rts: Always use atomics for context_switch and interrupt Message-ID: <6437aac044946_10a80d14cd3160212233@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 3c585040 by Ben Gamari at 2023-04-13T12:34:07+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - 83ba82ce by Ben Gamari at 2023-04-13T12:34:07+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 1fefb322 by Ben Gamari at 2023-04-13T12:34:07+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - 32357ebb by Ben Gamari at 2023-04-13T12:35:16+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - bf59ca9f by Ben Gamari at 2023-04-13T12:35:18+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - c4f67bde by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - abfe5e22 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - b8d6ccc2 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - f03fd079 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - 877aa0bf by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - 7496ff86 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 03937e30 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - f817fd36 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - 9072bf90 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - b63b3a80 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - 128e4bd2 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - 774b6472 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - 94a87700 by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - 9a50b1be by Ben Gamari at 2023-04-13T12:35:18+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - 4d28971b by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - b51cbef0 by Ben Gamari at 2023-04-13T12:35:19+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - e1a5e690 by Ben Gamari at 2023-04-13T12:35:19+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - 785c5928 by Ben Gamari at 2023-04-13T12:35:19+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - 7bf28b6c by Ben Gamari at 2023-04-13T12:35:19+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - f06e08f1 by Ben Gamari at 2023-04-13T12:35:19+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - a91dc7b3 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - 9b2d0a55 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - c1c6e7a5 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - dcb9dd8b by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - dfb96963 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - 81dd7d49 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - c82643be by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - 7a7cd477 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 6482ddc2 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - 574b6fd5 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - d3272cdc by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - cbd65cc0 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - 9fe65a39 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - a748828b by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - e44dbf89 by Ben Gamari at 2023-04-13T12:35:19+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - 1e7cfe63 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - 6dfa78dc by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - c5d911a8 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - d85b997c by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - ec81ad6b by Ben Gamari at 2023-04-13T12:35:20+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - ad56c311 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - 67588823 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - f4625c54 by Ben Gamari at 2023-04-13T12:35:20+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - fcc5f898 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - f3b6428d by Ben Gamari at 2023-04-13T12:35:20+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - 94c9b996 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - bc844d8f by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - cbd351bd by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - 38d611b6 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - ee372fda by Ben Gamari at 2023-04-13T12:35:20+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - fe7f662d by Ben Gamari at 2023-04-13T12:35:20+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - 69cbc948 by Ben Gamari at 2023-04-13T12:35:20+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - becec9fc by Ben Gamari at 2023-04-13T12:35:20+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 7782684e by Ben Gamari at 2023-04-13T12:35:42+05:30 contextswitch - - - - - 291bcf5a by Ben Gamari at 2023-04-13T12:38:53+05:30 rts: Fix incorrect format specifier warnings - - - - - 30 changed files: - hadrian/src/Flavour.hs - rts/Capability.c - rts/Capability.h - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/PrimOps.cmm - rts/Printer.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Sparks.h - rts/Stats.c - rts/Threads.c - rts/Timer.c - rts/TraverseHeap.c - rts/eventlog/EventLog.c - rts/include/rts/storage/ClosureMacros.h - rts/include/rts/storage/GC.h - rts/include/rts/storage/MBlock.h - rts/include/stg/SMP.h - rts/posix/Select.c - rts/posix/Signals.c - rts/rts.cabal.in - rts/sm/BlockAlloc.c - rts/sm/Compact.c - rts/sm/Evac.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc4e2482ca3e32308cbe5beb43c898a5bbe5e540...291bcf5a4c36a396aa842594eb789806f9b80ea5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc4e2482ca3e32308cbe5beb43c898a5bbe5e540...291bcf5a4c36a396aa842594eb789806f9b80ea5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 07:24:39 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 13 Apr 2023 03:24:39 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 62 commits: Prepare release 9.4.5 Message-ID: <6437ae37908fa_10a80d14fa0dd4219992@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: ca73c603 by Zubin Duggal at 2023-04-13T12:54:05+05:30 Prepare release 9.4.5 - - - - - 5bab6e61 by Zubin Duggal at 2023-04-13T12:54:05+05:30 Allow LLVM 14 - - - - - d7cc0048 by Ben Gamari at 2023-04-13T12:54:05+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - 00b419c1 by Ben Gamari at 2023-04-13T12:54:05+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 0ca09b07 by Ben Gamari at 2023-04-13T12:54:05+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - 0c2c2153 by Ben Gamari at 2023-04-13T12:54:05+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - d3d0cbaa by Ben Gamari at 2023-04-13T12:54:05+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - e7eb4969 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - b4b55d27 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - 97236661 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - 9d524993 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - e972135c by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - ade2da91 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 3c14809d by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - 6b3a0af4 by Ben Gamari at 2023-04-13T12:54:05+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - 4c415247 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - b12359cb by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - 6b3a9b39 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - 74de4064 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - 3cea0960 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - a0a87237 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - 3eb7c91e by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - 71d5b385 by Ben Gamari at 2023-04-13T12:54:06+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - 50367561 by Ben Gamari at 2023-04-13T12:54:06+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - a9d50d88 by Ben Gamari at 2023-04-13T12:54:06+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - 7bf42d4d by Ben Gamari at 2023-04-13T12:54:06+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - f9f9cb9f by Ben Gamari at 2023-04-13T12:54:06+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - 09dc5b04 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - ac2a7a06 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - c8488f84 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - 65992bca by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - bcce9d3a by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - cd456aa2 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - 071efba6 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - 8ef31cbe by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 718211d4 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - 071e8ca7 by Ben Gamari at 2023-04-13T12:54:06+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - 63e90592 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - 311e7182 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - 0ea1d584 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - 3955c9aa by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - 2f8fb5ac by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - 50722ad8 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - 28369e28 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - 23b4d530 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - 9ca58075 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - ff1519fe by Ben Gamari at 2023-04-13T12:54:07+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - 264d0d3c by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - 0ebf01ee by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - f2dee092 by Ben Gamari at 2023-04-13T12:54:07+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - 382cb783 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - 5c21bd88 by Ben Gamari at 2023-04-13T12:54:07+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - d120a411 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - 6fd35acd by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - 04920b38 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - 6167f215 by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - a204fc36 by Ben Gamari at 2023-04-13T12:54:07+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - 786585e1 by Ben Gamari at 2023-04-13T12:54:07+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - 4be3e19b by Ben Gamari at 2023-04-13T12:54:07+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - 1424da19 by Ben Gamari at 2023-04-13T12:54:08+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 25d31b6a by Ben Gamari at 2023-04-13T12:54:08+05:30 contextswitch - - - - - f37378b3 by Ben Gamari at 2023-04-13T12:54:08+05:30 rts: Fix incorrect format specifier warnings - - - - - 30 changed files: - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - hadrian/src/Flavour.hs - libraries/base/changelog.md - rts/Capability.c - rts/Capability.h - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/PrimOps.cmm - rts/Printer.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Sparks.h - rts/Stats.c - rts/Threads.c - rts/Timer.c - rts/TraverseHeap.c - rts/eventlog/EventLog.c - rts/include/rts/storage/ClosureMacros.h - rts/include/rts/storage/GC.h - rts/include/rts/storage/MBlock.h - rts/include/stg/SMP.h - rts/posix/Select.c - rts/posix/Signals.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/291bcf5a4c36a396aa842594eb789806f9b80ea5...f37378b34c34c193912760ef413ac72eb3457f2d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/291bcf5a4c36a396aa842594eb789806f9b80ea5...f37378b34c34c193912760ef413ac72eb3457f2d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 07:40:28 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Apr 2023 03:40:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Allow generation of TTH syntax with TH Message-ID: <6437b1ec32512_10a80d154ab3d822206e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 8c6d6f62 by Sylvain Henry at 2023-04-13T03:40:23-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - bad1b375 by Sylvain Henry at 2023-04-13T03:40:23-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 33e17249 by Sylvain Henry at 2023-04-13T03:40:23-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 6b302610 by Sylvain Henry at 2023-04-13T03:40:23-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - f435268d by Josh Meredith at 2023-04-13T03:40:24-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Literal.hs - docs/users_guide/index.rst - + docs/users_guide/javascript.rst - + libraries/base/GHC/JS/Foreign/Callback.hs - libraries/base/GHC/JS/Prim.hs - libraries/base/base.cabal - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/ghci/should_run/T23229.hs - + testsuite/tests/ghci/should_run/T23229.script - testsuite/tests/ghci/should_run/all.T - testsuite/tests/javascript/all.T - + testsuite/tests/javascript/js-callback01.hs - + testsuite/tests/javascript/js-callback01.stdout - + testsuite/tests/javascript/js-callback02.hs - + testsuite/tests/javascript/js-callback02.stdout - + testsuite/tests/javascript/js-callback03.hs - + testsuite/tests/javascript/js-callback03.stdout - + testsuite/tests/javascript/js-callback04.hs - + testsuite/tests/javascript/js-callback04.stdout - + testsuite/tests/javascript/js-callback05.hs - + testsuite/tests/javascript/js-callback05.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/006cd8bd7d0f37f8eb281d52e41f21ea7c678502...f435268da08a9f6f4c0ec7581755ff48f9044327 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/006cd8bd7d0f37f8eb281d52e41f21ea7c678502...f435268da08a9f6f4c0ec7581755ff48f9044327 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 09:12:57 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 13 Apr 2023 05:12:57 -0400 Subject: [Git][ghc/ghc][wip/T23083] 5 commits: exprIsTrivial: Factor out shared implementation Message-ID: <6437c799b7528_10a80d16d223442529dd@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: c8000b90 by Sebastian Graf at 2023-04-13T10:09:31+02:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - 58ca811d by Sebastian Graf at 2023-04-13T11:12:49+02:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - eed7c4d1 by Sebastian Graf at 2023-04-13T11:12:49+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - 27f108ac by Sebastian Graf at 2023-04-13T11:12:49+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 62f77bf1 by Sebastian Graf at 2023-04-13T11:12:49+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - docs/users_guide/using-optimisation.rst - testsuite/tests/corelint/T21115b.stderr - testsuite/tests/deSugar/should_compile/T2431.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f0eb801500744770cc6bfef401229113c28a8c4...62f77bf143492f6d983b9533978c21ef920278bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f0eb801500744770cc6bfef401229113c28a8c4...62f77bf143492f6d983b9533978c21ef920278bd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 09:27:26 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 13 Apr 2023 05:27:26 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 18 commits: Add release note for GHC.Unicode refactor in base-4.18. Message-ID: <6437cafeed19c_10a80d17349b2826413@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 5c16501f by Simon Peyton Jones at 2023-04-13T10:29:12+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - b431140c by Simon Peyton Jones at 2023-04-13T10:29:12+01:00 Add some documentation about redundant constraints - - - - - 9fcad479 by Simon Peyton Jones at 2023-04-13T10:29:12+01:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - e7ea954b by Simon Peyton Jones at 2023-04-13T10:29:12+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 23 changed files: - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7d6284dacc3bf215bfe55006e830583b0d163074...e7ea954b8ad6beac0c6f3eb350f0b576d42b3e68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7d6284dacc3bf215bfe55006e830583b0d163074...e7ea954b8ad6beac0c6f3eb350f0b576d42b3e68 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 09:53:41 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 13 Apr 2023 05:53:41 -0400 Subject: [Git][ghc/ghc][wip/js-th] 121 commits: Fix BCO creation setting caps when -j > -N Message-ID: <6437d125939e1_10a80d17bde39c27611d@gitlab.mail> Sylvain Henry pushed to branch wip/js-th at Glasgow Haskell Compiler / GHC Commits: c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 90479b27 by Sylvain Henry at 2023-04-13T11:29:21+02:00 JS: implement TH support - Add ghc-interp.js bootstrap script for the JS interpreter - Interactively link and execute iserv code from the ghci package - Incrementally load and run JS code for splices into the running iserv Co-authored-by: Luite Stegeman <stegeman at gmail.com> - - - - - c37f48c5 by Sylvain Henry at 2023-04-13T11:29:24+02:00 Fix comment - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8141271d68e9befbb3952930cf2cc4ee5cd48ac4...c37f48c594a8924af508f35af249eac914e203fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8141271d68e9befbb3952930cf2cc4ee5cd48ac4...c37f48c594a8924af508f35af249eac914e203fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 11:09:29 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 13 Apr 2023 07:09:29 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23252 Message-ID: <6437e2e96f2ef_10a80d18ed42f83127c4@gitlab.mail> Simon Peyton Jones pushed new branch wip/T23252 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23252 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 12:50:53 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Apr 2023 08:50:53 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Add quotRem rules (#22152) Message-ID: <6437faad98cdb_10a80d1a94f74032543a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 10 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Types/Literal.hs - + testsuite/tests/primops/should_compile/T22152.hs - + testsuite/tests/primops/should_compile/T22152.stderr - + testsuite/tests/primops/should_compile/T22152b.hs - + testsuite/tests/primops/should_compile/T22152b.stderr - testsuite/tests/primops/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -551,36 +551,43 @@ primOpIsCheap op = primOpOkForSpeculation op primOpIsDiv :: PrimOp -> Bool primOpIsDiv op = case op of - -- TODO: quotRemWord2, Int64, Word64 IntQuotOp -> True Int8QuotOp -> True Int16QuotOp -> True Int32QuotOp -> True + Int64QuotOp -> True IntRemOp -> True Int8RemOp -> True Int16RemOp -> True Int32RemOp -> True + Int64RemOp -> True IntQuotRemOp -> True Int8QuotRemOp -> True Int16QuotRemOp -> True Int32QuotRemOp -> True + -- Int64QuotRemOp doesn't exist (yet) WordQuotOp -> True Word8QuotOp -> True Word16QuotOp -> True Word32QuotOp -> True + Word64QuotOp -> True WordRemOp -> True Word8RemOp -> True Word16RemOp -> True Word32RemOp -> True + Word64RemOp -> True WordQuotRemOp -> True Word8QuotRemOp -> True Word16QuotRemOp -> True Word32QuotRemOp -> True + -- Word64QuotRemOp doesn't exist (yet) + + WordQuotRem2Op -> True FloatDivOp -> True DoubleDivOp -> True ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -27,6 +27,7 @@ module GHC.Core.Opt.ConstantFold ( primOpRules , builtinRules , caseRules + , caseRules2 ) where @@ -120,7 +121,9 @@ primOpRules nm = \case Int8QuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int8Op2 quot) , leftZero , rightIdentity oneI8 - , equalArgs $> Lit oneI8 ] + , equalArgs $> Lit oneI8 + , quotFoldingRules int8Ops + ] Int8RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int8Op2 rem) , leftZero , oneLit 1 $> Lit zeroI8 @@ -149,7 +152,9 @@ primOpRules nm = \case , mulFoldingRules Word8MulOp word8Ops ] Word8QuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word8Op2 quot) - , rightIdentity oneW8 ] + , rightIdentity oneW8 + , quotFoldingRules word8Ops + ] Word8RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word8Op2 rem) , leftZero , oneLit 1 $> Lit zeroW8 @@ -194,7 +199,9 @@ primOpRules nm = \case Int16QuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int16Op2 quot) , leftZero , rightIdentity oneI16 - , equalArgs $> Lit oneI16 ] + , equalArgs $> Lit oneI16 + , quotFoldingRules int16Ops + ] Int16RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int16Op2 rem) , leftZero , oneLit 1 $> Lit zeroI16 @@ -223,7 +230,9 @@ primOpRules nm = \case , mulFoldingRules Word16MulOp word16Ops ] Word16QuotOp-> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word16Op2 quot) - , rightIdentity oneW16 ] + , rightIdentity oneW16 + , quotFoldingRules word16Ops + ] Word16RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word16Op2 rem) , leftZero , oneLit 1 $> Lit zeroW16 @@ -268,7 +277,9 @@ primOpRules nm = \case Int32QuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int32Op2 quot) , leftZero , rightIdentity oneI32 - , equalArgs $> Lit oneI32 ] + , equalArgs $> Lit oneI32 + , quotFoldingRules int32Ops + ] Int32RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int32Op2 rem) , leftZero , oneLit 1 $> Lit zeroI32 @@ -297,7 +308,9 @@ primOpRules nm = \case , mulFoldingRules Word32MulOp word32Ops ] Word32QuotOp-> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word32Op2 quot) - , rightIdentity oneW32 ] + , rightIdentity oneW32 + , quotFoldingRules word32Ops + ] Word32RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word32Op2 rem) , leftZero , oneLit 1 $> Lit zeroW32 @@ -341,7 +354,9 @@ primOpRules nm = \case Int64QuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int64Op2 quot) , leftZero , rightIdentity oneI64 - , equalArgs $> Lit oneI64 ] + , equalArgs $> Lit oneI64 + , quotFoldingRules int64Ops + ] Int64RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (int64Op2 rem) , leftZero , oneLit 1 $> Lit zeroI64 @@ -370,7 +385,9 @@ primOpRules nm = \case , mulFoldingRules Word64MulOp word64Ops ] Word64QuotOp-> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word64Op2 quot) - , rightIdentity oneW64 ] + , rightIdentity oneW64 + , quotFoldingRules word64Ops + ] Word64RemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (word64Op2 rem) , leftZero , oneLit 1 $> Lit zeroW64 @@ -451,7 +468,9 @@ primOpRules nm = \case IntQuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (intOp2 quot) , leftZero , rightIdentityPlatform onei - , equalArgs >> retLit onei ] + , equalArgs >> retLit onei + , quotFoldingRules intOps + ] IntRemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (intOp2 rem) , leftZero , oneLit 1 >> retLit zeroi @@ -503,7 +522,9 @@ primOpRules nm = \case , mulFoldingRules WordMulOp wordOps ] WordQuotOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (wordOp2 quot) - , rightIdentityPlatform onew ] + , rightIdentityPlatform onew + , quotFoldingRules wordOps + ] WordRemOp -> mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (wordOp2 rem) , leftZero , oneLit 1 >> retLit zerow @@ -2652,6 +2673,14 @@ orFoldingRules num_ops = do (orFoldingRules' platform arg1 arg2 num_ops <|> orFoldingRules' platform arg2 arg1 num_ops) +quotFoldingRules :: NumOps -> RuleM CoreExpr +quotFoldingRules num_ops = do + env <- getRuleOpts + guard (roNumConstantFolding env) + [arg1,arg2] <- getArgs + platform <- getPlatform + liftMaybe (quotFoldingRules' platform arg1 arg2 num_ops) + addFoldingRules' :: Platform -> CoreExpr -> CoreExpr -> NumOps -> Maybe CoreExpr addFoldingRules' platform arg1 arg2 num_ops = case (arg1, arg2) of @@ -2942,6 +2971,29 @@ orFoldingRules' platform arg1 arg2 num_ops = case (arg1, arg2) of mkL = Lit . mkNumLiteral platform num_ops or x y = BinOpApp x (fromJust (numOr num_ops)) y +quotFoldingRules' :: Platform -> CoreExpr -> CoreExpr -> NumOps -> Maybe CoreExpr +quotFoldingRules' platform arg1 arg2 num_ops = case (arg1, arg2) of + + -- (x / l1) / l2 + -- l1 and l2 /= 0 + -- l1*l2 doesn't overflow + -- ==> x / (l1 * l2) + (is_div num_ops -> Just (x, L l1), L l2) + | l1 /= 0 + , l2 /= 0 + -- check that the result of the multiplication is in range + , Just l <- mkNumLiteralMaybe platform num_ops (l1 * l2) + -> Just (div x (Lit l)) + -- NB: we could directly return 0 or (-1) in case of overflow, + -- but we would need to know + -- (1) if we're dealing with a quot or a div operation + -- (2) if it's an underflow or an overflow. + -- Left as future work for now. + + _ -> Nothing + where + div x y = BinOpApp x (fromJust (numDiv num_ops)) y + is_binop :: PrimOp -> CoreExpr -> Maybe (Arg CoreBndr, Arg CoreBndr) is_binop op e = case e of BinOpApp x op' y | op == op' -> Just (x,y) @@ -2952,12 +3004,13 @@ is_op op e = case e of App (OpVal op') x | op == op' -> Just x _ -> Nothing -is_add, is_sub, is_mul, is_and, is_or :: NumOps -> CoreExpr -> Maybe (Arg CoreBndr, Arg CoreBndr) +is_add, is_sub, is_mul, is_and, is_or, is_div :: NumOps -> CoreExpr -> Maybe (Arg CoreBndr, Arg CoreBndr) is_add num_ops e = is_binop (numAdd num_ops) e is_sub num_ops e = is_binop (numSub num_ops) e is_mul num_ops e = is_binop (numMul num_ops) e is_and num_ops e = numAnd num_ops >>= \op -> is_binop op e is_or num_ops e = numOr num_ops >>= \op -> is_binop op e +is_div num_ops e = numDiv num_ops >>= \op -> is_binop op e is_neg :: NumOps -> CoreExpr -> Maybe (Arg CoreBndr) is_neg num_ops e = numNeg num_ops >>= \op -> is_op op e @@ -3006,6 +3059,7 @@ data NumOps = NumOps { numAdd :: !PrimOp -- ^ Add two numbers , numSub :: !PrimOp -- ^ Sub two numbers , numMul :: !PrimOp -- ^ Multiply two numbers + , numDiv :: !(Maybe PrimOp) -- ^ Divide two numbers , numAnd :: !(Maybe PrimOp) -- ^ And two numbers , numOr :: !(Maybe PrimOp) -- ^ Or two numbers , numNeg :: !(Maybe PrimOp) -- ^ Negate a number @@ -3016,15 +3070,20 @@ data NumOps = NumOps mkNumLiteral :: Platform -> NumOps -> Integer -> Literal mkNumLiteral platform ops i = mkLitNumberWrap platform (numLitType ops) i +-- | Create a numeric literal if it is in range +mkNumLiteralMaybe :: Platform -> NumOps -> Integer -> Maybe Literal +mkNumLiteralMaybe platform ops i = mkLitNumberMaybe platform (numLitType ops) i + int8Ops :: NumOps int8Ops = NumOps { numAdd = Int8AddOp , numSub = Int8SubOp , numMul = Int8MulOp - , numLitType = LitNumInt8 + , numDiv = Just Int8QuotOp , numAnd = Nothing , numOr = Nothing , numNeg = Just Int8NegOp + , numLitType = LitNumInt8 } word8Ops :: NumOps @@ -3032,6 +3091,7 @@ word8Ops = NumOps { numAdd = Word8AddOp , numSub = Word8SubOp , numMul = Word8MulOp + , numDiv = Just Word8QuotOp , numAnd = Just Word8AndOp , numOr = Just Word8OrOp , numNeg = Nothing @@ -3043,10 +3103,11 @@ int16Ops = NumOps { numAdd = Int16AddOp , numSub = Int16SubOp , numMul = Int16MulOp - , numLitType = LitNumInt16 + , numDiv = Just Int16QuotOp , numAnd = Nothing , numOr = Nothing , numNeg = Just Int16NegOp + , numLitType = LitNumInt16 } word16Ops :: NumOps @@ -3054,6 +3115,7 @@ word16Ops = NumOps { numAdd = Word16AddOp , numSub = Word16SubOp , numMul = Word16MulOp + , numDiv = Just Word16QuotOp , numAnd = Just Word16AndOp , numOr = Just Word16OrOp , numNeg = Nothing @@ -3065,10 +3127,11 @@ int32Ops = NumOps { numAdd = Int32AddOp , numSub = Int32SubOp , numMul = Int32MulOp - , numLitType = LitNumInt32 + , numDiv = Just Int32QuotOp , numAnd = Nothing , numOr = Nothing , numNeg = Just Int32NegOp + , numLitType = LitNumInt32 } word32Ops :: NumOps @@ -3076,6 +3139,7 @@ word32Ops = NumOps { numAdd = Word32AddOp , numSub = Word32SubOp , numMul = Word32MulOp + , numDiv = Just Word32QuotOp , numAnd = Just Word32AndOp , numOr = Just Word32OrOp , numNeg = Nothing @@ -3087,10 +3151,11 @@ int64Ops = NumOps { numAdd = Int64AddOp , numSub = Int64SubOp , numMul = Int64MulOp - , numLitType = LitNumInt64 + , numDiv = Just Int64QuotOp , numAnd = Nothing , numOr = Nothing , numNeg = Just Int64NegOp + , numLitType = LitNumInt64 } word64Ops :: NumOps @@ -3098,6 +3163,7 @@ word64Ops = NumOps { numAdd = Word64AddOp , numSub = Word64SubOp , numMul = Word64MulOp + , numDiv = Just Word64QuotOp , numAnd = Just Word64AndOp , numOr = Just Word64OrOp , numNeg = Nothing @@ -3109,6 +3175,7 @@ intOps = NumOps { numAdd = IntAddOp , numSub = IntSubOp , numMul = IntMulOp + , numDiv = Just IntQuotOp , numAnd = Just IntAndOp , numOr = Just IntOrOp , numNeg = Just IntNegOp @@ -3120,6 +3187,7 @@ wordOps = NumOps { numAdd = WordAddOp , numSub = WordSubOp , numMul = WordMulOp + , numDiv = Just WordQuotOp , numAnd = Just WordAndOp , numOr = Just WordOrOp , numNeg = Nothing @@ -3192,6 +3260,61 @@ caseRules _ (App (App (Var f) (Type ty)) v) -- dataToTag x caseRules _ _ = Nothing +-- | Case rules +-- +-- It's important that occurence info are present, hence the use of In* types. +caseRules2 + :: InExpr -- ^ Scutinee + -> InId -- ^ Case-binder + -> [InAlt] -- ^ Alternatives in standard (increasing) order + -> Maybe (InExpr, InId, [InAlt]) +caseRules2 scrut bndr alts + + -- case quotRem# x y of + -- (# q, _ #) -> body + -- ====> + -- case quot# x y of + -- q -> body + -- + -- case quotRem# x y of + -- (# _, r #) -> body + -- ====> + -- case rem# x y of + -- r -> body + | BinOpApp x op y <- scrut + , Just (quot,rem) <- is_any_quot_rem op + , [Alt (DataAlt _) [q,r] body] <- alts + , isDeadBinder bndr + , dead_q <- isDeadBinder q + , dead_r <- isDeadBinder r + , dead_q || dead_r + = if + | dead_q -> Just $ (BinOpApp x rem y, r, [Alt DEFAULT [] body]) + | dead_r -> Just $ (BinOpApp x quot y, q, [Alt DEFAULT [] body]) + | otherwise -> Nothing + + | otherwise + = Nothing + + +-- | If the given primop is a quotRem, return the corresponding (quot,rem). +is_any_quot_rem :: PrimOp -> Maybe (PrimOp, PrimOp) +is_any_quot_rem = \case + IntQuotRemOp -> Just (IntQuotOp , IntRemOp) + Int8QuotRemOp -> Just (Int8QuotOp, Int8RemOp) + Int16QuotRemOp -> Just (Int16QuotOp, Int16RemOp) + Int32QuotRemOp -> Just (Int32QuotOp, Int32RemOp) + -- Int64QuotRemOp doesn't exist (yet) + + WordQuotRemOp -> Just (WordQuotOp, WordRemOp) + Word8QuotRemOp -> Just (Word8QuotOp, Word8RemOp) + Word16QuotRemOp -> Just (Word16QuotOp, Word16RemOp) + Word32QuotRemOp -> Just (Word32QuotOp, Word32RemOp) + -- Word64QuotRemOp doesn't exist (yet) + + _ -> Nothing + + tx_lit_con :: Platform -> (Integer -> Integer) -> AltCon -> Maybe AltCon tx_lit_con _ _ DEFAULT = Just DEFAULT tx_lit_con platform adjust (LitAlt l) = Just $ LitAlt (mapLitValue platform adjust l) ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -19,6 +19,7 @@ import GHC.Driver.Flags import GHC.Core import GHC.Core.Opt.Simplify.Monad +import GHC.Core.Opt.ConstantFold import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst ) import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Opt.Simplify.Env @@ -3039,6 +3040,14 @@ rebuildCase env scrut case_bndr alts@[Alt _ bndrs rhs] cont ; case mb_rule of Just (env', rule_rhs, cont') -> simplExprF env' rule_rhs cont' Nothing -> reallyRebuildCase env scrut case_bndr alts cont } + +-------------------------------------------------- +-- 3. Primop-related case-rules +-------------------------------------------------- + + |Just (scrut', case_bndr', alts') <- caseRules2 scrut case_bndr alts + = reallyRebuildCase env scrut' case_bndr' alts' cont + where all_dead_bndrs = all isDeadBinder bndrs -- bndrs are [InId] is_plain_seq = all_dead_bndrs && isDeadBinder case_bndr -- Evaluation *only* for effect ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1615,8 +1615,10 @@ app_ok fun_ok primop_ok fun args PrimOpId op _ | primOpIsDiv op - , [arg1, Lit lit] <- args - -> not (isZeroLit lit) && expr_ok fun_ok primop_ok arg1 + , Lit divisor <- last args + -- there can be 2 args (most div primops) or 3 args + -- (WordQuotRem2Op), hence the use of last/init + -> not (isZeroLit divisor) && all (expr_ok fun_ok primop_ok) (init args) -- Special case for dividing operations that fail -- In general they are NOT ok-for-speculation -- (which primop_ok will catch), but they ARE OK ===================================== compiler/GHC/Types/Literal.hs ===================================== @@ -32,7 +32,7 @@ module GHC.Types.Literal , mkLitFloat, mkLitDouble , mkLitChar, mkLitString , mkLitBigNat - , mkLitNumber, mkLitNumberWrap + , mkLitNumber, mkLitNumberWrap, mkLitNumberMaybe -- ** Operations on Literals , literalType @@ -411,6 +411,12 @@ mkLitNumber platform nt i = assertPpr (litNumCheckRange platform nt i) (integer i) (LitNumber nt i) +-- | Create a numeric 'Literal' of the given type if it is in range +mkLitNumberMaybe :: Platform -> LitNumType -> Integer -> Maybe Literal +mkLitNumberMaybe platform nt i + | litNumCheckRange platform nt i = Just (LitNumber nt i) + | otherwise = Nothing + -- | Creates a 'Literal' of type @Int#@ mkLitInt :: Platform -> Integer -> Literal mkLitInt platform x = assertPpr (platformInIntRange platform x) (integer x) ===================================== testsuite/tests/primops/should_compile/T22152.hs ===================================== @@ -0,0 +1,16 @@ +{-# OPTIONS_GHC -O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques #-} +module T22152 (toHours) where + +{-# INLINE toHoursMinutesSeconds #-} +toHoursMinutesSeconds :: Int -> (Int, Int, Int) +toHoursMinutesSeconds t = (h, m', s) + where + (h, m') = m `quotRem` 60 + (m, s) = toMinutesSeconds t + +toMinutesSeconds :: Int -> (Int, Int) +toMinutesSeconds t = t `quotRem` 60 + +toHours t = h + where + (h, _, _) = toHoursMinutesSeconds t ===================================== testsuite/tests/primops/should_compile/T22152.stderr ===================================== @@ -0,0 +1,9 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 9, types: 5, coercions: 0, joins: 0/0} + +toHours = \ t -> case t of { I# x -> I# (quotInt# x 3600#) } + + + ===================================== testsuite/tests/primops/should_compile/T22152b.hs ===================================== @@ -0,0 +1,38 @@ +{-# OPTIONS_GHC -O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques #-} +module T22152b where + +import Data.Int +import Data.Word + +a :: Int32 -> Int32 +a x = (x `quot` maxBound) `quot` maxBound -- overflow, mustn't trigger the rewrite rule + +b :: Int -> Int +b x = (x `quot` 10) `quot` 20 + +c :: Word -> Word +c x = (x `quot` 10) `quot` 20 + +d :: Word8 -> Word8 +d x = (x `quot` 10) `quot` 20 + +e :: Word16 -> Word16 +e x = (x `quot` 10) `quot` 20 + +f :: Word32 -> Word32 +f x = (x `quot` 10) `quot` 20 + +g :: Word64 -> Word64 +g x = (x `quot` 10) `quot` 20 + +h :: Int8 -> Int8 +h x = (x `quot` 10) `quot` 20 + +i :: Int16 -> Int16 +i x = (x `quot` 10) `quot` 20 + +j :: Int32 -> Int32 +j x = (x `quot` 10) `quot` 20 + +k :: Int64 -> Int64 +k x = (x `quot` 10) `quot` 20 ===================================== testsuite/tests/primops/should_compile/T22152b.stderr ===================================== @@ -0,0 +1,38 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 103, types: 55, coercions: 0, joins: 0/0} + +b = \ x -> case x of { I# x1 -> I# (quotInt# x1 200#) } + +c = \ x -> case x of { W# x# -> W# (quotWord# x# 200##) } + +d = \ x -> case x of { W8# x# -> W8# (quotWord8# x# 200#Word8) } + +e = \ x -> + case x of { W16# x# -> W16# (quotWord16# x# 200#Word16) } + +f = \ x -> + case x of { W32# x# -> W32# (quotWord32# x# 200#Word32) } + +g = \ x -> + case x of { W64# x# -> W64# (quotWord64# x# 200#Word64) } + +h = \ x -> + case x of { I8# x# -> + I8# (quotInt8# (quotInt8# x# 10#Int8) 20#Int8) + } + +i = \ x -> case x of { I16# x# -> I16# (quotInt16# x# 200#Int16) } + +j = \ x -> case x of { I32# x# -> I32# (quotInt32# x# 200#Int32) } + +a = \ x -> + case x of { I32# x# -> + I32# (quotInt32# (quotInt32# x# 2147483647#Int32) 2147483647#Int32) + } + +k = \ x -> case x of { I64# x# -> I64# (quotInt64# x# 200#Int64) } + + + ===================================== testsuite/tests/primops/should_compile/all.T ===================================== @@ -6,3 +6,5 @@ test('LevAddrToAny', normal, compile, ['']) test('UnliftedMutVar_Comp', normal, compile, ['']) test('UnliftedStableName', normal, compile, ['']) test('KeepAliveWrapper', normal, compile, ['-O']) +test('T22152', normal, compile, ['']) +test('T22152b', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/690d0225d297a8c5c423ec4e63ee709df9d96d47...8af401ccfbe28d7bbfc493c0097834e9c66a36b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/690d0225d297a8c5c423ec4e63ee709df9d96d47...8af401ccfbe28d7bbfc493c0097834e9c66a36b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 12:51:30 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Apr 2023 08:51:30 -0400 Subject: [Git][ghc/ghc][master] Base/JS: GHC.JS.Foreign.Callback module (issue 23126) Message-ID: <6437fad2824ad_10a80d1acc9e70329315@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - 28 changed files: - docs/users_guide/index.rst - + docs/users_guide/javascript.rst - + libraries/base/GHC/JS/Foreign/Callback.hs - libraries/base/GHC/JS/Prim.hs - libraries/base/base.cabal - testsuite/tests/javascript/all.T - + testsuite/tests/javascript/js-callback01.hs - + testsuite/tests/javascript/js-callback01.stdout - + testsuite/tests/javascript/js-callback02.hs - + testsuite/tests/javascript/js-callback02.stdout - + testsuite/tests/javascript/js-callback03.hs - + testsuite/tests/javascript/js-callback03.stdout - + testsuite/tests/javascript/js-callback04.hs - + testsuite/tests/javascript/js-callback04.stdout - + testsuite/tests/javascript/js-callback05.hs - + testsuite/tests/javascript/js-callback05.stdout - + testsuite/tests/javascript/js-ffi-array.hs - + testsuite/tests/javascript/js-ffi-array.stdout - + testsuite/tests/javascript/js-ffi-int.hs - + testsuite/tests/javascript/js-ffi-int.stdout - + testsuite/tests/javascript/js-ffi-isNull.hs - + testsuite/tests/javascript/js-ffi-isNull.stdout - + testsuite/tests/javascript/js-ffi-isUndefined.hs - + testsuite/tests/javascript/js-ffi-isUndefined.stdout - + testsuite/tests/javascript/js-ffi-null.hs - + testsuite/tests/javascript/js-ffi-null.stdout - + testsuite/tests/javascript/js-ffi-string.hs - + testsuite/tests/javascript/js-ffi-string.stdout Changes: ===================================== docs/users_guide/index.rst ===================================== @@ -23,6 +23,7 @@ Contents: hints utils win32-dlls + javascript wasm bugs eventlog-formats ===================================== docs/users_guide/javascript.rst ===================================== @@ -0,0 +1,175 @@ +.. _ffi-javascript + +FFI and the JavaScript Backend +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: FFI and the JavaScript Backend + +GHC's JavaScript backend supports its own calling convention for +JavaScript-specific foreign imports. Any unapplied function is +supported, including function names. Commonly, JavaScript foreign +imports are written as an unapplied JavaScript `arrow function +`_, +but ``function`` keyword anonymous functions are also supported. + +By treating an import string as an unapplied function, arbitrary +JavaScript can be included in an import, so a simple example might +look like: + +.. code-block:: haskell + + foreign import javascript "((x,y) => { return x + y; })" + js_add :: Int -> Int -> Int + +JSVal +^^^^^ + +The JavaScript backend has a concept of an untyped 'plain' JavaScript +value, under the guise of the type ``JSVal``. Values having this type +are mostly opaque to Haskell codes: you can think of `JSVal` as a data type whose +data constructors aren't exposed. Its main use case is to pass opaque +JavaScript values from one FFI call to another. + +Nevertheless the module ``GHC.JS.Prim`` from ``base`` contains functions for +working with foreign ``JSVal`` objects. Currently, it provides the following +conversions: + +* ``Int`` <-> ``JSVal`` (``toJSInt``, ``fromJSInt``) +* ``String`` <-> ``JSVal`` (``toJSString``, ``fromJSString``) +* ``[JSVal]`` <-> ``JSVal`` (``toJSArray``, ``fromJSArray``) + +It also contains functions for working with objects: + +* ``jsNull :: JSVal`` - the JavaScript ``null`` +* ``isNull :: JSVal -> Bool`` - test for the JavaScript ``null`` +* ``isUndefined :: JSVal -> Bool`` - test for the JavaScript ``undefined`` +* ``getProp :: JSVal -> String -> JSVal`` - object field access + +JavaScript FFI Types +^^^^^^^^^^^^^^^^^^^^ + +Some types are able to be used directly in the type signatures of foreign +exports, without conversion to a ``JSVal``. We saw in the first example +that ``Int`` is one of these. + +The supported types are those with primitive JavaScript representations +that match the Haskell type. This means types such as the Haskell ``String`` +type aren't supported directly, because they're lists - which don't have +a primitive JavaScript representation, and so are incompatible with each +other. + +The following types are supported in this way: + +* ``Int`` +* ``Bool`` +* ``Char`` + +As in the C FFI, types in the JavaScript FFI can't be type checked against the foreign code, so +the following example would compile successfully - despite `5` not being a valid JavaScript value +for the Haskell `Bool` type: + +.. code-block:: haskell + + foreign import javascript "((x) => { return 5; })" + type_error :: Bool -> Bool + +JavaScript Callbacks +^^^^^^^^^^^^^^^^^^^^ + +The JavaScript execution model is based around callback functions, and +GHC's JavaScript backend implements these as a type in order to support +useful browser programs, and programs interacting with JavaScript libraries. + +The module ``GHC.JS.Foreign.Callback`` in ``base`` defines the type ``Callback a``, +as well as several functions to construct callbacks from Haskell functions +of up to three ``JSVal`` arguments. Unlike a regular function, a ``Callback`` +function is passed in the FFI as a plain JavaScript function - enabling us to call +these functions from within JavaScript: + +.. code-block:: haskell + + foreign import javascript "((f) => { f('Example!'); })" + callback_example :: Callback (JSVal -> IO ()) -> IO () + + printJSValAsString :: JSVal -> IO () + printJSValAsString = putStrLn . fromJSString + + main :: IO () + main = do + printJS <- syncCallback1 ThrowWouldBlock printJSValAsString + callback_example printJS + releaseCallback printJS + +This example will call our ``printJSValAsString`` function, via JavaScript, +with the JavaScript string ``Example!`` as an argument. On the last line, +the callback memory is freed. Since there's no way for the Haskell JS runtime +to know if a function is still being referenced by JavaScript code, the memory +must be manually released when no longer needed. + +On the first line of ``main``, we see where the ``Callback`` is actually +created, by ``syncCallback1``. ``syncCallback`` has versions up to three, +including a zero-argument version with no suffix. To use callbacks with more +than three pieces of data, it's recommended to package data into JavaScript +objects or arrays as required. + +There are three categories of functions that create callbacks, with the +arity-1 type signatures shown here for demonstration: + +* ``syncCallback1 :: (JSVal -> IO ()) -> OnBlocked -> IO (Callback (JSVal -> IO ()))``: + Synchronous callbacks that don't return a value. These take an additional + ``data OnBlocked = ThrowWouldBlock | ContinueAsync`` argument for use in the + case that the thread becomes blocked on e.g. an ``MVar`` transaction. + +* ``syncCallback' :: (JSVal -> IO JSVal) -> IO (Callback (JSVal -> IO ()))``: + Synchronous callbacks that return a value. Because of the return value, there + is no possibility of continuing asynchronously, so no ``OnBlocked`` argument + is taken. + +* ``asyncCallback :: (JSVal -> IO ()) -> IO (Callback (JSVal -> IO ()))``: + Asynchronous callbacks that immediately start in a new thread. Cannot return a + value. + +There is no checking that the passed arguments match the callback, so the +following example compiles and correctly prints 10, despite the argument being +passed as an ``Int`` to a ``Callback`` that accepts a ``JSVal``: + +.. code-block:: haskell + + foreign import javascript "((f,x) => { return f(x); })" + apply_int :: Callback (JSVal -> IO JSVal) -> Int -> IO Int + + main :: IO () + main = do + add3 <- syncCallback1' (return . (+3)) + print =<< apply_int add3 7 + releaseCallback add3 + +Callbacks as Foreign Exports +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +JavaScript callbacks allow for a sort of FFI exports via FFI imports. To do +this, a global JavaScript variable is set, and that global variable can then +be called from use cases that access plain JavaScript functions - such as +interactive HTML elements. This would look like: + +.. code-block:: haskell + + foreign import javascript "((f) => { globalF = f })" + setF :: Callback (JSVal -> IO ()) -> IO () + + main :: IO () + main = do + log <- syncCallback1 ThrowWouldBlock (print . fromJSString) + setF log + -- don't releaseCallback log + + +.. code-block:: html + + + +We have to make sure not to use ``releaseCallback`` on any functions that +are to be available in HTML, because we want these functions to be in +memory indefinitely. + ===================================== libraries/base/GHC/JS/Foreign/Callback.hs ===================================== @@ -0,0 +1,149 @@ +module GHC.JS.Foreign.Callback + ( Callback + , OnBlocked(..) + , releaseCallback + -- * asynchronous callbacks + , asyncCallback + , asyncCallback1 + , asyncCallback2 + , asyncCallback3 + -- * synchronous callbacks + , syncCallback + , syncCallback1 + , syncCallback2 + , syncCallback3 + -- * synchronous callbacks that return a value + , syncCallback' + , syncCallback1' + , syncCallback2' + , syncCallback3' + ) where + +import GHC.JS.Prim + +import qualified GHC.Exts as Exts + +import Data.Typeable + +import Unsafe.Coerce + +data OnBlocked = ContinueAsync | ThrowWouldBlock deriving (Eq) + +newtype Callback a = Callback JSVal deriving Typeable + +{- | + When you create a callback, the Haskell runtime stores a reference to + the exported IO action or function. This means that all data referenced by the + exported value stays in memory, even if nothing outside the Haskell runtime + holds a reference to to callback. + Use 'releaseCallback' to free the reference. Subsequent calls from JavaScript + to the callback will result in an exception. + -} +releaseCallback :: Callback a -> IO () +releaseCallback x = js_release x + +{- | Make a callback (JavaScript function) that runs the supplied IO action in a synchronous + thread when called. + Call 'releaseCallback' when done with the callback, freeing memory referenced + by the IO action. + -} +syncCallback :: OnBlocked -- ^ what to do when the thread blocks + -> IO () -- ^ the Haskell action + -> IO (Callback (IO ())) -- ^ the callback +syncCallback onBlocked x = js_syncCallback (onBlocked == ContinueAsync) (unsafeCoerce x) + + +{- | Make a callback (JavaScript function) that runs the supplied IO function in a synchronous + thread when called. The callback takes one argument that it passes as a JSVal value to + the Haskell function. + Call 'releaseCallback' when done with the callback, freeing data referenced + by the function. + -} +syncCallback1 :: OnBlocked -- ^ what to do when the thread blocks + -> (JSVal -> IO ()) -- ^ the Haskell function + -> IO (Callback (JSVal -> IO ())) -- ^ the callback +syncCallback1 onBlocked x = js_syncCallbackApply (onBlocked == ContinueAsync) 1 (unsafeCoerce x) + + +{- | Make a callback (JavaScript function) that runs the supplied IO function in a synchronous + thread when called. The callback takes two arguments that it passes as JSVal values to + the Haskell function. + Call 'releaseCallback' when done with the callback, freeing data referenced + by the function. + -} +syncCallback2 :: OnBlocked -- ^ what to do when the thread blocks + -> (JSVal -> JSVal -> IO ()) -- ^ the Haskell function + -> IO (Callback (JSVal -> JSVal -> IO ())) -- ^ the callback +syncCallback2 onBlocked x = js_syncCallbackApply (onBlocked == ContinueAsync) 2 (unsafeCoerce x) + +{- | Make a callback (JavaScript function) that runs the supplied IO function in a synchronous + thread when called. The callback takes three arguments that it passes as JSVal values to + the Haskell function. + Call 'releaseCallback' when done with the callback, freeing data referenced + by the function. + -} +syncCallback3 :: OnBlocked -- ^ what to do when the thread blocks + -> (JSVal -> JSVal -> JSVal -> IO ()) -- ^ the Haskell function + -> IO (Callback (JSVal -> JSVal -> JSVal -> IO ())) -- ^ the callback +syncCallback3 onBlocked x = js_syncCallbackApply (onBlocked == ContinueAsync) 3 (unsafeCoerce x) + +{- | Make a callback (JavaScript function) that runs the supplied IO action in a synchronous + thread when called. + Call 'releaseCallback' when done with the callback, freeing memory referenced + by the IO action. + -} +syncCallback' :: IO JSVal + -> IO (Callback (IO JSVal)) +syncCallback' x = js_syncCallbackReturn (unsafeCoerce x) + +syncCallback1' :: (JSVal -> IO JSVal) + -> IO (Callback (JSVal -> IO JSVal)) +syncCallback1' x = js_syncCallbackApplyReturn 1 (unsafeCoerce x) + +syncCallback2' :: (JSVal -> JSVal -> IO JSVal) + -> IO (Callback (JSVal -> JSVal -> IO JSVal)) +syncCallback2' x = js_syncCallbackApplyReturn 2 (unsafeCoerce x) + +syncCallback3' :: (JSVal -> JSVal -> JSVal -> IO JSVal) + -> IO (Callback (JSVal -> JSVal -> JSVal -> IO JSVal)) +syncCallback3' x = js_syncCallbackApplyReturn 3 (unsafeCoerce x) + +{- | Make a callback (JavaScript function) that runs the supplied IO action in an asynchronous + thread when called. + Call 'releaseCallback' when done with the callback, freeing data referenced + by the IO action. + -} +asyncCallback :: IO () -- ^ the action that the callback runs + -> IO (Callback (IO ())) -- ^ the callback +asyncCallback x = js_asyncCallback (unsafeCoerce x) + +asyncCallback1 :: (JSVal -> IO ()) -- ^ the function that the callback calls + -> IO (Callback (JSVal -> IO ())) -- ^ the calback +asyncCallback1 x = js_asyncCallbackApply 1 (unsafeCoerce x) + +asyncCallback2 :: (JSVal -> JSVal -> IO ()) -- ^ the Haskell function that the callback calls + -> IO (Callback (JSVal -> JSVal -> IO ())) -- ^ the callback +asyncCallback2 x = js_asyncCallbackApply 2 (unsafeCoerce x) + +asyncCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -- ^ the Haskell function that the callback calls + -> IO (Callback (JSVal -> JSVal -> JSVal -> IO ())) -- ^ the callback +asyncCallback3 x = js_asyncCallbackApply 3 (unsafeCoerce x) + +-- ---------------------------------------------------------------------------- + +foreign import javascript unsafe "(($1, $2) => { return h$makeCallback(h$runSync, [$1], $2); })" + js_syncCallback :: Bool -> Exts.Any -> IO (Callback (IO b)) +foreign import javascript unsafe "(($1) => { return h$makeCallback(h$run, [], $1); })" + js_asyncCallback :: Exts.Any -> IO (Callback (IO b)) +foreign import javascript unsafe "(($1) => { return h$makeCallback(h$runSyncReturn, [false], $1); })" + js_syncCallbackReturn :: Exts.Any -> IO (Callback (IO JSVal)) + +foreign import javascript unsafe "(($1, $2, $3) => { return h$makeCallbackApply($2, h$runSync, [$1], $3); })" + js_syncCallbackApply :: Bool -> Int -> Exts.Any -> IO (Callback b) +foreign import javascript unsafe "(($1, $2) => { return h$makeCallbackApply($1, h$run, [], $2); })" + js_asyncCallbackApply :: Int -> Exts.Any -> IO (Callback b) +foreign import javascript unsafe "(($1, $2) => { return h$makeCallbackApply($1, h$runSyncReturn, [false], $2); })" + js_syncCallbackApplyReturn :: Int -> Exts.Any -> IO (Callback b) + +foreign import javascript unsafe "(($1) => { return h$release($1); })" + js_release :: Callback a -> IO () ===================================== libraries/base/GHC/JS/Prim.hs ===================================== @@ -277,13 +277,13 @@ foreign import javascript unsafe "(($1) => { return ($1 === null); })" foreign import javascript unsafe "(($1) => { return ($1 === undefined); })" js_isUndefined :: JSVal -> Bool -foreign import javascript unsafe "(($1) => { return ($r = typeof($1) === 'number' ? ($1|0) : 0;); })" +foreign import javascript unsafe "(($1) => { return (typeof($1) === 'number' ? ($1|0) : 0); })" js_fromJSInt :: JSVal -> Int -foreign import javascript unsafe "(($1) => { return ($r = $1;); })" +foreign import javascript unsafe "(($1) => { return $1; })" js_toJSInt :: Int -> JSVal -foreign import javascript unsafe "$r = null;" +foreign import javascript unsafe "(() => { return null; })" js_null :: JSVal foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })" @@ -307,7 +307,6 @@ foreign import javascript unsafe "(($1,$2_1,$2_2) => { return $1[h$decodeUtf8z($ foreign import javascript unsafe "(($1_1,$1_2) => { return h$decodeUtf8z($1_1, $1_2); })" js_unpackJSStringUtf8## :: Addr# -> State# s -> (# State# s, JSVal# #) - foreign import javascript unsafe "(($1_1, $1_2) => { return h$decodeUtf8z($1_1,$1_2); })" js_unsafeUnpackJSStringUtf8## :: Addr# -> JSVal# ===================================== libraries/base/base.cabal ===================================== @@ -475,6 +475,7 @@ Library GHC.JS.Prim GHC.JS.Prim.Internal GHC.JS.Prim.Internal.Build + GHC.JS.Foreign.Callback -- We need to set the unit id to base (without a version number) -- as it's magic. ===================================== testsuite/tests/javascript/all.T ===================================== @@ -2,3 +2,16 @@ setTestOpts(when(not(js_arch()),skip)) test('T23101', normal, compile_and_run, ['']) + +test('js-ffi-int', normal, compile_and_run, ['']) +test('js-ffi-string', normal, compile_and_run, ['']) +test('js-ffi-null', normal, compile_and_run, ['']) +test('js-ffi-isNull', normal, compile_and_run, ['']) +test('js-ffi-isUndefined', normal, compile_and_run, ['']) +test('js-ffi-array', normal, compile_and_run, ['']) + +test('js-callback01', normal, compile_and_run, ['']) +test('js-callback02', normal, compile_and_run, ['']) +test('js-callback03', normal, compile_and_run, ['']) +test('js-callback04', js_skip, compile_and_run, ['']) +test('js-callback05', js_skip, compile_and_run, ['']) ===================================== testsuite/tests/javascript/js-callback01.hs ===================================== @@ -0,0 +1,51 @@ +import GHC.JS.Prim +import GHC.JS.Foreign.Callback +import Control.Concurrent + +foreign import javascript "(() => { console.log('test'); })" + js_log0 :: IO () + +foreign import javascript "((x) => { console.log(x); })" + js_log1 :: JSVal -> IO () + +foreign import javascript "((x,y) => { console.log(x); console.log(y); })" + js_log2 :: JSVal -> JSVal -> IO () + +foreign import javascript "((x,y,z) => { console.log(x); console.log(y); console.log(z); })" + js_log3 :: JSVal -> JSVal -> JSVal -> IO () + +foreign import javascript "((f) => { f(); })" + js_apply0_ :: Callback (IO ()) -> IO () + +foreign import javascript "((f,x) => { f(x); })" + js_apply1_ :: Callback (JSVal -> IO ()) -> JSVal -> IO () + +foreign import javascript "((f,x,y) => { f(x,y); })" + js_apply2_ :: Callback (JSVal -> JSVal -> IO ()) -> JSVal -> JSVal -> IO () + +foreign import javascript "((f,x,y,z) => { f(x,y,z); })" + js_apply3_ :: Callback (JSVal -> JSVal -> JSVal -> IO ()) -> JSVal -> JSVal -> JSVal -> IO () + +main :: IO () +main = do + log0 <- syncCallback ThrowWouldBlock js_log0 + log1 <- syncCallback1 ThrowWouldBlock js_log1 + log2 <- syncCallback2 ThrowWouldBlock js_log2 + log3 <- syncCallback3 ThrowWouldBlock js_log3 + + js_apply0_ log0 + js_apply1_ log1 (toJSString "test1x") + js_apply2_ log2 (toJSString "test2x") (toJSString "test2y") + js_apply3_ log3 (toJSString "test3x") (toJSString "test3y") (toJSString "test3z") + + log0' <- asyncCallback js_log0 + log1' <- asyncCallback1 js_log1 + log2' <- asyncCallback2 js_log2 + log3' <- asyncCallback3 js_log3 + + js_apply0_ log0' + js_apply1_ log1' (toJSString "test") + js_apply2_ log2' (toJSString "test") (toJSString "test") + js_apply3_ log3' (toJSString "test") (toJSString "test") (toJSString "test") + + threadDelay 1000000 -- Wait long enough for the async actions to complete ===================================== testsuite/tests/javascript/js-callback01.stdout ===================================== @@ -0,0 +1,14 @@ +test +test1x +test2x +test2y +test3x +test3y +test3z +test +test +test +test +test +test +test ===================================== testsuite/tests/javascript/js-callback02.hs ===================================== @@ -0,0 +1,42 @@ +import GHC.JS.Prim +import GHC.JS.Foreign.Callback + +foreign import javascript "(() => { return 1; })" + plus_one0 :: IO JSVal + +foreign import javascript "((x) => { return x + 1; })" + plus_one1 :: JSVal -> IO JSVal + +foreign import javascript "((x,y) => { return x + y + 1; })" + plus_one2 :: JSVal -> JSVal -> IO JSVal + +foreign import javascript "((x,y,z) => { return x + y + z + 1; })" + plus_one3 :: JSVal -> JSVal -> JSVal -> IO JSVal + +foreign import javascript "((f) => { return f(); })" + js_apply0 :: Callback (IO JSVal) -> IO JSVal + +foreign import javascript "((f,x) => { return f(x); })" + js_apply1 :: Callback (JSVal -> IO JSVal) -> JSVal -> IO JSVal + +foreign import javascript "((f,x,y) => { return f(x,y); })" + js_apply2 :: Callback (JSVal -> JSVal -> IO JSVal) -> JSVal -> JSVal -> IO JSVal + +foreign import javascript "((f,x,y,z) => { return f(x,y,z); })" + js_apply3 :: Callback (JSVal -> JSVal -> JSVal -> IO JSVal) -> JSVal -> JSVal -> JSVal -> IO JSVal + +logJSInt :: JSVal -> IO () +logJSInt = print . fromJSInt + +main :: IO () +main = do + plusOne0 <- syncCallback' plus_one0 + plusOne1 <- syncCallback1' plus_one1 + plusOne2 <- syncCallback2' plus_one2 + plusOne3 <- syncCallback3' plus_one3 + + logJSInt =<< js_apply0 plusOne0 + logJSInt =<< js_apply1 plusOne1 (toJSInt 2) + logJSInt =<< js_apply2 plusOne2 (toJSInt 2) (toJSInt 3) + logJSInt =<< js_apply3 plusOne3 (toJSInt 2) (toJSInt 3) (toJSInt 4) + ===================================== testsuite/tests/javascript/js-callback02.stdout ===================================== @@ -0,0 +1,4 @@ +1 +3 +6 +10 ===================================== testsuite/tests/javascript/js-callback03.hs ===================================== @@ -0,0 +1,33 @@ +import GHC.JS.Prim +import GHC.JS.Foreign.Callback + +foreign import javascript "((f) => { globalF = f; })" + setF :: Callback (JSVal -> IO ()) -> IO () + +foreign import javascript "((x) => { globalF(x); })" + callF :: JSVal -> IO () + +foreign import javascript "((x,y) => { return x + y })" + js_plus :: JSVal -> JSVal -> IO JSVal + +foreign import javascript "((g) => { globalG = g; })" + setG :: Callback (JSVal -> JSVal -> IO JSVal) -> IO () + +foreign import javascript "((x,y) => { return globalG(x,y); })" + callG :: JSVal -> JSVal -> IO JSVal + +main :: IO () +main = do + -- Set functions globally on the JavaScript side, to be accessed in regular JavaScript code + f <- syncCallback1 ThrowWouldBlock (\x -> if isNull x then putStrLn "isNull" else putStrLn "isNotNull") + g <- syncCallback2' js_plus + setF f + setG g + + -- Do other things before using the globally-set functions + putStrLn "test" + + -- Use the globally-set functions + callF jsNull + callF $ toJSString "" + print . fromJSInt =<< callG (toJSInt 1) (toJSInt 2) ===================================== testsuite/tests/javascript/js-callback03.stdout ===================================== @@ -0,0 +1,4 @@ +test +isNull +isNotNull +3 ===================================== testsuite/tests/javascript/js-callback04.hs ===================================== @@ -0,0 +1,16 @@ +import GHC.JS.Prim +import GHC.JS.Foreign.Callback + +foreign import javascript "(() => { console.log('javascript'); })" + js_log :: IO () + +foreign import javascript "((f) => { f(); })" + js_apply0_ :: Callback (IO ()) -> IO () + +main :: IO () +main = do + logH <- syncCallback ThrowWouldBlock (putStrLn "haskell") + logJ <- syncCallback ThrowWouldBlock js_log + + js_apply0_ logH + js_apply0_ logJ ===================================== testsuite/tests/javascript/js-callback04.stdout ===================================== @@ -0,0 +1,2 @@ +haskell +javascript ===================================== testsuite/tests/javascript/js-callback05.hs ===================================== @@ -0,0 +1,19 @@ +import GHC.JS.Prim +import GHC.JS.Foreign.Callback +import System.IO + +foreign import javascript "((f) => { f(); })" + js_apply0_ :: Callback (IO ()) -> IO () + +main :: IO () +main = do + log <- syncCallback ThrowWouldBlock (putStrLn "test" >> hFlush stdout) + js_apply0_ log + js_apply0_ log + + log <- syncCallback ThrowWouldBlock (putStrLn "test1" >> hFlush stdout) + log <- syncCallback ThrowWouldBlock (putStrLn "test2" >> hFlush stdout) + log <- syncCallback ThrowWouldBlock (putStrLn "test3" >> hFlush stdout) + js_apply0_ log1 + js_apply0_ log2 + js_apply0_ log3 ===================================== testsuite/tests/javascript/js-callback05.stdout ===================================== @@ -0,0 +1,5 @@ +test +test +test1 +test2 +test3 ===================================== testsuite/tests/javascript/js-ffi-array.hs ===================================== @@ -0,0 +1,18 @@ +import GHC.JS.Prim + +foreign import javascript "((xs) => { console.log(xs) })" + log_js :: JSVal -> IO () + +foreign import javascript "((xs,i) => { return xs[i]; })" + js_index :: JSVal -> JSVal -> JSVal + +foreign import javascript "(() => { return ['t','e','s','t']; })" + an_array :: JSVal + +main :: IO () +main = do + log_js =<< toJSArray [] + log_js =<< toJSArray [jsNull, toJSInt 0, toJSString "", toJSInt 1, toJSString "test", toJSInt 2] + xs <- toJSArray $ map toJSInt [1..10] + log_js $ js_index xs (toJSInt 3) + mapM_ log_js =<< fromJSArray an_array ===================================== testsuite/tests/javascript/js-ffi-array.stdout ===================================== @@ -0,0 +1,7 @@ +[] +[ null, 0, '', 1, 'test', 2 ] +4 +t +e +s +t ===================================== testsuite/tests/javascript/js-ffi-int.hs ===================================== @@ -0,0 +1,16 @@ +import GHC.JS.Prim + +foreign import javascript "((x) => { console.log(x); })" + log_js_int :: JSVal -> IO () + +foreign import javascript "(() => { return 3; })" + an_int :: JSVal + +main :: IO () +main = do + log_js_int (toJSInt 0) + log_js_int (toJSInt 1) + log_js_int (toJSInt 2) + log_js_int an_int + print (fromJSInt an_int) + print (fromJSInt $ toJSInt 4) ===================================== testsuite/tests/javascript/js-ffi-int.stdout ===================================== @@ -0,0 +1,6 @@ +0 +1 +2 +3 +3 +4 ===================================== testsuite/tests/javascript/js-ffi-isNull.hs ===================================== @@ -0,0 +1,10 @@ +import GHC.JS.Prim + +main :: IO () +main = do + print (isNull jsNull) + print (isNull $ toJSString "") + print (isNull $ toJSString "test") + print (isNull $ toJSInt 0) + print (isNull $ toJSInt 1) + print (isNull $ toJSInt 2) ===================================== testsuite/tests/javascript/js-ffi-isNull.stdout ===================================== @@ -0,0 +1,6 @@ +True +False +False +False +False +False ===================================== testsuite/tests/javascript/js-ffi-isUndefined.hs ===================================== @@ -0,0 +1,13 @@ +import GHC.JS.Prim + +foreign import javascript "((x) => { return undefined; })" + js_undefined :: JSVal + +main :: IO () +main = do + print (isUndefined js_undefined) + print (isUndefined $ toJSString "") + print (isUndefined $ toJSString "test") + print (isUndefined $ toJSInt 0) + print (isUndefined $ toJSInt 1) + print (isUndefined $ toJSInt 2) ===================================== testsuite/tests/javascript/js-ffi-isUndefined.stdout ===================================== @@ -0,0 +1,6 @@ +True +False +False +False +False +False ===================================== testsuite/tests/javascript/js-ffi-null.hs ===================================== @@ -0,0 +1,7 @@ +import GHC.JS.Prim + +foreign import javascript "((x) => { console.log(x); })" + log_null :: JSVal -> IO () + +main :: IO () +main = log_null jsNull ===================================== testsuite/tests/javascript/js-ffi-null.stdout ===================================== @@ -0,0 +1 @@ +null ===================================== testsuite/tests/javascript/js-ffi-string.hs ===================================== @@ -0,0 +1,13 @@ +import GHC.JS.Prim + +foreign import javascript "((x) => { console.log(x); })" + log_js_string :: JSVal -> IO () + +foreign import javascript "(() => { return 'a string'; })" + a_string :: JSVal + +main :: IO () +main = do + log_js_string (toJSString "test") + putStrLn (fromJSString a_string) + putStrLn (fromJSString $ toJSString "test") ===================================== testsuite/tests/javascript/js-ffi-string.stdout ===================================== @@ -0,0 +1,3 @@ +test +a string +test View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27d2978e5412f2bef4448e208182a03137dd5ee8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27d2978e5412f2bef4448e208182a03137dd5ee8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 13:03:38 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 13 Apr 2023 09:03:38 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 63 commits: Allow LLVM 14 Message-ID: <6437fdaaba45c_10a80d1b068fcc33014c@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 35aedf29 by Zubin Duggal at 2023-04-13T18:32:11+05:30 Allow LLVM 14 - - - - - 1fe02d69 by Ben Gamari at 2023-04-13T18:32:11+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - 074243ad by Ben Gamari at 2023-04-13T18:32:11+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 2bd2272f by Ben Gamari at 2023-04-13T18:32:11+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - bc49e406 by Ben Gamari at 2023-04-13T18:32:11+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - 2f2949cf by Ben Gamari at 2023-04-13T18:32:11+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - dc0f6aed by Ben Gamari at 2023-04-13T18:32:11+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - 7e5f322e by Ben Gamari at 2023-04-13T18:32:11+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - ea78129a by Ben Gamari at 2023-04-13T18:32:11+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - 333f6ba3 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - f5e1ac14 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - 2b416775 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 91e3a4ca by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - 99ea20a2 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - 0dd134a0 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - 28966f87 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - a88afd8e by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - d4ca3765 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - c698b9e8 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - b5600dca by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - c8d66b9b by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - 9b64396f by Ben Gamari at 2023-04-13T18:32:12+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - cc8f7b82 by Ben Gamari at 2023-04-13T18:32:12+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - 022c7500 by Ben Gamari at 2023-04-13T18:32:12+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - 074895f4 by Ben Gamari at 2023-04-13T18:32:12+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - 8e707288 by Ben Gamari at 2023-04-13T18:32:12+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - 34f4fdb9 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - 7bfa1b7a by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - 52972ea4 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - d0a62880 by Ben Gamari at 2023-04-13T18:32:12+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - ce559154 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - 9e459024 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - 031fc563 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - 5f6ba2c1 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 701904d2 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - 89829497 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - cd6d8d88 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - 5880feb1 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - c0b79141 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - 0f5a95a3 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - 236c29fd by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - 43143654 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - 0c440ba6 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - 80d5adcc by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - 6d790d46 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - 222c16ff by Ben Gamari at 2023-04-13T18:32:13+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - c1c3983b by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - 394f2667 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - 057093df by Ben Gamari at 2023-04-13T18:32:13+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - b84a33b2 by Ben Gamari at 2023-04-13T18:32:13+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - bf9d4ebc by Ben Gamari at 2023-04-13T18:32:13+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - 77d67957 by Ben Gamari at 2023-04-13T18:32:14+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - d292ffcb by Ben Gamari at 2023-04-13T18:32:14+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - 8ff50704 by Ben Gamari at 2023-04-13T18:32:14+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - bb3d4605 by Ben Gamari at 2023-04-13T18:32:14+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - b24b6f84 by Ben Gamari at 2023-04-13T18:32:14+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - 3da2b1d2 by Ben Gamari at 2023-04-13T18:32:14+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - 1f3a993d by Ben Gamari at 2023-04-13T18:32:14+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - a4700817 by Ben Gamari at 2023-04-13T18:32:14+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 005e6f32 by Ben Gamari at 2023-04-13T18:32:14+05:30 contextswitch - - - - - 78d3f899 by Ben Gamari at 2023-04-13T18:32:14+05:30 rts: Fix incorrect format specifier warnings - - - - - c41c0fc0 by Zubin Duggal at 2023-04-13T18:32:14+05:30 compiler: Fix performance regression in backport of "Make FloatIn robust to shadowing" (6206cb9287f3f6e70c669660a646a65274870d2b) In 9.4, we have noFloatIntoArg :: CoreExprWithFVs' -> Type -> Bool noFloatIntoArg expr expr_ty = ... But in master when 6206cb92 landed, after "Drop the app invariant" (dcf30da8) we had noFloatIntoArg :: CoreExprWithFVs' -> Bool noFloatIntoArg expr = ... When deciding whether to float things into the argument of a function, in 9.4 we must know the type of the argument. This was previously done by extracting the type of the argument from the function type, computed as we walked through all the arguments. However, this backport regressed compile time performance due to allocations by `exprType` particularly in T16577 and T5642, where it turns out that computing the type of the arguments to a function is quite expensive. Instead, we can compute the type of the argument by looking at the argument term directly, which turns out to be much faster and eliminates the performance regression. - - - - - e34731c8 by Zubin Duggal at 2023-04-13T18:32:14+05:30 Prepare release 9.4.5 - - - - - 30 changed files: - compiler/GHC/Core/Opt/FloatIn.hs - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - hadrian/src/Flavour.hs - libraries/base/changelog.md - rts/Capability.c - rts/Capability.h - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/PrimOps.cmm - rts/Printer.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Sparks.h - rts/Stats.c - rts/Threads.c - rts/Timer.c - rts/TraverseHeap.c - rts/eventlog/EventLog.c - rts/include/rts/storage/ClosureMacros.h - rts/include/rts/storage/GC.h - rts/include/rts/storage/MBlock.h - rts/include/stg/SMP.h - rts/posix/Select.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f37378b34c34c193912760ef413ac72eb3457f2d...e34731c80cf08c6d31ab1dc8924525aace9b4990 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f37378b34c34c193912760ef413ac72eb3457f2d...e34731c80cf08c6d31ab1dc8924525aace9b4990 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 14:56:26 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 13 Apr 2023 10:56:26 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/unused-ghc-prim Message-ID: <6438181adfc3d_10a80d1d279ef4341494@gitlab.mail> Matthew Pickering pushed new branch wip/unused-ghc-prim at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/unused-ghc-prim You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 16:03:14 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 13 Apr 2023 12:03:14 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead Message-ID: <643827c23fd48_10a80d1e51add83560b5@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: c4c441a2 by Sebastian Graf at 2023-04-13T18:02:57+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 8dfac072 by Sebastian Graf at 2023-04-13T18:02:57+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 29 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -717,9 +717,14 @@ this exhaustive list can be empty! its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils -* An empty case is replaced by its scrutinee during the CoreToStg - conversion; remember STG is un-typed, so there is no need for - the empty case to do the type conversion. +* In CoreToStg, when extracting a StgArg from an StgExpr, we have to look into + empty case scrutinees, not unlike GHC.Core.Utils.getIdFromTrivialExpr. + +* An empty case is compiled as an eval on the scrutinee in + GHC.StgToCmm.Expr.cgCase and GHC.StgToJS.Expr.genCase. + Historically, we lowered EmptyCase in CorePrep by way of an unsafeCoercion on + the scrutinee, but that yielded panics in CodeGen when we were beginning to + eta expand in arguments. It's simpler to stick to it until Cmm anyway. Note [Join points] ~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -1390,7 +1390,7 @@ setNominalRole_maybe r co | case prov of PhantomProv _ -> False -- should always be phantom ProofIrrelProv _ -> True -- it's always safe PluginProv _ -> False -- who knows? This choice is conservative. - CorePrepProv _ -> True + CorePrepProv -> True = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1516,7 +1516,7 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco UnivCo (PluginProv _) _ _ _ -> mkKindCo co - UnivCo (CorePrepProv _) _ _ _ -> mkKindCo co + UnivCo CorePrepProv _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2339,7 +2339,7 @@ seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co seqProv (PluginProv _) = () -seqProv (CorePrepProv _) = () +seqProv CorePrepProv = () seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -622,7 +622,7 @@ opt_univ env sym prov role oty1 oty2 #endif ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco PluginProv _ -> prov - CorePrepProv _ -> prov + CorePrepProv -> prov ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,7 @@ orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co orphNamesOfProv (PluginProv _) = emptyNameSet -orphNamesOfProv (CorePrepProv _) = emptyNameSet +orphNamesOfProv CorePrepProv = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo @@ -798,4 +798,3 @@ freeVars = go go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) - ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2301,9 +2301,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) -- see #9122 for discussion of these checks checkTypes t1 t2 - | allow_ill_kinded_univ_co prov - = return () -- Skip kind checks - | otherwise = do { checkWarnL fixed_rep_1 (report "left-hand type does not have a fixed runtime representation") ; checkWarnL fixed_rep_2 @@ -2321,13 +2318,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) reps1 = typePrimRep t1 reps2 = typePrimRep t2 - -- CorePrep deliberately makes ill-kinded casts - -- e.g (case error @Int "blah" of {}) :: Int# - -- ==> (error @Int "blah") |> Unsafe Int Int# - -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - allow_ill_kinded_univ_co (CorePrepProv homo_kind) = not homo_kind - allow_ill_kinded_univ_co _ = False - validateCoercion :: PrimRep -> PrimRep -> LintM () validateCoercion rep1 rep2 = do { platform <- getPlatform @@ -2357,8 +2347,8 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov - lint_prov _ _ prov@(CorePrepProv _) = return prov + lint_prov _ _ prov@(PluginProv _) = return prov + lint_prov _ _ prov at CorePrepProv = return prov check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -661,7 +661,7 @@ tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc -tyCoFVsOfProv (CorePrepProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc +tyCoFVsOfProv CorePrepProv fv_cand in_scope acc = emptyFV fv_cand in_scope acc tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -731,8 +731,8 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True -almost_devoid_co_var_of_prov (CorePrepProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _) _ = True +almost_devoid_co_var_of_prov CorePrepProv _ = True almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1104,7 +1104,7 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyUniqSet - go_prov (CorePrepProv _) = emptyUniqSet + go_prov CorePrepProv = emptyUniqSet -- this last case can happen from the tyConsOfType used from -- checkTauTvUpdate @@ -1318,5 +1318,4 @@ occCheckExpand vs_to_avoid ty go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p - + go_prov _ p at CorePrepProv = return p ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1437,9 +1437,9 @@ data UnivCoProvenance | PluginProv String -- ^ From a plugin, which asserts that this coercion -- is sound. The string is for the use of the plugin. - | CorePrepProv -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - Bool -- True <=> the UnivCo must be homogeneously kinded - -- False <=> allow hetero-kinded, e.g. Int ~ Int# + | CorePrepProv -- ^ See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep + -- The UnivCo is always homogeneously kinded, e.g., it + -- disallows Int ~ Int# deriving Data.Data @@ -1447,7 +1447,7 @@ instance Outputable UnivCoProvenance where ppr (PhantomProv _) = text "(phantom)" ppr (ProofIrrelProv _) = text "(proof irrel.)" ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) - ppr (CorePrepProv _) = text "(CorePrep)" + ppr CorePrepProv = text "(CorePrep)" -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1760,7 +1760,7 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co go_prov _ (PluginProv _) = mempty - go_prov _ (CorePrepProv _) = mempty + go_prov _ CorePrepProv = mempty -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1821,7 +1821,7 @@ provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co provSize (PluginProv _) = 1 -provSize (CorePrepProv _) = 1 +provSize CorePrepProv = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -912,7 +912,7 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -252,7 +252,7 @@ tidyCo env@(_, subst) co go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -563,7 +563,7 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) go_prov _ p@(PluginProv _) = p - go_prov _ p@(CorePrepProv _) = p + go_prov _ p at CorePrepProv = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -981,7 +981,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov env (PhantomProv co) = PhantomProv <$> go_co env co go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p + go_prov _ p at CorePrepProv = return p {- ********************************************************************* ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -321,7 +321,7 @@ toIfaceCoercionX fr co go_prov (PhantomProv co) = IfacePhantomProv (go co) go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) go_prov (PluginProv str) = IfacePluginProv str - go_prov (CorePrepProv b) = IfaceCorePrepProv b + go_prov CorePrepProv = IfaceCorePrepProv toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -19,8 +19,7 @@ module GHC.CoreToStg ( CoreToStgOpts (..), coreToStg ) where import GHC.Prelude import GHC.Core -import GHC.Core.Utils ( exprType, findDefault, isJoinBind - , exprIsTickedString_maybe ) +import GHC.Core.Utils import GHC.Core.Opt.Arity ( manifestArity ) import GHC.Core.Type import GHC.Core.TyCon @@ -430,29 +429,7 @@ coreToStgExpr (Cast expr _) = coreToStgExpr expr -- Cases require a little more real work. - -{- -coreToStgExpr (Case scrut _ _ []) - = coreToStgExpr scrut - -- See Note [Empty case alternatives] in GHC.Core If the case - -- alternatives are empty, the scrutinee must diverge or raise an - -- exception, so we can just dive into it. - -- - -- Of course this may seg-fault if the scrutinee *does* return. A - -- belt-and-braces approach would be to move this case into the - -- code generator, and put a return point anyway that calls a - -- runtime system error function. - -coreToStgExpr e0@(Case scrut bndr _ [alt]) = do - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder is dead - -- It usually is, but see #18227 - , (_,_,rhs) <- alt - = coreToStgExpr rhs - -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce --} - --- The normal case for case-expressions +-- As Note [Empty case alternatives] says, we hold on to EmptyCase here. coreToStgExpr (Case scrut bndr _ alts) = do { scrut2 <- coreToStgExpr scrut ; alts2 <- extendVarEnvCts [(bndr, LambdaBound)] (mapM vars_alt alts) @@ -597,8 +574,11 @@ coreToStgArgs (arg : args) = do -- Non-type argument arg' <- coreToStgExpr arg let (aticks, arg'') = stripStgTicksTop tickishFloatable arg' - stg_arg = case arg'' of + -- stg_arg is somewhat like getIdFromTrivialExpr, only that it works on + -- Stg and extracts Var or Lit args + stg_arg arg = case arg of StgApp v [] -> StgVarArg v + StgCase arg' _ _ [] -> stg_arg arg' -- See Note [Empty case alternatives] StgConApp con _ [] _ -> StgVarArg (dataConWorkId con) StgOpApp (StgPrimOp op) [] _ -> StgVarArg (primOpWrapperId op) StgLit lit -> StgLitArg lit @@ -617,11 +597,11 @@ coreToStgArgs (arg : args) = do -- Non-type argument platform <- getPlatform let arg_rep = typePrimRep (exprType arg) - stg_arg_rep = typePrimRep (stgArgType stg_arg) + stg_arg_rep = typePrimRep (stgArgType (stg_arg arg'')) bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep) warnPprTrace bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) $ - return (stg_arg : stg_args, ticks ++ aticks) + return (stg_arg arg'': stg_args, ticks ++ aticks) coreToStgTick :: Type -- type of the ticked expression -> CoreTickish @@ -959,6 +939,9 @@ myCollectBinders expr -- | If the argument expression is (potential chain of) 'App', return the head -- of the app chain, and collect ticks/args along the chain. +-- INVARIANT: If the app head is trivial, return the atomic Var/Lit that was +-- wrapped in casts, empty case, ticks, etc. +-- So keep in sync with 'exprIsTrivial'. myCollectArgs :: HasDebugCallStack => CoreExpr -> (CoreExpr, [CoreArg], [CoreTickish]) myCollectArgs expr = go expr [] [] @@ -970,8 +953,10 @@ myCollectArgs expr -- See Note [Ticks in applications] go e as (t:ts) -- ticks can appear in type apps go (Cast e _) as ts = go e as ts + go (Case e _ _ []) as ts = assertPpr (null as) (ppr e $$ ppr as $$ ppr expr) $ + go e [] ts -- NB: Empty case discards arguments go (Lam b e) as ts - | isTyVar b = go e as ts -- Note [Collect args] + | isTyVar b = go e (drop 1 as) ts -- Note [Collect args] go e as ts = (e, as, ts) {- Note [Collect args] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -142,7 +142,7 @@ The goal of this pass is to prepare for code generation. profiling mode. We have to do this here because we won't have unfoldings after this pass (see `trimUnfolding` and Note [Drop unfoldings and rules]. -12. Eliminate case clutter in favour of unsafe coercions. +12. Eliminate unsafeEqualityProof in favour of unsafe coercions. See Note [Unsafe coercions] 13. Eliminate some magic Ids, specifically @@ -159,45 +159,17 @@ any trivial or useless bindings. Note [Unsafe coercions] ~~~~~~~~~~~~~~~~~~~~~~~ -CorePrep does these two transformations: - -1. Convert empty case to cast with an unsafe coercion - (case e of {}) ===> e |> unsafe-co - See Note [Empty case alternatives] in GHC.Core: if the case - alternatives are empty, the scrutinee must diverge or raise an - exception, so we can just dive into it. - - Of course, if the scrutinee *does* return, we may get a seg-fault. - A belt-and-braces approach would be to persist empty-alternative - cases to code generator, and put a return point anyway that calls a - runtime system error function. - - Notice that eliminating empty case can lead to an ill-kinded coercion - case error @Int "foo" of {} :: Int# - ===> error @Int "foo" |> unsafe-co - where unsafe-co :: Int ~ Int# - But that's fine because the expression diverges anyway. And it's - no different to what happened before. - -2. Eliminate unsafeEqualityProof in favour of an unsafe coercion - case unsafeEqualityProof of UnsafeRefl g -> e - ===> e[unsafe-co/g] - See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce - - Note that this requires us to substitute 'unsafe-co' for 'g', and - that is the main (current) reason for cpe_tyco_env in CorePrepEnv. - Tiresome, but not difficult. - -These transformations get rid of "case clutter", leaving only casts. -We are doing no further significant transformations, so the reasons -for the case forms have disappeared. And it is extremely helpful for -the ANF-ery, CoreToStg, and backends, if trivial expressions really do -look trivial. #19700 was an example. - -In both cases, the "unsafe-co" is just (UnivCo ty1 ty2 (CorePrepProv b)), -The boolean 'b' says whether the unsafe coercion is supposed to be -kind-homogeneous (yes for (2), no for (1). This information is used -/only/ by Lint. +CorePrep eliminates unsafeEqualityProof in favour of an unsafe coercion + case unsafeEqualityProof of UnsafeRefl g -> e + ===> e[unsafe-co/g] +See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce. + +The "unsafe-co" is just (UnivCo ty1 ty2 CorePrepProv), +a coercion that is always kind-homogeneous (as checked by Lint). + +Note that this requires us to substitute 'unsafe-co' for 'g', and +that is the main (current) reason for cpe_tyco_env in CorePrepEnv. +Tiresome, but not difficult. Note [CorePrep invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -830,23 +802,6 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } --- Eliminate empty case --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut _ ty []) - = do { (floats, scrut') <- cpeRhsE env scrut - ; let ty' = cpSubstTy env ty - scrut_ty' = exprType scrut' - co' = mkUnivCo prov Representational scrut_ty' ty' - prov = CorePrepProv False - -- False says that the kinds of two types may differ - -- E.g. we might cast Int to Int#. This is fine - -- because the scrutinee is guaranteed to diverge - - ; return (floats, Cast scrut' co') } - -- This can give rise to - -- Warning: Unsafe coercion: between unboxed and boxed value - -- but it's fine because 'scrut' diverges - -- Eliminate unsafeEqualityProof -- See Note [Unsafe coercions] cpeRhsE env (Case scrut bndr _ alts) @@ -855,8 +810,7 @@ cpeRhsE env (Case scrut bndr _ alts) -- is dead. It usually is, but see #18227 , [Alt _ [co_var] rhs] <- alts , let Pair ty1 ty2 = coVarTypes co_var - the_co = mkUnivCo prov Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) - prov = CorePrepProv True -- True <=> kind homogeneous + the_co = mkUnivCo CorePrepProv Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) env' = extendCoVarEnv env co_var the_co = cpeRhsE env' rhs @@ -1491,12 +1445,33 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1614,6 +1589,40 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + let t = g x + in f t +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + let t = \y. g x y + in f t +The arity to which we eta expand is easily determined by 'exprArity', which is +very cheap. + +We eta expand arguments here, in CorePrep, rather than in the Simplifier, +because it would be costly to run arity analysis on arguments repeatedly. +That is especially true for 'exprEtaExpandArity', the full-blown arity analyser +which eta-expands over ok-for-spec stuff, that the Simplifier uses for +let RHSs and lambda bodies. + +Analysing arguments with 'exprEtaExpandArity' however allows us to eta expand +arguments containing seqs (with -fno-pedantic-bottoms, no less) such as in +T23083 + let t = case z of __DEFAULT -> g x + in f t +to + let t = \y -> case z of __DEFAULT -> g x + in f t +so in the presence of -fdo-arg-eta-expansion (implied by -O2) we analyse with +'exprEtaExpandArity' for parity with what the Simplifier did to the let binding +if it saw the ANFised form. + +Note that eta expanding `t` gives rise to another opportunity, namely to inline +`g` (in the Simplifier), potentially enabling subsequent optimisations. But the +we could have inlined `g` into the PAP to begin with, as discussed in #22886. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1977,6 +1986,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1987,6 +2001,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -259,6 +259,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoArgEtaExpansion -- Eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3398,6 +3398,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-arg-eta-expansion" Opt_DoArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -3990,6 +3991,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([2], Opt_DoArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1741,7 +1741,7 @@ freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co freeNamesIfProv (IfacePluginProv _) = emptyNameSet -freeNamesIfProv (IfaceCorePrepProv _) = emptyNameSet +freeNamesIfProv IfaceCorePrepProv = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -402,7 +402,7 @@ data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String - | IfaceCorePrepProv Bool -- See defn of CorePrepProv + | IfaceCorePrepProv -- See defn of CorePrepProv {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,7 +624,7 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) go_prov co@(IfacePluginProv _) = co - go_prov co@(IfaceCorePrepProv _) = co + go_prov co at IfaceCorePrepProv = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1860,7 +1860,7 @@ pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) -pprIfaceUnivCoProv (IfaceCorePrepProv _) +pprIfaceUnivCoProv IfaceCorePrepProv = text "CorePrep" ------------------- @@ -2229,9 +2229,8 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a) = do putByte bh 3 put_ bh a - put_ bh (IfaceCorePrepProv a) = do + put_ bh IfaceCorePrepProv = do putByte bh 4 - put_ bh a get bh = do tag <- getByte bh @@ -2242,8 +2241,7 @@ instance Binary IfaceUnivCoProv where return $ IfaceProofIrrelProv a 3 -> do a <- get bh return $ IfacePluginProv a - 4 -> do a <- get bh - return (IfaceCorePrepProv a) + 4 -> do return IfaceCorePrepProv _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1510,7 +1510,7 @@ tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceCorePrepProv b) = return $ CorePrepProv b +tcIfaceUnivCoProv IfaceCorePrepProv = return CorePrepProv {- ************************************************************************ ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -447,7 +447,7 @@ stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr -mkStgCase scrut bndr ty alts | all isBndr alts = scrut +mkStgCase scrut bndr ty alts | all isBndr alts = scrut -- NB: Always true for empty Case! | otherwise = StgCase scrut bndr ty alts where ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -650,6 +650,9 @@ elimCase _ args bndr alt_ty alts -------------------------------------------------------------------------------- unariseAlts :: UnariseEnv -> AltType -> InId -> [StgAlt] -> UniqSM [StgAlt] +unariseAlts _ _ _ [] + = return [] -- See Note [Empty case alternatives] + unariseAlts rho (MultiValAlt n) bndr [GenStgAlt{ alt_con = DEFAULT , alt_bndrs = [] , alt_rhs = e}] ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -53,7 +53,6 @@ import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import Control.Monad ( unless, void ) import Control.Arrow ( first ) @@ -427,6 +426,8 @@ data GcPlan ------------------------------------- cgCase :: CgStgExpr -> Id -> AltType -> [CgStgAlt] -> FCode ReturnKind +cgCase e _ _ [] = cgExpr e -- See Note [Empty case alternatives] + {- Note [Scrutinising VoidRep] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1028,7 +1029,7 @@ cgIdApp fun_id args = do (text "TagCheck failed on entry in" <+> ppr mod <+> text "- value:" <> ppr fun_id <+> pdoc platform fun)) fun - EnterIt -> assert (null args) $ -- Discarding arguments + EnterIt -> assertPpr (null args) (ppr fun_id $$ ppr args) $ -- Discarding arguments emitEnter fun SlowCall -> do -- A slow function call via the RTS apply routines ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -570,6 +570,9 @@ genCase :: HasDebugCallStack -> LiveVars -> G (JStat, ExprResult) genCase ctx bnd e at alts l + | [] <- alts = genExpr ctx e + -- See Note [Empty case alternatives]; + -- we simply generate code for eval'ing the scrutinee | snd (isInlineExpr (ctxEvaluatedIds ctx) e) = do bndi <- identsForId bnd let ctx' = ctxSetTop bnd ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -157,7 +157,7 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyNameEnv - go_prov (CorePrepProv _) = emptyNameEnv + go_prov CorePrepProv = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1535,7 +1535,7 @@ collect_cand_qtvs_co orig_ty bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co go_prov dv (PluginProv _) = return dv - go_prov dv (CorePrepProv _) = return dv + go_prov dv CorePrepProv = return dv go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,16 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-arg-eta-expansion + :shortdesc: Enable argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T23083 where + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,42 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 27, types: 24, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 12, types: 13, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> GHC.Base.$ @GHC.Types.LiftedRep @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62f77bf143492f6d983b9533978c21ef920278bd...8dfac07272cd782d19a19541603fa89f49e1a83d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62f77bf143492f6d983b9533978c21ef920278bd...8dfac07272cd782d19a19541603fa89f49e1a83d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 16:13:07 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 13 Apr 2023 12:13:07 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/js-mkdir Message-ID: <64382a1382ebb_10a80d1e70d014358354@gitlab.mail> Josh Meredith pushed new branch wip/js-mkdir at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/js-mkdir You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 16:25:52 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 13 Apr 2023 12:25:52 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 9 commits: Add quotRem rules (#22152) Message-ID: <64382d106f850_10a80d1ea944f8369452@gitlab.mail> Simon Peyton Jones pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - 8336db84 by Simon Peyton Jones at 2023-04-13T17:27:36+01:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - fad82547 by Simon Peyton Jones at 2023-04-13T17:27:37+01:00 Add some documentation about redundant constraints - - - - - 4a1353ab by Simon Peyton Jones at 2023-04-13T17:27:37+01:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - f8579b80 by Simon Peyton Jones at 2023-04-13T17:27:37+01:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 19 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7ea954b8ad6beac0c6f3eb350f0b576d42b3e68...f8579b80b7610be6f11cae1586857c0b59bd3e43 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e7ea954b8ad6beac0c6f3eb350f0b576d42b3e68...f8579b80b7610be6f11cae1586857c0b59bd3e43 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 16:55:13 2023 From: gitlab at gitlab.haskell.org (ase (@adamse)) Date: Thu, 13 Apr 2023 12:55:13 -0400 Subject: [Git][ghc/ghc][wip/adamse/stableptr-clarifications] rts: improve memory ordering and add some comments to the StablePtr implementation Message-ID: <643833f1fcb5_10a80d1f24f1fc3835e6@gitlab.mail> ase pushed to branch wip/adamse/stableptr-clarifications at Glasgow Haskell Compiler / GHC Commits: 913f1060 by Adam Sandberg Ericsson at 2023-04-13T17:54:15+01:00 rts: improve memory ordering and add some comments to the StablePtr implementation - - - - - 1 changed file: - rts/StablePtr.c Changes: ===================================== rts/StablePtr.c ===================================== @@ -98,8 +98,13 @@ */ +// the global stable pointer entry table spEntry *stable_ptr_table = NULL; + +// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after static spEntry *stable_ptr_free = NULL; + +// current stable pointer table size static unsigned int SPT_size = 0; #define INIT_SPT_SIZE 64 @@ -117,6 +122,7 @@ static unsigned int SPT_size = 0; #error unknown SIZEOF_VOID_P #endif +// old stable pointer tables static spEntry *old_SPTs[MAX_N_OLD_SPTS]; static uint32_t n_old_SPTs = 0; @@ -149,8 +155,9 @@ stablePtrUnlock(void) * -------------------------------------------------------------------------- */ STATIC_INLINE void -initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free) +initSpEntryFreeList(spEntry *table, uint32_t n) { + spEntry* free = NULL; spEntry *p; for (p = table + n - 1; p >= table; p--) { p->addr = (P_)free; @@ -166,7 +173,7 @@ initStablePtrTable(void) SPT_size = INIT_SPT_SIZE; stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry), "initStablePtrTable"); - initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL); + initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE); #if defined(THREADED_RTS) initMutex(&stable_ptr_mutex); @@ -181,6 +188,8 @@ initStablePtrTable(void) static void enlargeStablePtrTable(void) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + uint32_t old_SPT_size = SPT_size; spEntry *new_stable_ptr_table; @@ -206,7 +215,8 @@ enlargeStablePtrTable(void) */ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table); - initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); + // add the new entries to the free list + initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size); } /* Note [Enlarging the stable pointer table] @@ -245,6 +255,7 @@ exitStablePtrTable(void) { if (stable_ptr_table) stgFree(stable_ptr_table); + stable_ptr_table = NULL; SPT_size = 0; @@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp) void freeStablePtrUnsafe(StgStablePtr sp) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + // see Note [NULL StgStablePtr] if (sp == NULL) { return; } + StgWord spw = (StgWord)sp - 1; + ASSERT(spw < SPT_size); + freeSpEntry(&stable_ptr_table[spw]); } @@ -278,25 +294,35 @@ void freeStablePtr(StgStablePtr sp) { stablePtrLock(); + freeStablePtrUnsafe(sp); + stablePtrUnlock(); } /* ----------------------------------------------------------------------------- - * Looking up + * Allocating stable pointers * -------------------------------------------------------------------------- */ StgStablePtr getStablePtr(StgPtr p) { - StgWord sp; - stablePtrLock(); - if (!stable_ptr_free) enlargeStablePtrTable(); - sp = stable_ptr_free - stable_ptr_table; - stable_ptr_free = (spEntry*)(stable_ptr_free->addr); - RELAXED_STORE(&stable_ptr_table[sp].addr, p); + + if (!stable_ptr_free) + enlargeStablePtrTable(); + + // find the index of free stable ptr + StgWord sp = stable_ptr_free - stable_ptr_table; + + // unlink the table entry we grabbed from the free list + stable_ptr_free = (spEntry*)(stable_ptr_free->addr); + + // release store to pair with acquire load in deRefStablePtr + RELEASE_STORE(&stable_ptr_table[sp].addr, p); + stablePtrUnlock(); + // see Note [NULL StgStablePtr] sp = sp + 1; return (StgStablePtr)(sp); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/913f106083431b555183f2ba84538c86bd0e8cc1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/913f106083431b555183f2ba84538c86bd0e8cc1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 16:56:43 2023 From: gitlab at gitlab.haskell.org (ase (@adamse)) Date: Thu, 13 Apr 2023 12:56:43 -0400 Subject: [Git][ghc/ghc][wip/adamse/stableptr-clarifications] rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <6438344bbcc1d_10a80d1f3e7a00384241@gitlab.mail> ase pushed to branch wip/adamse/stableptr-clarifications at Glasgow Haskell Compiler / GHC Commits: 9a7be9f6 by Adam Sandberg Ericsson at 2023-04-13T17:56:22+01:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - 1 changed file: - rts/StablePtr.c Changes: ===================================== rts/StablePtr.c ===================================== @@ -98,8 +98,13 @@ */ +// the global stable pointer entry table spEntry *stable_ptr_table = NULL; + +// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after static spEntry *stable_ptr_free = NULL; + +// current stable pointer table size static unsigned int SPT_size = 0; #define INIT_SPT_SIZE 64 @@ -117,6 +122,7 @@ static unsigned int SPT_size = 0; #error unknown SIZEOF_VOID_P #endif +// old stable pointer tables static spEntry *old_SPTs[MAX_N_OLD_SPTS]; static uint32_t n_old_SPTs = 0; @@ -149,8 +155,9 @@ stablePtrUnlock(void) * -------------------------------------------------------------------------- */ STATIC_INLINE void -initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free) +initSpEntryFreeList(spEntry *table, uint32_t n) { + spEntry* free = NULL; spEntry *p; for (p = table + n - 1; p >= table; p--) { p->addr = (P_)free; @@ -166,7 +173,7 @@ initStablePtrTable(void) SPT_size = INIT_SPT_SIZE; stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry), "initStablePtrTable"); - initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL); + initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE); #if defined(THREADED_RTS) initMutex(&stable_ptr_mutex); @@ -181,6 +188,8 @@ initStablePtrTable(void) static void enlargeStablePtrTable(void) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + uint32_t old_SPT_size = SPT_size; spEntry *new_stable_ptr_table; @@ -206,7 +215,8 @@ enlargeStablePtrTable(void) */ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table); - initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); + // add the new entries to the free list + initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size); } /* Note [Enlarging the stable pointer table] @@ -245,6 +255,7 @@ exitStablePtrTable(void) { if (stable_ptr_table) stgFree(stable_ptr_table); + stable_ptr_table = NULL; SPT_size = 0; @@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp) void freeStablePtrUnsafe(StgStablePtr sp) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + // see Note [NULL StgStablePtr] if (sp == NULL) { return; } + StgWord spw = (StgWord)sp - 1; + ASSERT(spw < SPT_size); + freeSpEntry(&stable_ptr_table[spw]); } @@ -278,25 +294,35 @@ void freeStablePtr(StgStablePtr sp) { stablePtrLock(); + freeStablePtrUnsafe(sp); + stablePtrUnlock(); } /* ----------------------------------------------------------------------------- - * Looking up + * Allocating stable pointers * -------------------------------------------------------------------------- */ StgStablePtr getStablePtr(StgPtr p) { - StgWord sp; - stablePtrLock(); - if (!stable_ptr_free) enlargeStablePtrTable(); - sp = stable_ptr_free - stable_ptr_table; - stable_ptr_free = (spEntry*)(stable_ptr_free->addr); - RELAXED_STORE(&stable_ptr_table[sp].addr, p); + + if (!stable_ptr_free) + enlargeStablePtrTable(); + + // find the index of free stable ptr + StgWord sp = stable_ptr_free - stable_ptr_table; + + // unlink the table entry we grabbed from the free list + stable_ptr_free = (spEntry*)(stable_ptr_free->addr); + + // release store to pair with acquire load in deRefStablePtr + RELEASE_STORE(&stable_ptr_table[sp].addr, p); + stablePtrUnlock(); + // see Note [NULL StgStablePtr] sp = sp + 1; return (StgStablePtr)(sp); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a7be9f6517ea5d3388358b2e3d232a36196caf3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9a7be9f6517ea5d3388358b2e3d232a36196caf3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 17:13:26 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Thu, 13 Apr 2023 13:13:26 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] 2 commits: hlint Message-ID: <643838363ffbb_10a80d1f91138c3950f4@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: c1f7dcf6 by Sven Tennie at 2023-04-10T13:54:09+00:00 hlint - - - - - 8328acac by Sven Tennie at 2023-04-13T17:13:06+00:00 Save - - - - - 10 changed files: - compiler/CodeGen.Platform.h - compiler/GHC/CmmToAsm/RISCV64.hs - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs - compiler/GHC/CmmToAsm/RISCV64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs - + compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs - compiler/ghc.cabal.in Changes: ===================================== compiler/CodeGen.Platform.h ===================================== @@ -1086,6 +1086,90 @@ freeReg REG_D6 = False freeReg _ = True +#elif defined(MACHREGS_riscv64) +freeReg 0 = False -- x0 / zero is always 0; not usable in general usage + +# if defined(REG_Base) +freeReg REG_Base = False +# endif +# if defined(REG_Sp) +freeReg REG_Sp = False +# endif +# if defined(REG_SpLim) +freeReg REG_SpLim = False +# endif +# if defined(REG_Hp) +freeReg REG_Hp = False +# endif +# if defined(REG_HpLim) +freeReg REG_HpLim = False +# endif + +# if defined(REG_R1) +freeReg REG_R1 = False +# endif +# if defined(REG_R2) +freeReg REG_R2 = False +# endif +# if defined(REG_R3) +freeReg REG_R3 = False +# endif +# if defined(REG_R4) +freeReg REG_R4 = False +# endif +# if defined(REG_R5) +freeReg REG_R5 = False +# endif +# if defined(REG_R6) +freeReg REG_R6 = False +# endif +# if defined(REG_R7) +freeReg REG_R7 = False +# endif +# if defined(REG_R8) +freeReg REG_R8 = False +# endif + +# if defined(REG_F1) +freeReg REG_F1 = False +# endif +# if defined(REG_F2) +freeReg REG_F2 = False +# endif +# if defined(REG_F3) +freeReg REG_F3 = False +# endif +# if defined(REG_F4) +freeReg REG_F4 = False +# endif +# if defined(REG_F5) +freeReg REG_F5 = False +# endif +# if defined(REG_F6) +freeReg REG_F6 = False +# endif + +# if defined(REG_D1) +freeReg REG_D1 = False +# endif +# if defined(REG_D2) +freeReg REG_D2 = False +# endif +# if defined(REG_D3) +freeReg REG_D3 = False +# endif +# if defined(REG_D4) +freeReg REG_D4 = False +# endif +# if defined(REG_D5) +freeReg REG_D5 = False +# endif +# if defined(REG_D6) +freeReg REG_D6 = False +# endif + +freeReg _ = True + #else freeReg = panic "freeReg not defined for this platform" ===================================== compiler/GHC/CmmToAsm/RISCV64.hs ===================================== @@ -18,6 +18,7 @@ import qualified GHC.CmmToAsm.RISCV64.Ppr as RISCV64 import qualified GHC.CmmToAsm.RISCV64.CodeGen as RISCV64 import qualified GHC.CmmToAsm.RISCV64.Regs as RISCV64 import qualified GHC.CmmToAsm.RISCV64.RegInfo as RISCV64 +import GHC.Utils.Outputable ncgRISCV64 :: Bool -> NCGConfig -> NcgImpl RawCmmStatics RISCV64.Instr RISCV64.JumpDest ncgRISCV64 no_empty_asm config = NcgImpl @@ -28,15 +29,18 @@ ncgRISCV64 no_empty_asm config = NcgImpl , canShortcut = RISCV64.canShortcut , shortcutStatics = RISCV64.shortcutStatics , shortcutJump = RISCV64.shortcutJump - , pprNatCmmDeclH = RISCV64.pprNatCmmDeclH + , pprNatCmmDeclH = RISCV64.pprNatCmmDecl , pprNatCmmDeclS = RISCV64.pprNatCmmDeclS - , maxSpillSlots = RISCV64.maxSpillSlots - , allocatableRegs = RISCV64.allocatableRegs + , maxSpillSlots = RISCV64.maxSpillSlots config + , allocatableRegs = RISCV64.allocatableRegs platform , ncgAllocMoreStack = RISCV64.allocMoreStack - , ncgMakeFarBranches = RISCV64.makeFarBranches + , ncgMakeFarBranches = const id , extractUnwindPoints = const [] , invertCondBranches = \_ _ -> id } + where + platform = ncgPlatform config + -- | Instruction instance for RISC-V 64bit instance Instruction RISCV64.Instr where @@ -55,4 +59,4 @@ instance Instruction RISCV64.Instr where mkStackAllocInstr = RISCV64.mkStackAllocInstr mkStackDeallocInstr = RISCV64.mkStackDeallocInstr pprInstr = RISCV64.pprInstr - mkComment = pure . RISCV64.COMMENT + mkComment = pure . RISCV64.COMMENT . ftext ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -11,10 +11,17 @@ import Control.Monad import GHC.Cmm.Dataflow.Block import GHC.Data.OrdList import GHC.Cmm.Dataflow -import GHC.Driver.Ppr (showPprUnsafe) +import GHC.Driver.Ppr ( showPprUnsafe, showSDocUnsafe ) import GHC.Plugins (Outputable) -import GHC.Driver.Ppr (showSDocUnsafe) import GHC.Utils.Outputable +import GHC.Platform +import GHC.CmmToAsm.Config +import GHC.Platform.Reg +import GHC.CmmToAsm.Format +import GHC.CmmToAsm.RISCV64.Regs +import GHC.Platform.Regs +import GHC.Utils.Panic +import GHC.Cmm.BlockId -- | Don't try to compile all GHC Cmm files in the beginning. -- Ignore them. There's a flag to decide we really want to emit something. @@ -60,9 +67,24 @@ basicBlockCodeGen block = do = (instr:instrs, blocks, statics) return (BasicBlock id top : other_blocks, statics) +-------------------------------------------------------------------------------- +-- | 'InstrBlock's are the insn sequences generated by the insn selectors. +-- They are really trees of insns to facilitate fast appending, where a +-- left-to-right traversal yields the insns in the correct order. +-- type InstrBlock = OrdList Instr +-- | Register's passed up the tree. If the stix code forces the register +-- to live in a pre-decided machine register, it comes out as @Fixed@; +-- otherwise, it comes out as @Any@, and the parent can decide which +-- register to put it in. +-- +data Register + = Fixed Format Reg InstrBlock + | Any Format (Reg -> InstrBlock) + + stmtsToInstrs :: [CmmNode e x] -> NatM InstrBlock stmtsToInstrs stmts = do instrss <- mapM stmtToInstrs stmts @@ -72,9 +94,102 @@ stmtToInstrs :: CmmNode e x -> NatM InstrBlock stmtToInstrs stmt = do platform <- getPlatform case stmt of - CmmComment s -> return (unitOL (COMMENT s)) - a -> error $ "TODO: stmtToInstrs" ++ (showSDocUnsafe . pdoc platform) a + CmmComment s -> return (unitOL (COMMENT (ftext s))) + -- TODO: Maybe, it would be nice to see the tick comment in assembly? + CmmTick {} -> return nilOL + CmmAssign reg src + | isFloatType ty -> assignReg_FltCode format reg src + | otherwise -> assignReg_IntCode format reg src + where ty = cmmRegType reg + format = cmmTypeFormat ty + CmmBranch id -> genBranch id + a -> error $ "TODO: stmtToInstrs " ++ (showSDocUnsafe . pdoc platform) a + +assignReg_FltCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock +assignReg_FltCode _ _ _ = error "TODO: assignReg_FltCode" + +-- TODO: Format parameter unused +assignReg_IntCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock +assignReg_IntCode _ reg src + = do + platform <- getPlatform + let dst = getRegisterReg platform reg + r <- getRegister src + return $ case r of + Any _ code -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL` code dst + Fixed format freg fcode -> error "TODO: assignReg_IntCode - Fixed" + +-- | Grab the Reg for a CmmReg +getRegisterReg :: Platform -> CmmReg -> Reg +getRegisterReg _ (CmmLocal (LocalReg u pk)) + = RegVirtual $ mkVirtualReg u (cmmTypeFormat pk) +getRegisterReg platform (CmmGlobal reg@(GlobalRegUse mid _)) + = case globalRegMaybe platform mid of + Just reg -> RegReal reg + Nothing -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal reg) + +getRegister :: CmmExpr -> NatM Register +getRegister e = do + config <- getConfig + getRegister' config (ncgPlatform config) e + +getRegister' :: NCGConfig -> Platform -> CmmExpr -> NatM Register + -- Generic case. +getRegister' config plat expr + = case expr of + CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)) + -> pprPanic "getRegisterReg-memory" (ppr $ PicBaseReg) + CmmLit lit + -> case lit of + CmmInt i W64 -> do + return (Any (intFormat W64) (\dst -> unitOL $ annExpr expr (LI dst i))) + CmmInt i w -> error ("TODO: getRegister' CmmInt " ++ show i ++ show w ++ " " ++show expr) + e -> error ("TODO: getRegister' other " ++ show e) + e -> error ("TODO: getRegister'" ++ show e) + +-- ----------------------------------------------------------------------------- +-- Unconditional branches +genBranch :: BlockId -> NatM InstrBlock +genBranch = return . toOL . mkJumpInstr + + +-- ----------------------------------------------------------------------------- +-- | Utilities +ann :: SDoc -> Instr -> Instr +ann doc instr {- debugIsOn -} = ANN doc instr +-- ann _ instr = instr +{-# INLINE ann #-} + +-- Using pprExpr will hide the AST, @ANN@ will end up in the assembly with +-- -dppr-debug. The idea is that we can trivially see how a cmm expression +-- ended up producing the assembly we see. By having the verbatim AST printed +-- we can simply check the patterns that were matched to arrive at the assembly +-- we generated. +-- +-- pprExpr will hide a lot of noise of the underlying data structure and print +-- the expression into something that can be easily read by a human. However +-- going back to the exact CmmExpr representation can be laborious and adds +-- indirections to find the matches that lead to the assembly. +-- +-- An improvement oculd be to have +-- +-- (pprExpr genericPlatform e) <> parens (text. show e) +-- +-- to have the best of both worlds. +-- +-- Note: debugIsOn is too restrictive, it only works for debug compilers. +-- However, we do not only want to inspect this for debug compilers. Ideally +-- we'd have a check for -dppr-debug here already, such that we don't even +-- generate the ANN expressions. However, as they are lazy, they shouldn't be +-- forced until we actually force them, and without -dppr-debug they should +-- never end up being forced. +annExpr :: CmmExpr -> Instr -> Instr +annExpr e instr {- debugIsOn -} = ANN (text . show $ e) instr +-- annExpr e instr {- debugIsOn -} = ANN (pprExpr genericPlatform e) instr +-- annExpr _ instr = instr +{-# INLINE annExpr #-} +-- TODO: Consider using jump tables generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) -generateJumpTableForInstr _ = error "TODO: generateJumpTableForInstr" +generateJumpTableForInstr _ = Nothing ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -1,45 +1,73 @@ +{-# LANGUAGE EmptyCase #-} module GHC.CmmToAsm.RISCV64.Instr where -import GHC.Data.FastString -import GHC.CmmToAsm.Types + +import GHC.Cmm import GHC.Cmm.BlockId -import GHC.Types.Unique.Supply import GHC.Cmm.Dataflow.Label -import Prelude +import GHC.CmmToAsm.Config +import GHC.CmmToAsm.Instr hiding (patchRegsOfInstr, takeDeltaInstr, regUsageOfInstr, isMetaInstr, jumpDestsOfInstr) +import GHC.CmmToAsm.Types +import GHC.Data.FastString import GHC.Platform -import GHC.Utils.Outputable import GHC.Platform.Reg -import GHC.CmmToAsm.Config -import GHC.CmmToAsm.Instr -import GHC.Cmm +import GHC.Types.Unique.Supply +import GHC.Utils.Outputable +import Prelude +import GHC.Platform.Regs (freeReg) data Instr - -- comment pseudo-op - = COMMENT FastString - -- some static data spat out during code + = -- comment pseudo-op + COMMENT SDoc + | MULTILINE_COMMENT SDoc + | -- Annotated instruction. Should print # + ANN SDoc Instr + -- specify current stack offset for + -- benefit of subsequent passes + | DELTA Int + + | -- some static data spat out during code -- generation. Will be extracted before -- pretty-printing. - | LDATA Section RawCmmStatics - - -- start a new basic block. Useful during + LDATA Section RawCmmStatics + | -- start a new basic block. Useful during -- codegen, removed later. Preceding -- instruction should be a jump, as per the -- invariants for a BasicBlock (see Cmm). - | NEWBLOCK BlockId + NEWBLOCK BlockId + | -- load immediate pseudo-instruction + LI Reg Integer + | -- jump pseudo-instruction + J BlockId +instance Outputable Instr where + ppr instr = text "TODO: Outputable Instr ppr" allocMoreStack :: - Int - -> NatCmmDecl statics GHC.CmmToAsm.RISCV64.Instr.Instr - -> UniqSM (NatCmmDecl statics GHC.CmmToAsm.RISCV64.Instr.Instr, [(BlockId,BlockId)]) + Int -> + NatCmmDecl statics GHC.CmmToAsm.RISCV64.Instr.Instr -> + UniqSM (NatCmmDecl statics GHC.CmmToAsm.RISCV64.Instr.Instr, [(BlockId, BlockId)]) allocMoreStack = error "TODO: allocMoreStack" -maxSpillSlots :: Int -maxSpillSlots = error "TODO: maxSpillSlots" +-- saved return address + previous fp +-- (https://pdos.csail.mit.edu/6.S081/2020/lec/l-riscv.txt) +stackFrameHeaderSize :: Int +stackFrameHeaderSize = 2 * spillSlotSize -makeFarBranches - :: LabelMap RawCmmStatics - -> [NatBasicBlock Instr] - -> [NatBasicBlock Instr] +-- | All registers are 8 byte wide. +spillSlotSize :: Int +spillSlotSize = 8 + +-- | The number of spill slots available without allocating more. +maxSpillSlots :: NCGConfig -> Int +maxSpillSlots config +-- = 0 -- set to zero, to see when allocMoreStack has to fire. + = ((ncgSpillPreallocSize config - stackFrameHeaderSize) + `div` spillSlotSize) - 1 + +makeFarBranches :: + LabelMap RawCmmStatics -> + [NatBasicBlock Instr] -> + [NatBasicBlock Instr] makeFarBranches _ _ = error "TODO: makeFarBranches" -- | Get the registers that are being used by this instruction. @@ -47,66 +75,115 @@ makeFarBranches _ _ = error "TODO: makeFarBranches" -- Just state precisely the regs read and written by that insn. -- The consequences of control flow transfers, as far as register -- allocation goes, are taken care of by the register allocator. --- -regUsageOfInstr - :: Platform - -> instr - -> RegUsage -regUsageOfInstr _ _ = error "TODO: regUsageOfInstr" +regUsageOfInstr :: + Platform -> + Instr -> + RegUsage +regUsageOfInstr platform instr = case instr of + ANN _ i -> regUsageOfInstr platform i + COMMENT{} -> usage ([], []) + MULTILINE_COMMENT{} -> usage ([], []) + LDATA{} -> usage ([], []) + DELTA{} -> usage ([], []) + NEWBLOCK{} -> usage ([], []) + LI reg _ -> usage ([], [reg]) + -- Looks like J doesn't change registers (beside PC) + -- This might be wrong. + J{} -> usage ([], []) + where + -- filtering the usage is necessary, otherwise the register + -- allocator will try to allocate pre-defined fixed stg + -- registers as well, as they show up. + usage (src, dst) = RU (filter (interesting platform) src) + (filter (interesting platform) dst) + + interesting :: Platform -> Reg -> Bool + interesting _ (RegVirtual _) = True + interesting platform (RegReal (RealRegSingle i)) = freeReg platform i + -- | Apply a given mapping to all the register references in this -- instruction. -patchRegsOfInstr - :: instr - -> (Reg -> Reg) - -> instr -patchRegsOfInstr _ _ = error "TODO: patchRegsOfInstr" +patchRegsOfInstr :: + Instr -> + (Reg -> Reg) -> + Instr +patchRegsOfInstr instr env = case instr of + ANN _ i -> patchRegsOfInstr i env + COMMENT{} -> instr + MULTILINE_COMMENT{} -> instr + LDATA{} -> instr + DELTA{} -> instr + NEWBLOCK{} -> instr + LI reg i -> LI (env reg) i + -- Looks like J doesn't change registers (beside PC) + -- This might be wrong. + J{} -> instr + -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the -- register allocator needs to worry about. -isJumpishInstr - :: instr -> Bool -isJumpishInstr _ = error "TODO: isJumpishInstr" +isJumpishInstr :: Instr -> Bool +isJumpishInstr COMMENT {} = False +isJumpishInstr MULTILINE_COMMENT {} = False +isJumpishInstr ANN {} = False +isJumpishInstr DELTA {} = False +isJumpishInstr LDATA {} = False +isJumpishInstr NEWBLOCK {} = False +isJumpishInstr LI {} = False +isJumpishInstr J {} = True --- | Give the possible destinations of this jump instruction. --- Must be defined for all jumpish instructions. -jumpDestsOfInstr - :: instr -> [BlockId] -jumpDestsOfInstr _ = error "TODO: jumpDestsOfInstr" + +-- | Checks whether this instruction is a jump/branch instruction. +-- One that can change the flow of control in a way that the +-- register allocator needs to worry about. +jumpDestsOfInstr :: Instr -> [BlockId] +jumpDestsOfInstr (ANN _ i) = jumpDestsOfInstr i +jumpDestsOfInstr (J t) = [t] +jumpDestsOfInstr _ = [] -- | Change the destination of this jump instruction. -- Used in the linear allocator when adding fixup blocks for join -- points. -patchJumpInstr - :: instr - -> (BlockId -> BlockId) - -> instr +patchJumpInstr :: + instr -> + (BlockId -> BlockId) -> + instr patchJumpInstr _ _ = error "TODO: patchJumpInstr" -- | An instruction to spill a register into a spill slot. -mkSpillInstr - :: NCGConfig - -> Reg -- ^ the reg to spill - -> Int -- ^ the current stack delta - -> Int -- ^ spill slot to use - -> [instr] -- ^ instructions +mkSpillInstr :: + NCGConfig -> + -- | the reg to spill + Reg -> + -- | the current stack delta + Int -> + -- | spill slot to use + Int -> + -- | instructions + [instr] mkSpillInstr _ _ _ _ = error "TODO: mkSpillInstr" -- | An instruction to reload a register from a spill slot. -mkLoadInstr - :: NCGConfig - -> Reg -- ^ the reg to reload. - -> Int -- ^ the current stack delta - -> Int -- ^ the spill slot to use - -> [instr] -- ^ instructions +mkLoadInstr :: + NCGConfig -> + -- | the reg to reload. + Reg -> + -- | the current stack delta + Int -> + -- | the spill slot to use + Int -> + -- | instructions + [instr] mkLoadInstr _ _ _ _ = error "TODO: mkLoadInstr" -- | See if this instruction is telling us the current C stack delta -takeDeltaInstr - :: instr - -> Maybe Int -takeDeltaInstr _ = error "TODO: takeDeltaInstr" +takeDeltaInstr :: Instr -> Maybe Int +takeDeltaInstr (ANN _ i) = takeDeltaInstr i +takeDeltaInstr (DELTA i) = Just i +takeDeltaInstr _ = Nothing + -- | Check whether this instruction is some meta thing inserted into -- the instruction stream for other purposes. @@ -115,50 +192,63 @@ takeDeltaInstr _ = error "TODO: takeDeltaInstr" -- and have its registers allocated. -- -- eg, comments, delta, ldata, etc. -isMetaInstr - :: instr - -> Bool -isMetaInstr _ = error "TODO: isMetaInstr" +isMetaInstr :: Instr -> Bool +isMetaInstr instr + = case instr of + ANN _ i -> isMetaInstr i + COMMENT{} -> True + MULTILINE_COMMENT{} -> True + LDATA{} -> True + NEWBLOCK{} -> True + LI{} -> False + J{} -> False -- | Copy the value in a register to another one. -- Must work for all register classes. -mkRegRegMoveInstr - :: Platform - -> Reg -- ^ source register - -> Reg -- ^ destination register - -> instr +mkRegRegMoveInstr :: + Platform -> + -- | source register + Reg -> + -- | destination register + Reg -> + instr mkRegRegMoveInstr _ _ _ = error "TODO: mkRegRegMoveInstr" -- | Take the source and destination from this reg -> reg move instruction -- or Nothing if it's not one -takeRegRegMoveInstr - :: instr - -> Maybe (Reg, Reg) -takeRegRegMoveInstr _ = error "TODO: takeRegRegMoveInstr" +takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg) +takeRegRegMoveInstr COMMENT {} = Nothing +takeRegRegMoveInstr MULTILINE_COMMENT {} = Nothing +takeRegRegMoveInstr ANN {} = Nothing +takeRegRegMoveInstr DELTA {} = Nothing +takeRegRegMoveInstr LDATA {} = Nothing +takeRegRegMoveInstr NEWBLOCK {} = Nothing +takeRegRegMoveInstr LI {} = Nothing +takeRegRegMoveInstr J {} = Nothing -- | Make an unconditional jump instruction. -- For architectures with branch delay slots, its ok to put -- a NOP after the jump. Don't fill the delay slot with an -- instruction that references regs or you'll confuse the -- linear allocator. -mkJumpInstr - :: BlockId - -> [instr] -mkJumpInstr _ = error "TODO: mkJumpInstr" +mkJumpInstr :: + BlockId -> + [Instr] +mkJumpInstr id = [J id] -- Subtract an amount from the C stack pointer -mkStackAllocInstr - :: Platform - -> Int - -> [instr] +mkStackAllocInstr :: + Platform -> + Int -> + [instr] mkStackAllocInstr _ _ = error "TODO: mkStackAllocInstr" -- Add an amount to the C stack pointer -mkStackDeallocInstr - :: Platform - -> Int - -> [instr] +mkStackDeallocInstr :: + Platform -> + Int -> + [instr] mkStackDeallocInstr _ _ = error "TODO: mkStackDeallocInstr" -- | Pretty-print an instruction ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -1,11 +1,137 @@ +{-# OPTIONS_GHC -Wno-unused-matches #-} + module GHC.CmmToAsm.RISCV64.Ppr where -import GHC.Utils.Outputable + +import GHC.Cmm hiding (topInfoTable) +import GHC.Cmm.BlockId +import GHC.Cmm.CLabel +import GHC.Cmm.Dataflow.Collections +import GHC.Cmm.Dataflow.Label +import GHC.CmmToAsm.Config +import GHC.CmmToAsm.Ppr +import GHC.CmmToAsm.RISCV64.Instr hiding (pprInstr) import GHC.CmmToAsm.Types -import GHC.CmmToAsm.RISCV64.Instr -import Prelude +import GHC.Platform +import GHC.Types.Basic +import GHC.Utils.Outputable +import Prelude hiding ((<>)) +import GHC.CmmToAsm.Utils + +pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc +pprNatCmmDecl _ cmmData@(CmmData _ _) = error $ "TODO: pprNatCmmDecl : " ++ showPprUnsafe cmmData +pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = + let platform = ncgPlatform config + in pprProcAlignment config + $$ case topInfoTable proc of + Nothing -> + -- special case for code without info table: + pprSectionAlign config (Section Text lbl) + $$ + -- do not + -- pprProcAlignment config $$ + pprLabel platform lbl + $$ vcat (map (pprBasicBlock config top_info) blocks) -- blocks guaranteed not null, so label needed + $$ + -- TODO: Is this call to pprSizeDecl needed? (Doc states this .size is only for source compatibility.) + pprSizeDecl platform lbl + Just cmmStaticsRaw@(CmmStaticsRaw info_lbl _) -> error $ "TODO: pprNatCmmDecl : " ++ show cmmStaticsRaw + +pprProcAlignment :: IsDoc doc => NCGConfig -> doc +pprProcAlignment config = maybe empty (pprAlign platform . mkAlignment) (ncgProcAlignment config) + where + platform = ncgPlatform config + +pprAlign :: IsDoc doc => Platform -> Alignment -> doc +pprAlign _platform alignment = + line $ text "\t.balign " <> int (alignmentBytes alignment) + +pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc +pprSectionAlign _config (Section (OtherSection _) _) = + error "AArch64.Ppr.pprSectionAlign: unknown section" +pprSectionAlign config sec@(Section seg _) = + line (pprSectionHeader config sec) + $$ pprAlignForSection (ncgPlatform config) seg + +-- | Print appropriate alignment for the given section type. +pprAlignForSection :: IsDoc doc => Platform -> SectionType -> doc +pprAlignForSection _platform _seg = + -- .balign is stable, whereas .align is platform dependent. + line (text "\t.balign 8") -- always 8 + +pprLabel :: IsDoc doc => Platform -> CLabel -> doc +pprLabel platform lbl = + pprGloblDecl platform lbl + $$ pprTypeDecl platform lbl + $$ line (pprAsmLabel platform lbl <> char ':') + +pprGloblDecl :: IsDoc doc => Platform -> CLabel -> doc +pprGloblDecl platform lbl + | not (externallyVisibleCLabel lbl) = empty + | otherwise = line (text "\t.globl " <> pprAsmLabel platform lbl) + +pprLabelType' :: IsLine doc => Platform -> CLabel -> doc +pprLabelType' platform lbl = + if isCFunctionLabel lbl || functionOkInfoTable + then text "@function" + else text "@object" + where + functionOkInfoTable = + platformTablesNextToCode platform + && isInfoTableLabel lbl + && not (isCmmInfoTableLabel lbl) + && not (isConInfoTableLabel lbl) + +-- this is called pprTypeAndSizeDecl in PPC.Ppr +pprTypeDecl :: IsDoc doc => Platform -> CLabel -> doc +pprTypeDecl platform lbl = + if osElfTarget (platformOS platform) && externallyVisibleCLabel lbl + then line (text ".type " <> pprAsmLabel platform lbl <> text ", " <> pprLabelType' platform lbl) + else empty + +-- | Output the ELF .size directive. +pprSizeDecl :: IsDoc doc => Platform -> CLabel -> doc +pprSizeDecl platform lbl = + if osElfTarget (platformOS platform) + then line (text "\t.size" <+> pprAsmLabel platform lbl <> text ", .-" <> pprAsmLabel platform lbl) + else empty + +pprBasicBlock :: + IsDoc doc => + NCGConfig -> + LabelMap RawCmmStatics -> + NatBasicBlock Instr -> + doc +pprBasicBlock config info_env (BasicBlock blockid instrs) = + maybe_infotable $ + pprLabel platform asmLbl + $$ vcat (map (pprInstr platform) instrs) + where + asmLbl = blockLbl blockid + platform = ncgPlatform config + maybe_infotable c = case mapLookup blockid info_env of + Nothing -> c + Just cmm@(CmmStaticsRaw info_lbl info) -> error $ "pprBasicBlock " ++ showPprUnsafe cmm + +pprInstr :: IsDoc doc => Platform -> Instr -> doc +pprInstr platform instr = case instr of + -- Meta Instructions --------------------------------------------------------- + -- see Note [dualLine and dualDoc] in GHC.Utils.Outputable + COMMENT s -> dualDoc (asmComment s) empty + MULTILINE_COMMENT s -> dualDoc (asmMultilineComment s) empty + ANN d i -> dualDoc (pprInstr platform i <+> asmDoubleslashComment d) (pprInstr platform i) + DELTA d -> dualDoc (asmComment $ text "\tdelta = " <> int d) empty + -- see Note [dualLine and dualDoc] in GHC.Utils.Outputable + NEWBLOCK _ -> error "pprInstr: NEWBLOCK" + LDATA _ _ -> error "pprInstr: LDATA" + J t -> error "pprInstr: LDATA" + LI reg i -> error "pprInstr: LDATA" + +-- aarch64 GNU as uses // for comments. +asmComment :: SDoc -> SDoc +asmComment c = whenPprDebug $ text "#" <+> c -pprNatCmmDeclH :: IsDoc doc => NatCmmDecl RawCmmStatics Instr -> doc -pprNatCmmDeclH _ = error "TODO: pprNatCmmDeclH" +asmDoubleslashComment :: SDoc -> SDoc +asmDoubleslashComment c = whenPprDebug $ text "//" <+> c -pprNatCmmDeclS :: IsDoc doc => NatCmmDecl RawCmmStatics Instr -> doc -pprNatCmmDeclS _ = error "TODO: pprNatCmmDeclS" +asmMultilineComment :: SDoc -> SDoc +asmMultilineComment c = whenPprDebug $ text "/*" $+$ c $+$ text "*/" ===================================== compiler/GHC/CmmToAsm/RISCV64/Regs.hs ===================================== @@ -1,6 +1,28 @@ module GHC.CmmToAsm.RISCV64.Regs where import GHC.Platform.Reg import Prelude +import GHC.CmmToAsm.Format +import GHC.Utils.Panic +import GHC.Types.Unique +import GHC.Platform +import GHC.Platform.Regs -allocatableRegs :: [RealReg] -allocatableRegs = error "TODO: allocatableRegs" +allMachRegNos :: [RegNo] +allMachRegNos = [1..31] ++ [32..63] + +-- allocatableRegs is allMachRegNos with the fixed-use regs removed. +-- i.e., these are the regs for which we are prepared to allow the +-- register allocator to attempt to map VRegs to. +allocatableRegs :: Platform -> [RealReg] +allocatableRegs platform + = let isFree i = freeReg platform i + in map RealRegSingle $ filter isFree allMachRegNos + +mkVirtualReg :: Unique -> Format -> VirtualReg +mkVirtualReg u format + | not (isFloatFormat format) = VirtualRegI u + | otherwise + = case format of + FF32 -> VirtualRegD u + FF64 -> VirtualRegD u + _ -> panic "RISCV64.mkVirtualReg" ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -114,6 +114,7 @@ import qualified GHC.CmmToAsm.Reg.Linear.PPC as PPC import qualified GHC.CmmToAsm.Reg.Linear.X86 as X86 import qualified GHC.CmmToAsm.Reg.Linear.X86_64 as X86_64 import qualified GHC.CmmToAsm.Reg.Linear.AArch64 as AArch64 +import qualified GHC.CmmToAsm.Reg.Linear.RISCV64 as RISCV64 import GHC.CmmToAsm.Reg.Target import GHC.CmmToAsm.Reg.Liveness import GHC.CmmToAsm.Reg.Utils @@ -223,7 +224,7 @@ linearRegAlloc config entry_ids block_live sccs ArchAlpha -> panic "linearRegAlloc ArchAlpha" ArchMipseb -> panic "linearRegAlloc ArchMipseb" ArchMipsel -> panic "linearRegAlloc ArchMipsel" - ArchRISCV64 -> panic "linearRegAlloc ArchRISCV64" + ArchRISCV64 -> go $ (frInitFreeRegs platform :: RISCV64.FreeRegs) ArchLoongArch64-> panic "linearRegAlloc ArchLoongArch64" ArchJavaScript -> panic "linearRegAlloc ArchJavaScript" ArchWasm32 -> panic "linearRegAlloc ArchWasm32" ===================================== compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs ===================================== @@ -29,10 +29,12 @@ import qualified GHC.CmmToAsm.Reg.Linear.PPC as PPC import qualified GHC.CmmToAsm.Reg.Linear.X86 as X86 import qualified GHC.CmmToAsm.Reg.Linear.X86_64 as X86_64 import qualified GHC.CmmToAsm.Reg.Linear.AArch64 as AArch64 +import qualified GHC.CmmToAsm.Reg.Linear.RISCV64 as RISCV64 import qualified GHC.CmmToAsm.PPC.Instr as PPC.Instr import qualified GHC.CmmToAsm.X86.Instr as X86.Instr import qualified GHC.CmmToAsm.AArch64.Instr as AArch64.Instr +import qualified GHC.CmmToAsm.RISCV64.Instr as RISCV64.Instr class Show freeRegs => FR freeRegs where frAllocateReg :: Platform -> RealReg -> freeRegs -> freeRegs @@ -64,6 +66,13 @@ instance FR AArch64.FreeRegs where frInitFreeRegs = AArch64.initFreeRegs frReleaseReg = \_ -> AArch64.releaseReg +instance FR RISCV64.FreeRegs where + frAllocateReg = \_ -> RISCV64.allocateReg + frGetFreeRegs = \_ -> RISCV64.getFreeRegs + frInitFreeRegs = RISCV64.initFreeRegs + frReleaseReg = \_ -> RISCV64.releaseReg + + maxSpillSlots :: NCGConfig -> Int maxSpillSlots config = case platformArch (ncgPlatform config) of ArchX86 -> X86.Instr.maxSpillSlots config @@ -76,7 +85,7 @@ maxSpillSlots config = case platformArch (ncgPlatform config) of ArchAlpha -> panic "maxSpillSlots ArchAlpha" ArchMipseb -> panic "maxSpillSlots ArchMipseb" ArchMipsel -> panic "maxSpillSlots ArchMipsel" - ArchRISCV64 -> panic "maxSpillSlots ArchRISCV64" + ArchRISCV64 -> RISCV64.Instr.maxSpillSlots config ArchLoongArch64->panic "maxSpillSlots ArchLoongArch64" ArchJavaScript-> panic "maxSpillSlots ArchJavaScript" ArchWasm32 -> panic "maxSpillSlots ArchWasm32" ===================================== compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs ===================================== @@ -0,0 +1,69 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + +-- | Free regs map for RISC-V 64bit +module GHC.CmmToAsm.Reg.Linear.RISCV64 where + +import GHC.Prelude + +import GHC.CmmToAsm.RISCV64.Regs +import GHC.Platform.Reg.Class +import GHC.Platform.Reg + +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Platform + +import Data.Word + +import GHC.Stack + +-- TODO: Register selection can likely be smart. Re-check this. (I'm not even sure this is correct.) +data FreeRegs = FreeRegs !Word32 !Word32 + +instance Show FreeRegs where + show (FreeRegs g f) = "FreeRegs: " ++ showBits g ++ "; " ++ showBits f + +instance Outputable FreeRegs where + ppr (FreeRegs g f) = text " " <+> foldr (\i x -> pad_int i <+> x) (text "") [0..31] + $$ text "GPR" <+> foldr (\i x -> show_bit g i <+> x) (text "") [0..31] + $$ text "FPR" <+> foldr (\i x -> show_bit f i <+> x) (text "") [0..31] + where pad_int i | i < 10 = char ' ' <> int i + pad_int i = int i + -- remember bit = 1 means it's available. + show_bit bits bit | testBit bits bit = text " " + show_bit _ _ = text " x" + +noFreeRegs :: FreeRegs +noFreeRegs = FreeRegs 0 0 + +showBits :: Word32 -> String +showBits w = map (\i -> if testBit w i then '1' else '0') [0..31] + +-- FR instance implementation (See Linear.FreeRegs) +allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +allocateReg (RealRegSingle r) (FreeRegs g f) + | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32)) + | r < 32 && testBit g r = FreeRegs (clearBit g r) f + | r > 31 = panic $ "Linear.RISCV64.allocReg: double allocation of float reg v" ++ show (r - 32) ++ "; " ++ showBits f + | otherwise = pprPanic "Linear.RISCV64.allocReg" $ text ("double allocation of gp reg x" ++ show r ++ "; " ++ showBits g) + +getFreeRegs :: RegClass -> FreeRegs -> [RealReg] +getFreeRegs cls (FreeRegs g f) + -- TODO: how to handle small floats? + | RcFloat <- cls = [] -- For now we only support double and integer registers, floats will need to be promoted. + | RcDouble <- cls = go 32 f 31 + | RcInteger <- cls = go 1 g 30 + where + go _ _ i | i < 0 = [] + go off x i | testBit x i = RealRegSingle (off + i) : (go off x $! i - 1) + | otherwise = go off x $! i - 1 + +initFreeRegs :: Platform -> FreeRegs +initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs platform) + +releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs +releaseReg (RealRegSingle r) (FreeRegs g f) + | r > 31 && testBit f (r - 32) = pprPanic "Linear.RISCV64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32)) + | r < 32 && testBit g r = pprPanic "Linear.RISCV64.releaseReg" (text "can't release non-allocated reg x" <> int r) + | r > 31 = FreeRegs g (setBit f (r - 32)) + | otherwise = FreeRegs (setBit g r) f ===================================== compiler/ghc.cabal.in ===================================== @@ -253,6 +253,7 @@ Library GHC.CmmToAsm.Reg.Linear.FreeRegs GHC.CmmToAsm.Reg.Linear.JoinToTargets GHC.CmmToAsm.Reg.Linear.PPC + GHC.CmmToAsm.Reg.Linear.RISCV64 GHC.CmmToAsm.Reg.Linear.StackMap GHC.CmmToAsm.Reg.Linear.State GHC.CmmToAsm.Reg.Linear.Stats View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1df55c28d4fbbf3139621aca638dc7453035491b...8328acac55b046f522531208c8b3cf9068d3069a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1df55c28d4fbbf3139621aca638dc7453035491b...8328acac55b046f522531208c8b3cf9068d3069a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 18:48:00 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 13 Apr 2023 14:48:00 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 65 commits: Bump submodules: text, parsec, bytestring, containers Message-ID: <64384e60ca1e6_10a80d212b3c404108ad@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: eff3d206 by Zubin Duggal at 2023-04-14T00:17:34+05:30 Bump submodules: text, parsec, bytestring, containers - - - - - ac8f1697 by Zubin Duggal at 2023-04-14T00:17:34+05:30 Bump base to 4.17.1.0 and add release notes - - - - - c5d09f33 by Zubin Duggal at 2023-04-14T00:17:34+05:30 Allow LLVM 14 - - - - - 26f2bec5 by Ben Gamari at 2023-04-14T00:17:35+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - 13e14be6 by Ben Gamari at 2023-04-14T00:17:35+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 96862cc2 by Ben Gamari at 2023-04-14T00:17:35+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - 146892bd by Ben Gamari at 2023-04-14T00:17:35+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - e2eb8d82 by Ben Gamari at 2023-04-14T00:17:35+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - 9e1f111c by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - deba0aa8 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - ab5ee88d by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - 1c371946 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - 1a13f4da by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - 97523a9b by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 416d6ff7 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - 05bc513c by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - c0737604 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - 783b6988 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - 43f0f714 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - 963bc047 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - 9a4c9968 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - 48c69a2f by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - 8b1baec4 by Ben Gamari at 2023-04-14T00:17:35+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - 3949a572 by Ben Gamari at 2023-04-14T00:17:35+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - 41c51e1a by Ben Gamari at 2023-04-14T00:17:36+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - 91c7537d by Ben Gamari at 2023-04-14T00:17:36+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - b5396b12 by Ben Gamari at 2023-04-14T00:17:36+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - a6289921 by Ben Gamari at 2023-04-14T00:17:36+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - 147f35f8 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - 90a25e71 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - 826084b3 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - de816a96 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - 4c33058c by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - 52ba9bb9 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - 1fb40ddb by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - 2c31b8ce by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 2b528ff0 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - fc86a99c by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - 9e875e18 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - 3d27987a by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - f45a20c6 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - c73fabb4 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - af8bfb33 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - bee528c5 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - bd35b0a3 by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - 8b0ba85b by Ben Gamari at 2023-04-14T00:17:36+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - aba51a5a by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - 9a423a4a by Ben Gamari at 2023-04-14T00:17:37+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - 6be4dc1d by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - cbeb4db1 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - c01c5092 by Ben Gamari at 2023-04-14T00:17:37+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - c8756aff by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - 9a7e286c by Ben Gamari at 2023-04-14T00:17:37+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - 22b8f1c4 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - 18c7c7d4 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - 37766167 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - 7dbd4385 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - c2d74f30 by Ben Gamari at 2023-04-14T00:17:37+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - 0b63d8a8 by Ben Gamari at 2023-04-14T00:17:37+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - 2d8ba4d9 by Ben Gamari at 2023-04-14T00:17:37+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - 0361c519 by Ben Gamari at 2023-04-14T00:17:37+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 7d37aa31 by Ben Gamari at 2023-04-14T00:17:37+05:30 contextswitch - - - - - e416505f by Ben Gamari at 2023-04-14T00:17:37+05:30 rts: Fix incorrect format specifier warnings - - - - - 004fec88 by Zubin Duggal at 2023-04-14T00:17:37+05:30 compiler: Fix performance regression in backport of "Make FloatIn robust to shadowing" (6206cb9287f3f6e70c669660a646a65274870d2b) In 9.4, we have noFloatIntoArg :: CoreExprWithFVs' -> Type -> Bool noFloatIntoArg expr expr_ty = ... But in master when 6206cb92 landed, after "Drop the app invariant" (dcf30da8) we had noFloatIntoArg :: CoreExprWithFVs' -> Bool noFloatIntoArg expr = ... When deciding whether to float things into the argument of a function, in 9.4 we must know the type of the argument. This was previously done by extracting the type of the argument from the function type, computed as we walked through all the arguments. However, this backport regressed compile time performance due to allocations by `exprType` particularly in T16577 and T5642, where it turns out that computing the type of the arguments to a function is quite expensive. Instead, we can compute the type of the argument by looking at the argument term directly, which turns out to be much faster and eliminates the performance regression. - - - - - f9895206 by Zubin Duggal at 2023-04-14T00:17:37+05:30 Prepare release 9.4.5 - - - - - 30 changed files: - compiler/GHC/Core/Opt/FloatIn.hs - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - hadrian/src/Flavour.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/bytestring - libraries/containers - libraries/parsec - libraries/text - rts/Capability.c - rts/Capability.h - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/PrimOps.cmm - rts/Printer.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Sparks.h - rts/Stats.c - rts/Threads.c - rts/Timer.c - rts/TraverseHeap.c - rts/eventlog/EventLog.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e34731c80cf08c6d31ab1dc8924525aace9b4990...f9895206decc70c4b6a084247c30dcbeebebe8f4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e34731c80cf08c6d31ab1dc8924525aace9b4990...f9895206decc70c4b6a084247c30dcbeebebe8f4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 18:54:23 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Thu, 13 Apr 2023 14:54:23 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 4 commits: Prepare release 9.4.5 Message-ID: <64384fdf6d26e_10a80d2155e97c4119bb@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 35ab2927 by Zubin Duggal at 2023-04-14T00:23:57+05:30 Prepare release 9.4.5 - - - - - 9ff7a319 by Teo Camarasu at 2023-04-14T00:23:57+05:30 Add regression test for #17574 This test currently fails in the nonmoving way (cherry picked from commit a56141a69842a78d56ec11be85a775eb703219bf) - - - - - 0c216a55 by Teo Camarasu at 2023-04-14T00:23:57+05:30 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 (cherry picked from commit 20c6669fc46c567e00d3cdf22aa84479b6d8dc17) - - - - - 19c8dde2 by Teo Camarasu at 2023-04-14T00:23:57+05:30 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. (cherry picked from commit 62c3f7ee4199305cde009ededeae6ece1bcde7f0) (cherry picked from commit fabc5a1c9aa468e97429ca5f8e501ec4fbd1084f) - - - - - 13 changed files: - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - libraries/base/changelog.md - rts/sm/NonMoving.c - rts/sm/NonMoving.h - rts/sm/NonMovingMark.c - rts/sm/NonMovingMark.h - rts/sm/Sanity.c - rts/sm/Storage.c - + testsuite/tests/rts/T17574.hs - + testsuite/tests/rts/T17574.stdout - testsuite/tests/rts/all.T Changes: ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are @@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-has AC_CONFIG_MACRO_DIRS([m4]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=NO} +: ${RELEASE=YES} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the ===================================== docs/users_guide/9.4.5-notes.rst ===================================== @@ -0,0 +1,220 @@ +.. _release-9-4-5: + +Version 9.4.5 +============== + +The significant changes to the various parts of the compiler are listed in the +following sections. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +10, 11, 12, 13, or 14. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Fix a compiler bug where programs using Template Haskell involving Constant + Applicative forms could be garbage collected too early (:ghc-ticket:`22417`). + +- Fix a shadowing related bug in the occurence analysis phase of the simplifier + (:ghc-ticket:`22623`). + +- Fix a regression in the typechecker where certain typeclass instances + involving type and data familes would fail to resolve (:ghc-ticket:`22647`, + :ghc-ticket:`23134`). + +- Fix a regression in the constrain solver which resulted in a loop when trying + to expand superclasses (:ghc-ticket:`22516`). + +- Fix the linker warning about chained fixups on Darwin platforms for programs + compiled with GHC (:ghc-ticket:`22429`). + +- Fix a compiler panic in the demand analyser due to a bug involving shadowing + (:ghc-ticket:`22718`). + +- Fix a driver bug where certain non-fatal Safe Haskell related warnings were + being marked as fatal (:ghc-ticket:`22728`). + +- Fix a bug to do with missing parenthesis while printing splices with + ``-ddump-splices`` (:ghc-ticket:`22784`). + +- Fix a bug with the graph-colouring register allocater leading to compiler + panics when compiling with ``-fregs-graph`` (:ghc-ticket:`22798`, + :ghc-ticket:`23002`). + +- Fix a bug to do with code emitted on Darwin platforms using + relocations not supported on the platform (:ghc-ticket:`21972`). + +- Improve performance for code generated by the native code generator on + x86 for programs involving atomic counters (:ghc-ticket:`22764`). + +- Fix core lint errors arising from incorrect scoping of type variables + within ``SPECIALISE`` pragmas occuring in ``instance`` definitions + (:ghc-ticket:`22913`). + +- Fix core lint errors arising from an incorrect type given to the + ``decodeDouble_Int64`` rule (:ghc-ticket:`23019`). + +- Improve code generation for bitmasks on AArch64 with the native code + generator (:ghc-ticket:`23030`). + +- Many improvements to recompilation checking with multiple home units + (:ghc-ticket:`22675`, :ghc-ticket:`22677`, :ghc-ticket:`22669`, :ghc-ticket:`22678`, + :ghc-ticket:`22679`, :ghc-ticket:`22680`). + +- Fix a spurious warning with ``-Wmissing-home-modules`` (:ghc-ticket:`22676`). + +- Fix a typechecker panic on certain programs involving representation polymorphism + (:ghc-ticket:`22743`). + +- Fix bugs to do with GHCi and compiler loops pariticularly when using ``-dppr-debug`` + (:ghc-ticket:`22695`). + +- Fix memory leak in the compiler and in GHCi, including a bug where old + environments would persist on reloading (:ghc-ticket:`22530`, :ghc-ticket:`22833`). + +- Fix a miscompilation due to a simplifier bug (:ghc-ticket:`23184`). + +- Fix a miscompilation to do with unlifted bindings due to a bug in the specialiser + (:ghc-ticket:`22998`). + +- Fix a compiler panic during the "Float In" optimsation pass due to improper + handling of shadowing (:ghc-ticket:`22662`). + +- Fix a compiler panic when compiling certain programs involving representation + polymoprhism with optimisation (:ghc-ticet:`22725`). + +Runtime system +-------------- + +- Fix a GC bug where a race condition in the parallel GC could cause it to + garbage collect live sparks (:ghc-ticket:`22528`). + +- Truncate eventlog events with a large payload (:ghc-ticket:`20221`). + +- Fix a bug with the alignment of RTS data structures that could result in + segfaults when compiled with high optimisation settings on certain platforms + (:ghc-ticket:`22975` , :ghc-ticket:`22965`). + +- Take section alignment into account in the RTS linker (:ghc-ticket:`23066`). + +- Fix a bug causing segfaults where certain sections of the RTS would assume + that the number of capabilites was equal to the number passed via the command + line, even though the number of capabilites can be dynamically changed + (:ghc-ticket:`23088`). + +- Fix a race with the nonmoving GC (:ghc-ticket:`23170`). + +- A bug in the nonmoving garbage collector regarding the treatment of + zero-length ``SmallArray#``\ s has been fixed (:ghc-ticket:`22264`). + +- A number of bugs regarding the non-moving garbage collector's treatment of + ``Weak#`` pointers have been fixed (:ghc-ticket:`22327`). + +- A few race conditions between the non-moving collector and + ``setNumCapabilities`` which could result in undefined behavior have been + fixed (:ghc-ticket:`22926`, :ghc-ticket:`22927`). + +- The non-moving collector is now able to better schedule marking work during + the post-mark synchronization phase of collection, significantly reducing + pause times in some workloads (:ghc-ticket:`22929`). + +- Various bugs in the non-moving collector's implementation of the selector + optimisation have been fixed (:ghc-ticket:`22930`). + +- Accounting for live bytes is now performed accurately when using the + non-moving GC (:ghc-ticket:`17574`). + +- Allow performing memory inventory with the non-moving GC (:ghc-ticket:`21840`). + +Build system and packaging +-------------------------- + +- Bump ``gmp-tarballs`` to a version which doesn't use the reserved ``x18`` + register on AArch64/Darwin systems, and also has fixes for CVE-2021-43618 + (:ghc-ticket:`22497`, :ghc-ticket:`22789`). + +- Remove quarantine attribute when installing binary distribution on MacOS + (:ghc-ticket:`21506`, :ghc-ticket:`23009`). + +- Fail in the binary distribution ``configure`` script if ``find`` is not + available (:ghc-ticket:`22691`). + +- Install manpages with the binary distribution (:ghc-ticket:`22371`). + +- Fix a bug to do with merging of archives causing GHC to fail to bootstrap + on Windows (:ghc-ticket:`21990`). + +- Hadrian bug fixes to do with building a Windows cross compiler + (:ghc-ticket:`20697`, :ghc-ticket:`22805`). + +- Fix escaping of ``$tooldir`` in the ``configure`` script (:ghc-ticket:`22561`). + +- Allow LLVM 14 and use it for the Windows toolchain (:ghc-ticket:`21964`). + +Core libraries +-------------- + +- Bump ``base`` to 4.17.1.0 + +- base: Remove ``mingwex`` dependency on Windows (:ghc-ticket:`22166`). + +- base: Fix inconsistency with decoding terminal input on Windows (:ghc-ticket:`21488`). + +- Bump ``bytestring`` to 0.11.4.0 + +- Bump``parsec`` to 3.1.16.1 + +- Bump ``text`` to 2.0.2 + +- Bump ``containers`` to 0.6.7 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/release-notes.rst ===================================== @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 1 + 9.4.5-notes 9.4.4-notes 9.4.3-notes 9.4.2-notes ===================================== libraries/base/changelog.md ===================================== @@ -4,7 +4,7 @@ * Remove `mingwex` dependency on Windows (#22166). - * Fix inconcistency with decoding terminal input on Windows (#21488). + * Fix inconsistency with decoding terminal input on Windows (#21488). ## 4.17.0.0 *August 2022* ===================================== rts/sm/NonMoving.c ===================================== @@ -396,7 +396,8 @@ Mutex concurrent_coll_finished_lock; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The nonmoving collector uses an approximate heuristic for reporting live * data quantity. Specifically, during mark we record how much live data we - * find in nonmoving_live_words. At the end of mark we declare this amount to + * find in nonmoving_segment_live_words. At the end of mark this is combined with nonmoving_large_words + * and nonmoving_compact_words, and we declare this amount to * be how much live data we have on in the nonmoving heap (by setting * oldest_gen->live_estimate). * @@ -541,7 +542,7 @@ Mutex concurrent_coll_finished_lock; * */ -memcount nonmoving_live_words = 0; +memcount nonmoving_segment_live_words = 0; // See Note [Sync phase marking budget]. MarkBudget sync_phase_marking_budget = 200000; @@ -683,10 +684,11 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_large_objects); } n_nonmoving_large_blocks += oldest_gen->n_large_blocks; + nonmoving_large_words += oldest_gen->n_large_words; oldest_gen->large_objects = NULL; oldest_gen->n_large_words = 0; oldest_gen->n_large_blocks = 0; - nonmoving_live_words = 0; + nonmoving_segment_live_words = 0; // Clear compact object mark bits for (bdescr *bd = nonmoving_compact_objects; bd; bd = bd->link) { @@ -701,6 +703,7 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_compact_objects); } n_nonmoving_compact_blocks += oldest_gen->n_compact_blocks; + nonmoving_compact_words += oldest_gen->n_compact_blocks * BLOCK_SIZE_W; oldest_gen->n_compact_blocks = 0; oldest_gen->compact_objects = NULL; // TODO (osa): what about "in import" stuff?? @@ -1054,7 +1057,9 @@ concurrent_marking: freeMarkQueue(mark_queue); stgFree(mark_queue); - oldest_gen->live_estimate = nonmoving_live_words; + nonmoving_large_words = countOccupied(nonmoving_marked_large_objects); + nonmoving_compact_words = n_nonmoving_marked_compact_blocks * BLOCK_SIZE_W; + oldest_gen->live_estimate = nonmoving_segment_live_words + nonmoving_large_words + nonmoving_compact_words; oldest_gen->n_old_blocks = 0; resizeGenerations(); ===================================== rts/sm/NonMoving.h ===================================== @@ -120,10 +120,11 @@ struct NonmovingHeap { extern struct NonmovingHeap nonmovingHeap; -extern memcount nonmoving_live_words; +extern memcount nonmoving_segment_live_words; #if defined(THREADED_RTS) extern bool concurrent_coll_running; +extern Mutex nonmoving_collection_mutex; #endif void nonmovingInit(void); ===================================== rts/sm/NonMovingMark.c ===================================== @@ -76,6 +76,10 @@ static bool is_nonmoving_weak(StgWeak *weak); * consequently will trace the pointers of only one object per block. However, * this is okay since the only type of pinned object supported by GHC is the * pinned ByteArray#, which has no pointers. + * + * We need to take care that the stats department is made aware of the amount of + * live large (and compact) objects, since they no longer live on gen[i]->large_objects. + * Failing to do so caused #17574. */ bdescr *nonmoving_large_objects = NULL; @@ -83,6 +87,9 @@ bdescr *nonmoving_marked_large_objects = NULL; memcount n_nonmoving_large_blocks = 0; memcount n_nonmoving_marked_large_blocks = 0; +memcount nonmoving_large_words = 0; +memcount nonmoving_compact_words = 0; + bdescr *nonmoving_compact_objects = NULL; bdescr *nonmoving_marked_compact_objects = NULL; memcount n_nonmoving_compact_blocks = 0; @@ -1736,7 +1743,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p); nonmoving_block_idx block_idx = nonmovingGetBlockIdx((StgPtr) p); nonmovingSetMark(seg, block_idx); - nonmoving_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); + nonmoving_segment_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); } // If we found a indirection to shortcut keep going. ===================================== rts/sm/NonMovingMark.h ===================================== @@ -127,6 +127,11 @@ extern bdescr *nonmoving_large_objects, *nonmoving_marked_large_objects, extern memcount n_nonmoving_large_blocks, n_nonmoving_marked_large_blocks, n_nonmoving_compact_blocks, n_nonmoving_marked_compact_blocks; +// The size of live large/compact objects in words. +// Only updated at the end of nonmoving GC. +extern memcount nonmoving_large_words, + nonmoving_compact_words; + extern StgTSO *nonmoving_old_threads; extern StgWeak *nonmoving_old_weak_ptr_list; extern StgTSO *nonmoving_threads; ===================================== rts/sm/Sanity.c ===================================== @@ -1206,11 +1206,12 @@ memInventory (bool show) bool leak; #if defined(THREADED_RTS) - // Can't easily do a memory inventory: We might race with the nonmoving - // collector. In principle we could try to take nonmoving_collection_mutex - // and do an inventory if we have it but we don't currently implement this. - if (RtsFlags.GcFlags.useNonmoving) - return; + // We need to be careful not to race with the nonmoving collector. + // If a nonmoving collection is on-going we simply abort the inventory. + if (RtsFlags.GcFlags.useNonmoving){ + if(TRY_ACQUIRE_LOCK(&nonmoving_collection_mutex)) + return; + } #endif // count the blocks we current have @@ -1314,6 +1315,13 @@ memInventory (bool show) } ASSERT(n_alloc_blocks == live_blocks); ASSERT(!leak); + +#if defined(THREADED_RTS) + if (RtsFlags.GcFlags.useNonmoving){ + RELEASE_LOCK(&nonmoving_collection_mutex); + } +#endif + } ===================================== rts/sm/Storage.c ===================================== @@ -42,6 +42,7 @@ #include "GC.h" #include "Evac.h" #include "NonMovingAllocate.h" +#include "sm/NonMovingMark.h" #if defined(ios_HOST_OS) || defined(darwin_HOST_OS) #include "Hash.h" #endif @@ -1615,7 +1616,12 @@ W_ genLiveWords (generation *gen) W_ genLiveBlocks (generation *gen) { - return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks; + W_ nonmoving_blocks = 0; + // The nonmoving heap contains some blocks that live outside the regular generation structure. + if (gen == oldest_gen && RtsFlags.GcFlags.useNonmoving){ + nonmoving_blocks = n_nonmoving_large_blocks + n_nonmoving_marked_large_blocks + n_nonmoving_compact_blocks + n_nonmoving_marked_compact_blocks; + } + return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks + nonmoving_blocks; } W_ gcThreadLiveWords (uint32_t i, uint32_t g) @@ -1711,6 +1717,9 @@ StgWord calcTotalLargeObjectsW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_large_words; } + + totalW += nonmoving_large_words; + return totalW; } @@ -1722,6 +1731,9 @@ StgWord calcTotalCompactW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_compact_blocks * BLOCK_SIZE_W; } + + totalW += nonmoving_compact_words; + return totalW; } ===================================== testsuite/tests/rts/T17574.hs ===================================== @@ -0,0 +1,40 @@ +-- | Check that large objects are properly accounted for by GHC.Stats +module Main (main) where + +import Control.Monad +import Control.Exception +import Control.Concurrent +import System.Mem +import System.Exit +import GHC.Stats +import GHC.Compact +import Data.List (replicate) + +import qualified Data.ByteString.Char8 as BS + +doGC :: IO () +doGC = do + performMajorGC + threadDelay 1000 -- small delay to allow GC to run when using concurrent gc + +main :: IO () +main = do + let size = 4096*2 + largeString <- evaluate $ BS.replicate size 'A' + compactString <- compact $ replicate size 'A' + doGC + doGC -- run GC twice to make sure the objects end up in the oldest gen + stats <- getRTSStats + let large_obj_bytes = gcdetails_large_objects_bytes $ gc stats + let compact_obj_bytes = gcdetails_compact_bytes $ gc stats + -- assert that large_obj_bytes is at least as big as size + -- this indicates that `largeString` is being accounted for by the stats department + when (large_obj_bytes < fromIntegral size) $ do + putStrLn $ "large_obj_bytes is: " <> show large_obj_bytes <> " but expected at least: " <> show size + exitFailure + when (compact_obj_bytes < fromIntegral size) $ do + putStrLn $ "compact_obj_bytes is: " <> show large_obj_bytes <> " but expected at least: " <> show size + exitFailure + -- keep them alive + print $ BS.length largeString + print $ length $ getCompact compactString ===================================== testsuite/tests/rts/T17574.stdout ===================================== @@ -0,0 +1,2 @@ +8192 +8192 ===================================== testsuite/tests/rts/all.T ===================================== @@ -489,3 +489,5 @@ test('decodeMyStack', normal, compile_and_run, ['-finfo-table-map']) test('decodeMyStack_underflowFrames', [extra_run_opts('+RTS -kc8K -RTS')], compile_and_run, ['-finfo-table-map -rtsopts']) # -finfo-table-map intentionally missing test('decodeMyStack_emptyListForMissingFlag', [ignore_stdout, ignore_stderr], compile_and_run, ['']) + +test('T17574', [], compile_and_run, ['-with-rtsopts -T']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9895206decc70c4b6a084247c30dcbeebebe8f4...19c8dde2a7d1f404d1c92ab0a053c085f6c76ced -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9895206decc70c4b6a084247c30dcbeebebe8f4...19c8dde2a7d1f404d1c92ab0a053c085f6c76ced You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 21:01:24 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 13 Apr 2023 17:01:24 -0400 Subject: [Git][ghc/ghc][wip/js-th] 2 commits: Fix tests Message-ID: <64386da4c596f_10a80d2398b1744287bf@gitlab.mail> Sylvain Henry pushed to branch wip/js-th at Glasgow Haskell Compiler / GHC Commits: 55209151 by Sylvain Henry at 2023-04-13T23:03:44+02:00 Fix tests - - - - - 3fde377b by Sylvain Henry at 2023-04-13T23:05:27+02:00 Remove spurious change - - - - - 3 changed files: - compiler/GHC/Driver/Pipeline.hs - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout Changes: ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -111,6 +111,8 @@ import GHC.Types.SourceError import GHC.Unit import GHC.Unit.Env +--import GHC.Unit.Finder +--import GHC.Unit.State import GHC.Unit.Module.ModSummary import GHC.Unit.Module.ModIface import GHC.Unit.Module.Deps ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -149,6 +149,7 @@ GHC.JS.Make GHC.JS.Ppr GHC.JS.Syntax GHC.JS.Transform +GHC.JS.Unsat.Syntax GHC.Linker.Static.Utils GHC.Linker.Types GHC.Parser.Annotation ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -150,6 +150,7 @@ GHC.JS.Make GHC.JS.Ppr GHC.JS.Syntax GHC.JS.Transform +GHC.JS.Unsat.Syntax GHC.Linker.Static.Utils GHC.Linker.Types GHC.Parser View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c37f48c594a8924af508f35af249eac914e203fb...3fde377be3a3711f6803f432f826754cf227ef33 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c37f48c594a8924af508f35af249eac914e203fb...3fde377be3a3711f6803f432f826754cf227ef33 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 22:40:08 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 13 Apr 2023 18:40:08 -0400 Subject: [Git][ghc/ghc][wip/T23252] Stop if type constructors have kind errors Message-ID: <643884c84a0ae_10a80d2536e44c43362e@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23252 at Glasgow Haskell Compiler / GHC Commits: 341aeeaf by Simon Peyton Jones at 2023-04-13T23:40:31+01:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 6 changed files: - compiler/GHC/Tc/TyCl.hs - testsuite/tests/dependent/should_fail/T15743c.hs - testsuite/tests/dependent/should_fail/T15743c.stderr - + testsuite/tests/roles/should_fail/T23252.hs - + testsuite/tests/roles/should_fail/T23252.stderr - testsuite/tests/roles/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -248,7 +248,13 @@ tcTyClDecls tyclds kisig_env role_annots = do { -- Step 1: kind-check this group and returns the final -- (possibly-polymorphic) kind of each TyCon and Class -- See Note [Kind checking for type and class decls] - (tc_tycons, kindless) <- kcTyClGroup kisig_env tyclds + (tc_tycons, kindless) <- checkNoErrs $ + kcTyClGroup kisig_env tyclds + -- checkNoErrs: If the TyCons are ill-kinded, stop now. Else we + -- can get follow-on errors. Example: #23252, where the TyCon + -- had an ill-scoped kind forall (d::k) k (a::k). blah + -- and that ill-scoped kind made role inference fall over. + ; traceTc "tcTyAndCl generalized kinds" (vcat (map ppr_tc_tycon tc_tycons)) -- Step 2: type-check all groups together, returning ===================================== testsuite/tests/dependent/should_fail/T15743c.hs ===================================== @@ -8,4 +8,4 @@ import Data.Proxy data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type data T k (c :: k) (a :: Proxy c) b (x :: SimilarKind a b) -data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) + ===================================== testsuite/tests/dependent/should_fail/T15743c.stderr ===================================== @@ -13,18 +13,3 @@ T15743c.hs:10:1: error: (b :: Proxy d) (x :: SimilarKind a b) • In the data type declaration for ‘T’ - -T15743c.hs:11:1: error: - • The kind of ‘T2’ is ill-scoped - Inferred kind: T2 :: forall (d :: k). - forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> - SimilarKind a b -> * - NB: Specified variables (namely: (d :: k)) always come first - Perhaps try this order instead: - k - (d :: k) - (c :: k) - (a :: Proxy c) - (b :: Proxy d) - (x :: SimilarKind a b) - • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/T23252.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE PolyKinds, DataKinds, ExplicitForAll #-} +{-# LANGUAGE RoleAnnotations #-} + +module T15743 where + +import Data.Kind +import Data.Proxy + +data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type + +data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) +type role T2 nominal nominal nominal nominal -- Too few! ===================================== testsuite/tests/roles/should_fail/T23252.stderr ===================================== @@ -0,0 +1,14 @@ +T23252.hs:11:1: error: + • The kind of ‘T2’ is ill-scoped + Inferred kind: T2 :: forall (d :: k). + forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> + SimilarKind a b -> * + NB: Specified variables (namely: (d :: k)) always come first + Perhaps try this order instead: + k + (d :: k) + (c :: k) + (a :: Proxy c) + (b :: Proxy d) + (x :: SimilarKind a b) + • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/all.T ===================================== @@ -8,3 +8,4 @@ test('Roles12', [], makefile_test, []) test('T8773', normal, compile_fail, ['']) test('T9204', [], makefile_test, []) test('RolesIArray', normal, compile_fail, ['']) +test('T23252', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/341aeeaf9edd88080a40e9c8a1167f37dadb71f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/341aeeaf9edd88080a40e9c8a1167f37dadb71f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 13 23:57:04 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 13 Apr 2023 19:57:04 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Add quotRem rules (#22152) Message-ID: <643896d0da2e5_10a80d268751744523a2@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - 18a451d2 by Adam Sandberg Ericsson at 2023-04-13T19:56:59-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - 6813e725 by Matthew Pickering at 2023-04-13T19:57:00-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Types/Literal.hs - docs/index.html → docs/index.html.in - docs/users_guide/index.rst - + docs/users_guide/javascript.rst - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - + libraries/base/GHC/JS/Foreign/Callback.hs - libraries/base/GHC/JS/Prim.hs - libraries/base/base.cabal - rts/StablePtr.c - testsuite/tests/javascript/all.T - + testsuite/tests/javascript/js-callback01.hs - + testsuite/tests/javascript/js-callback01.stdout - + testsuite/tests/javascript/js-callback02.hs - + testsuite/tests/javascript/js-callback02.stdout - + testsuite/tests/javascript/js-callback03.hs - + testsuite/tests/javascript/js-callback03.stdout - + testsuite/tests/javascript/js-callback04.hs - + testsuite/tests/javascript/js-callback04.stdout - + testsuite/tests/javascript/js-callback05.hs - + testsuite/tests/javascript/js-callback05.stdout - + testsuite/tests/javascript/js-ffi-array.hs - + testsuite/tests/javascript/js-ffi-array.stdout - + testsuite/tests/javascript/js-ffi-int.hs - + testsuite/tests/javascript/js-ffi-int.stdout - + testsuite/tests/javascript/js-ffi-isNull.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f435268da08a9f6f4c0ec7581755ff48f9044327...6813e72540043bc52fa86e66e916f4e911682728 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f435268da08a9f6f4c0ec7581755ff48f9044327...6813e72540043bc52fa86e66e916f4e911682728 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 05:37:53 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Apr 2023 01:37:53 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <6438e6b16315d_10a80d2c0604744661ad@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 68032477 by Adam Sandberg Ericsson at 2023-04-14T01:37:44-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - 4e25561a by Matthew Pickering at 2023-04-14T01:37:45-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - 7a1b9b01 by Simon Peyton Jones at 2023-04-14T01:37:46-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 10 changed files: - compiler/GHC/Tc/TyCl.hs - docs/index.html → docs/index.html.in - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - rts/StablePtr.c - testsuite/tests/dependent/should_fail/T15743c.hs - testsuite/tests/dependent/should_fail/T15743c.stderr - + testsuite/tests/roles/should_fail/T23252.hs - + testsuite/tests/roles/should_fail/T23252.stderr - testsuite/tests/roles/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -248,7 +248,13 @@ tcTyClDecls tyclds kisig_env role_annots = do { -- Step 1: kind-check this group and returns the final -- (possibly-polymorphic) kind of each TyCon and Class -- See Note [Kind checking for type and class decls] - (tc_tycons, kindless) <- kcTyClGroup kisig_env tyclds + (tc_tycons, kindless) <- checkNoErrs $ + kcTyClGroup kisig_env tyclds + -- checkNoErrs: If the TyCons are ill-kinded, stop now. Else we + -- can get follow-on errors. Example: #23252, where the TyCon + -- had an ill-scoped kind forall (d::k) k (a::k). blah + -- and that ill-scoped kind made role inference fall over. + ; traceTc "tcTyAndCl generalized kinds" (vcat (map ppr_tc_tycon tc_tycons)) -- Step 2: type-check all groups together, returning ===================================== docs/index.html → docs/index.html.in ===================================== @@ -39,7 +39,7 @@
  • - GHC API + GHC API

    Documentation for the GHC API. ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -193,7 +193,7 @@ buildHtmlDocumentation = do | SphinxHTML `Set.member` doctargets ] need $ map ((root -/-) . pathIndex) targets - copyFileUntracked "docs/index.html" file + copyFile "docs/index.html" file -- | Compile a Sphinx ReStructured Text package to HTML. buildSphinxHtml :: FilePath -> Rules () ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -305,10 +305,10 @@ rtsCabalFlags = mconcat flag = interpolateCabalFlag packageVersions :: Interpolations -packageVersions = foldMap f [ base, ghcPrim, ghc, cabal, templateHaskell, ghcCompact, array ] +packageVersions = foldMap f [ base, ghcPrim, compiler, ghc, cabal, templateHaskell, ghcCompact, array ] where f :: Package -> Interpolations - f pkg = interpolateVar var $ show . version <$> readPackageData pkg + f pkg = interpolateVar var $ version <$> readPackageData pkg where var = "LIBRARY_" <> pkgName pkg <> "_VERSION" templateRule :: FilePath -> Interpolations -> Rules () @@ -335,6 +335,7 @@ templateRules = do templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion templateRule "libraries/prologue.txt" $ packageVersions + templateRule "docs/index.html" $ packageVersions -- Generators ===================================== rts/StablePtr.c ===================================== @@ -98,8 +98,13 @@ */ +// the global stable pointer entry table spEntry *stable_ptr_table = NULL; + +// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after static spEntry *stable_ptr_free = NULL; + +// current stable pointer table size static unsigned int SPT_size = 0; #define INIT_SPT_SIZE 64 @@ -117,6 +122,7 @@ static unsigned int SPT_size = 0; #error unknown SIZEOF_VOID_P #endif +// old stable pointer tables static spEntry *old_SPTs[MAX_N_OLD_SPTS]; static uint32_t n_old_SPTs = 0; @@ -149,8 +155,9 @@ stablePtrUnlock(void) * -------------------------------------------------------------------------- */ STATIC_INLINE void -initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free) +initSpEntryFreeList(spEntry *table, uint32_t n) { + spEntry* free = NULL; spEntry *p; for (p = table + n - 1; p >= table; p--) { p->addr = (P_)free; @@ -166,7 +173,7 @@ initStablePtrTable(void) SPT_size = INIT_SPT_SIZE; stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry), "initStablePtrTable"); - initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL); + initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE); #if defined(THREADED_RTS) initMutex(&stable_ptr_mutex); @@ -181,6 +188,8 @@ initStablePtrTable(void) static void enlargeStablePtrTable(void) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + uint32_t old_SPT_size = SPT_size; spEntry *new_stable_ptr_table; @@ -206,7 +215,8 @@ enlargeStablePtrTable(void) */ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table); - initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); + // add the new entries to the free list + initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size); } /* Note [Enlarging the stable pointer table] @@ -245,6 +255,7 @@ exitStablePtrTable(void) { if (stable_ptr_table) stgFree(stable_ptr_table); + stable_ptr_table = NULL; SPT_size = 0; @@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp) void freeStablePtrUnsafe(StgStablePtr sp) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + // see Note [NULL StgStablePtr] if (sp == NULL) { return; } + StgWord spw = (StgWord)sp - 1; + ASSERT(spw < SPT_size); + freeSpEntry(&stable_ptr_table[spw]); } @@ -278,25 +294,35 @@ void freeStablePtr(StgStablePtr sp) { stablePtrLock(); + freeStablePtrUnsafe(sp); + stablePtrUnlock(); } /* ----------------------------------------------------------------------------- - * Looking up + * Allocating stable pointers * -------------------------------------------------------------------------- */ StgStablePtr getStablePtr(StgPtr p) { - StgWord sp; - stablePtrLock(); - if (!stable_ptr_free) enlargeStablePtrTable(); - sp = stable_ptr_free - stable_ptr_table; - stable_ptr_free = (spEntry*)(stable_ptr_free->addr); - RELAXED_STORE(&stable_ptr_table[sp].addr, p); + + if (!stable_ptr_free) + enlargeStablePtrTable(); + + // find the index of free stable ptr + StgWord sp = stable_ptr_free - stable_ptr_table; + + // unlink the table entry we grabbed from the free list + stable_ptr_free = (spEntry*)(stable_ptr_free->addr); + + // release store to pair with acquire load in deRefStablePtr + RELEASE_STORE(&stable_ptr_table[sp].addr, p); + stablePtrUnlock(); + // see Note [NULL StgStablePtr] sp = sp + 1; return (StgStablePtr)(sp); ===================================== testsuite/tests/dependent/should_fail/T15743c.hs ===================================== @@ -8,4 +8,4 @@ import Data.Proxy data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type data T k (c :: k) (a :: Proxy c) b (x :: SimilarKind a b) -data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) + ===================================== testsuite/tests/dependent/should_fail/T15743c.stderr ===================================== @@ -13,18 +13,3 @@ T15743c.hs:10:1: error: (b :: Proxy d) (x :: SimilarKind a b) • In the data type declaration for ‘T’ - -T15743c.hs:11:1: error: - • The kind of ‘T2’ is ill-scoped - Inferred kind: T2 :: forall (d :: k). - forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> - SimilarKind a b -> * - NB: Specified variables (namely: (d :: k)) always come first - Perhaps try this order instead: - k - (d :: k) - (c :: k) - (a :: Proxy c) - (b :: Proxy d) - (x :: SimilarKind a b) - • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/T23252.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE PolyKinds, DataKinds, ExplicitForAll #-} +{-# LANGUAGE RoleAnnotations #-} + +module T15743 where + +import Data.Kind +import Data.Proxy + +data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type + +data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) +type role T2 nominal nominal nominal nominal -- Too few! ===================================== testsuite/tests/roles/should_fail/T23252.stderr ===================================== @@ -0,0 +1,14 @@ +T23252.hs:11:1: error: + • The kind of ‘T2’ is ill-scoped + Inferred kind: T2 :: forall (d :: k). + forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> + SimilarKind a b -> * + NB: Specified variables (namely: (d :: k)) always come first + Perhaps try this order instead: + k + (d :: k) + (c :: k) + (a :: Proxy c) + (b :: Proxy d) + (x :: SimilarKind a b) + • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/all.T ===================================== @@ -8,3 +8,4 @@ test('Roles12', [], makefile_test, []) test('T8773', normal, compile_fail, ['']) test('T9204', [], makefile_test, []) test('RolesIArray', normal, compile_fail, ['']) +test('T23252', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6813e72540043bc52fa86e66e916f4e911682728...7a1b9b016a86a5a31b9c01e29060973c348fab07 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6813e72540043bc52fa86e66e916f4e911682728...7a1b9b016a86a5a31b9c01e29060973c348fab07 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 07:38:02 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 14 Apr 2023 03:38:02 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 68 commits: Bump submodules: text, parsec, bytestring, containers Message-ID: <643902da877b9_10a80d2e012f88476818@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 0bc34bd0 by Zubin Duggal at 2023-04-14T13:07:37+05:30 Bump submodules: text, parsec, bytestring, containers - - - - - 40bf9669 by Zubin Duggal at 2023-04-14T13:07:37+05:30 Bump base to 4.17.1.0 and add release notes - - - - - 8244cdcf by Zubin Duggal at 2023-04-14T13:07:37+05:30 Allow LLVM 14 - - - - - 083017b9 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - c192ecd0 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 509c30d2 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - 1717f212 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - 2d6d6fdd by Ben Gamari at 2023-04-14T13:07:38+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - 76508973 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - de27e933 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - 1405f97a by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - d01a6ea7 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - ec088ed3 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - fe5c048b by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 6326b966 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - d3404b5a by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - 9c77c4b9 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - b96e007c by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - d29d4837 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - 6d1d5e84 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - e07c917c by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - d8c99faa by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - f521c304 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - f59ee743 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - 66c32a26 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - a7be6c65 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - 70a8ca3f by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - 19db4bf7 by Ben Gamari at 2023-04-14T13:07:38+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - 1a6716be by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - fb9caa54 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - ecf80b17 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - 64f05017 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - dbf32a81 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - 77ddce65 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - 162c3509 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - a5fb1176 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 986028e8 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - 2c0ed71d by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - a6e08eff by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - ec8ae75e by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - bdf67900 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - 61e6b54d by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - 1f9376bc by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - 146530f0 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - ee3a6e37 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - c2b57cc8 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - 4f86e5d6 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - f0e75bc3 by Ben Gamari at 2023-04-14T13:07:39+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - 4fd491c1 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - 890d0df6 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - d616fef8 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - ca9068c0 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - 4b6acb26 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - f9b47bde by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - a79e52cf by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - 8a031eb8 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - 1b294f15 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - 4c855ce5 by Ben Gamari at 2023-04-14T13:07:40+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - 6a18fc31 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - fa9c8e61 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - b7a380d9 by Ben Gamari at 2023-04-14T13:07:40+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 70d9353f by Ben Gamari at 2023-04-14T13:07:40+05:30 contextswitch - - - - - b82c9613 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Fix incorrect format specifier warnings - - - - - 11ac9861 by Zubin Duggal at 2023-04-14T13:07:40+05:30 compiler: Fix performance regression in backport of "Make FloatIn robust to shadowing" (6206cb9287f3f6e70c669660a646a65274870d2b) In 9.4, we have noFloatIntoArg :: CoreExprWithFVs' -> Type -> Bool noFloatIntoArg expr expr_ty = ... But in master when 6206cb92 landed, after "Drop the app invariant" (dcf30da8) we had noFloatIntoArg :: CoreExprWithFVs' -> Bool noFloatIntoArg expr = ... When deciding whether to float things into the argument of a function, in 9.4 we must know the type of the argument. This was previously done by extracting the type of the argument from the function type, computed as we walked through all the arguments. However, this backport regressed compile time performance due to allocations by `exprType` particularly in T16577 and T5642, where it turns out that computing the type of the arguments to a function is quite expensive. Instead, we can compute the type of the argument by looking at the argument term directly, which turns out to be much faster and eliminates the performance regression. - - - - - 6fd97ab1 by Zubin Duggal at 2023-04-14T13:07:40+05:30 Prepare release 9.4.5 - - - - - 82b1c20b by Teo Camarasu at 2023-04-14T13:07:40+05:30 Add regression test for #17574 This test currently fails in the nonmoving way (cherry picked from commit a56141a69842a78d56ec11be85a775eb703219bf) - - - - - 90da06d5 by Teo Camarasu at 2023-04-14T13:07:40+05:30 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 (cherry picked from commit 20c6669fc46c567e00d3cdf22aa84479b6d8dc17) - - - - - 0ac1c43d by Teo Camarasu at 2023-04-14T13:07:40+05:30 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. (cherry picked from commit 62c3f7ee4199305cde009ededeae6ece1bcde7f0) (cherry picked from commit fabc5a1c9aa468e97429ca5f8e501ec4fbd1084f) - - - - - 30 changed files: - compiler/GHC/Core/Opt/FloatIn.hs - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - hadrian/src/Flavour.hs - libraries/base/base.cabal - libraries/base/changelog.md - libraries/bytestring - libraries/containers - libraries/parsec - libraries/text - rts/Capability.c - rts/Capability.h - rts/HeapStackCheck.cmm - rts/IOManager.c - rts/PrimOps.cmm - rts/Printer.c - rts/Profiling.c - rts/Proftimer.c - rts/RetainerProfile.c - rts/RtsAPI.c - rts/RtsStartup.c - rts/Schedule.c - rts/Schedule.h - rts/Sparks.h - rts/Stats.c - rts/Threads.c - rts/Timer.c - rts/TraverseHeap.c - rts/eventlog/EventLog.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19c8dde2a7d1f404d1c92ab0a053c085f6c76ced...0ac1c43dd13a6b515ee8fd0158690949e862b75d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19c8dde2a7d1f404d1c92ab0a053c085f6c76ced...0ac1c43dd13a6b515ee8fd0158690949e862b75d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 07:42:19 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 14 Apr 2023 03:42:19 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 4 commits: Add regression test for #17574 Message-ID: <643903db33d3b_10a80d2e11774447952b@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 0a6f2a0d by Teo Camarasu at 2023-04-14T13:08:15+05:30 Add regression test for #17574 This test currently fails in the nonmoving way (cherry picked from commit a56141a69842a78d56ec11be85a775eb703219bf) - - - - - 9a85b847 by Teo Camarasu at 2023-04-14T13:08:15+05:30 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 (cherry picked from commit 20c6669fc46c567e00d3cdf22aa84479b6d8dc17) - - - - - 2058c8ef by Teo Camarasu at 2023-04-14T13:08:15+05:30 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. (cherry picked from commit 62c3f7ee4199305cde009ededeae6ece1bcde7f0) (cherry picked from commit fabc5a1c9aa468e97429ca5f8e501ec4fbd1084f) - - - - - d52ea64e by Zubin Duggal at 2023-04-14T13:11:53+05:30 Prepare release 9.4.5 Metric Decrease: T13035 T15164 T1969 T9961 WWRec T12707 T13379 - - - - - 13 changed files: - configure.ac - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - libraries/base/changelog.md - rts/sm/NonMoving.c - rts/sm/NonMoving.h - rts/sm/NonMovingMark.c - rts/sm/NonMovingMark.h - rts/sm/Sanity.c - rts/sm/Storage.c - + testsuite/tests/rts/T17574.hs - + testsuite/tests/rts/T17574.stdout - testsuite/tests/rts/all.T Changes: ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are @@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-has AC_CONFIG_MACRO_DIRS([m4]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=NO} +: ${RELEASE=YES} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the ===================================== docs/users_guide/9.4.5-notes.rst ===================================== @@ -0,0 +1,220 @@ +.. _release-9-4-5: + +Version 9.4.5 +============== + +The significant changes to the various parts of the compiler are listed in the +following sections. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +10, 11, 12, 13, or 14. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Fix a compiler bug where programs using Template Haskell involving Constant + Applicative forms could be garbage collected too early (:ghc-ticket:`22417`). + +- Fix a shadowing related bug in the occurence analysis phase of the simplifier + (:ghc-ticket:`22623`). + +- Fix a regression in the typechecker where certain typeclass instances + involving type and data familes would fail to resolve (:ghc-ticket:`22647`, + :ghc-ticket:`23134`). + +- Fix a regression in the constrain solver which resulted in a loop when trying + to expand superclasses (:ghc-ticket:`22516`). + +- Fix the linker warning about chained fixups on Darwin platforms for programs + compiled with GHC (:ghc-ticket:`22429`). + +- Fix a compiler panic in the demand analyser due to a bug involving shadowing + (:ghc-ticket:`22718`). + +- Fix a driver bug where certain non-fatal Safe Haskell related warnings were + being marked as fatal (:ghc-ticket:`22728`). + +- Fix a bug to do with missing parenthesis while printing splices with + ``-ddump-splices`` (:ghc-ticket:`22784`). + +- Fix a bug with the graph-colouring register allocater leading to compiler + panics when compiling with ``-fregs-graph`` (:ghc-ticket:`22798`, + :ghc-ticket:`23002`). + +- Fix a bug to do with code emitted on Darwin platforms using + relocations not supported on the platform (:ghc-ticket:`21972`). + +- Improve performance for code generated by the native code generator on + x86 for programs involving atomic counters (:ghc-ticket:`22764`). + +- Fix core lint errors arising from incorrect scoping of type variables + within ``SPECIALISE`` pragmas occuring in ``instance`` definitions + (:ghc-ticket:`22913`). + +- Fix core lint errors arising from an incorrect type given to the + ``decodeDouble_Int64`` rule (:ghc-ticket:`23019`). + +- Improve code generation for bitmasks on AArch64 with the native code + generator (:ghc-ticket:`23030`). + +- Many improvements to recompilation checking with multiple home units + (:ghc-ticket:`22675`, :ghc-ticket:`22677`, :ghc-ticket:`22669`, :ghc-ticket:`22678`, + :ghc-ticket:`22679`, :ghc-ticket:`22680`). + +- Fix a spurious warning with ``-Wmissing-home-modules`` (:ghc-ticket:`22676`). + +- Fix a typechecker panic on certain programs involving representation polymorphism + (:ghc-ticket:`22743`). + +- Fix bugs to do with GHCi and compiler loops pariticularly when using ``-dppr-debug`` + (:ghc-ticket:`22695`). + +- Fix memory leak in the compiler and in GHCi, including a bug where old + environments would persist on reloading (:ghc-ticket:`22530`, :ghc-ticket:`22833`). + +- Fix a miscompilation due to a simplifier bug (:ghc-ticket:`23184`). + +- Fix a miscompilation to do with unlifted bindings due to a bug in the specialiser + (:ghc-ticket:`22998`). + +- Fix a compiler panic during the "Float In" optimsation pass due to improper + handling of shadowing (:ghc-ticket:`22662`). + +- Fix a compiler panic when compiling certain programs involving representation + polymoprhism with optimisation (:ghc-ticet:`22725`). + +Runtime system +-------------- + +- Fix a GC bug where a race condition in the parallel GC could cause it to + garbage collect live sparks (:ghc-ticket:`22528`). + +- Truncate eventlog events with a large payload (:ghc-ticket:`20221`). + +- Fix a bug with the alignment of RTS data structures that could result in + segfaults when compiled with high optimisation settings on certain platforms + (:ghc-ticket:`22975` , :ghc-ticket:`22965`). + +- Take section alignment into account in the RTS linker (:ghc-ticket:`23066`). + +- Fix a bug causing segfaults where certain sections of the RTS would assume + that the number of capabilites was equal to the number passed via the command + line, even though the number of capabilites can be dynamically changed + (:ghc-ticket:`23088`). + +- Fix a race with the nonmoving GC (:ghc-ticket:`23170`). + +- A bug in the nonmoving garbage collector regarding the treatment of + zero-length ``SmallArray#``\ s has been fixed (:ghc-ticket:`22264`). + +- A number of bugs regarding the non-moving garbage collector's treatment of + ``Weak#`` pointers have been fixed (:ghc-ticket:`22327`). + +- A few race conditions between the non-moving collector and + ``setNumCapabilities`` which could result in undefined behavior have been + fixed (:ghc-ticket:`22926`, :ghc-ticket:`22927`). + +- The non-moving collector is now able to better schedule marking work during + the post-mark synchronization phase of collection, significantly reducing + pause times in some workloads (:ghc-ticket:`22929`). + +- Various bugs in the non-moving collector's implementation of the selector + optimisation have been fixed (:ghc-ticket:`22930`). + +- Accounting for live bytes is now performed accurately when using the + non-moving GC (:ghc-ticket:`17574`). + +- Allow performing memory inventory with the non-moving GC (:ghc-ticket:`21840`). + +Build system and packaging +-------------------------- + +- Bump ``gmp-tarballs`` to a version which doesn't use the reserved ``x18`` + register on AArch64/Darwin systems, and also has fixes for CVE-2021-43618 + (:ghc-ticket:`22497`, :ghc-ticket:`22789`). + +- Remove quarantine attribute when installing binary distribution on MacOS + (:ghc-ticket:`21506`, :ghc-ticket:`23009`). + +- Fail in the binary distribution ``configure`` script if ``find`` is not + available (:ghc-ticket:`22691`). + +- Install manpages with the binary distribution (:ghc-ticket:`22371`). + +- Fix a bug to do with merging of archives causing GHC to fail to bootstrap + on Windows (:ghc-ticket:`21990`). + +- Hadrian bug fixes to do with building a Windows cross compiler + (:ghc-ticket:`20697`, :ghc-ticket:`22805`). + +- Fix escaping of ``$tooldir`` in the ``configure`` script (:ghc-ticket:`22561`). + +- Allow LLVM 14 and use it for the Windows toolchain (:ghc-ticket:`21964`). + +Core libraries +-------------- + +- Bump ``base`` to 4.17.1.0 + +- base: Remove ``mingwex`` dependency on Windows (:ghc-ticket:`22166`). + +- base: Fix inconsistency with decoding terminal input on Windows (:ghc-ticket:`21488`). + +- Bump ``bytestring`` to 0.11.4.0 + +- Bump``parsec`` to 3.1.16.1 + +- Bump ``text`` to 2.0.2 + +- Bump ``containers`` to 0.6.7 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/release-notes.rst ===================================== @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 1 + 9.4.5-notes 9.4.4-notes 9.4.3-notes 9.4.2-notes ===================================== libraries/base/changelog.md ===================================== @@ -4,7 +4,7 @@ * Remove `mingwex` dependency on Windows (#22166). - * Fix inconcistency with decoding terminal input on Windows (#21488). + * Fix inconsistency with decoding terminal input on Windows (#21488). ## 4.17.0.0 *August 2022* ===================================== rts/sm/NonMoving.c ===================================== @@ -396,7 +396,8 @@ Mutex concurrent_coll_finished_lock; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The nonmoving collector uses an approximate heuristic for reporting live * data quantity. Specifically, during mark we record how much live data we - * find in nonmoving_live_words. At the end of mark we declare this amount to + * find in nonmoving_segment_live_words. At the end of mark this is combined with nonmoving_large_words + * and nonmoving_compact_words, and we declare this amount to * be how much live data we have on in the nonmoving heap (by setting * oldest_gen->live_estimate). * @@ -541,7 +542,7 @@ Mutex concurrent_coll_finished_lock; * */ -memcount nonmoving_live_words = 0; +memcount nonmoving_segment_live_words = 0; // See Note [Sync phase marking budget]. MarkBudget sync_phase_marking_budget = 200000; @@ -683,10 +684,11 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_large_objects); } n_nonmoving_large_blocks += oldest_gen->n_large_blocks; + nonmoving_large_words += oldest_gen->n_large_words; oldest_gen->large_objects = NULL; oldest_gen->n_large_words = 0; oldest_gen->n_large_blocks = 0; - nonmoving_live_words = 0; + nonmoving_segment_live_words = 0; // Clear compact object mark bits for (bdescr *bd = nonmoving_compact_objects; bd; bd = bd->link) { @@ -701,6 +703,7 @@ static void nonmovingPrepareMark(void) dbl_link_onto(bd, &nonmoving_compact_objects); } n_nonmoving_compact_blocks += oldest_gen->n_compact_blocks; + nonmoving_compact_words += oldest_gen->n_compact_blocks * BLOCK_SIZE_W; oldest_gen->n_compact_blocks = 0; oldest_gen->compact_objects = NULL; // TODO (osa): what about "in import" stuff?? @@ -1054,7 +1057,9 @@ concurrent_marking: freeMarkQueue(mark_queue); stgFree(mark_queue); - oldest_gen->live_estimate = nonmoving_live_words; + nonmoving_large_words = countOccupied(nonmoving_marked_large_objects); + nonmoving_compact_words = n_nonmoving_marked_compact_blocks * BLOCK_SIZE_W; + oldest_gen->live_estimate = nonmoving_segment_live_words + nonmoving_large_words + nonmoving_compact_words; oldest_gen->n_old_blocks = 0; resizeGenerations(); ===================================== rts/sm/NonMoving.h ===================================== @@ -120,10 +120,11 @@ struct NonmovingHeap { extern struct NonmovingHeap nonmovingHeap; -extern memcount nonmoving_live_words; +extern memcount nonmoving_segment_live_words; #if defined(THREADED_RTS) extern bool concurrent_coll_running; +extern Mutex nonmoving_collection_mutex; #endif void nonmovingInit(void); ===================================== rts/sm/NonMovingMark.c ===================================== @@ -76,6 +76,10 @@ static bool is_nonmoving_weak(StgWeak *weak); * consequently will trace the pointers of only one object per block. However, * this is okay since the only type of pinned object supported by GHC is the * pinned ByteArray#, which has no pointers. + * + * We need to take care that the stats department is made aware of the amount of + * live large (and compact) objects, since they no longer live on gen[i]->large_objects. + * Failing to do so caused #17574. */ bdescr *nonmoving_large_objects = NULL; @@ -83,6 +87,9 @@ bdescr *nonmoving_marked_large_objects = NULL; memcount n_nonmoving_large_blocks = 0; memcount n_nonmoving_marked_large_blocks = 0; +memcount nonmoving_large_words = 0; +memcount nonmoving_compact_words = 0; + bdescr *nonmoving_compact_objects = NULL; bdescr *nonmoving_marked_compact_objects = NULL; memcount n_nonmoving_compact_blocks = 0; @@ -1736,7 +1743,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) struct NonmovingSegment *seg = nonmovingGetSegment((StgPtr) p); nonmoving_block_idx block_idx = nonmovingGetBlockIdx((StgPtr) p); nonmovingSetMark(seg, block_idx); - nonmoving_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); + nonmoving_segment_live_words += nonmovingSegmentBlockSize(seg) / sizeof(W_); } // If we found a indirection to shortcut keep going. ===================================== rts/sm/NonMovingMark.h ===================================== @@ -127,6 +127,11 @@ extern bdescr *nonmoving_large_objects, *nonmoving_marked_large_objects, extern memcount n_nonmoving_large_blocks, n_nonmoving_marked_large_blocks, n_nonmoving_compact_blocks, n_nonmoving_marked_compact_blocks; +// The size of live large/compact objects in words. +// Only updated at the end of nonmoving GC. +extern memcount nonmoving_large_words, + nonmoving_compact_words; + extern StgTSO *nonmoving_old_threads; extern StgWeak *nonmoving_old_weak_ptr_list; extern StgTSO *nonmoving_threads; ===================================== rts/sm/Sanity.c ===================================== @@ -1206,11 +1206,12 @@ memInventory (bool show) bool leak; #if defined(THREADED_RTS) - // Can't easily do a memory inventory: We might race with the nonmoving - // collector. In principle we could try to take nonmoving_collection_mutex - // and do an inventory if we have it but we don't currently implement this. - if (RtsFlags.GcFlags.useNonmoving) - return; + // We need to be careful not to race with the nonmoving collector. + // If a nonmoving collection is on-going we simply abort the inventory. + if (RtsFlags.GcFlags.useNonmoving){ + if(TRY_ACQUIRE_LOCK(&nonmoving_collection_mutex)) + return; + } #endif // count the blocks we current have @@ -1314,6 +1315,13 @@ memInventory (bool show) } ASSERT(n_alloc_blocks == live_blocks); ASSERT(!leak); + +#if defined(THREADED_RTS) + if (RtsFlags.GcFlags.useNonmoving){ + RELEASE_LOCK(&nonmoving_collection_mutex); + } +#endif + } ===================================== rts/sm/Storage.c ===================================== @@ -42,6 +42,7 @@ #include "GC.h" #include "Evac.h" #include "NonMovingAllocate.h" +#include "sm/NonMovingMark.h" #if defined(ios_HOST_OS) || defined(darwin_HOST_OS) #include "Hash.h" #endif @@ -1615,7 +1616,12 @@ W_ genLiveWords (generation *gen) W_ genLiveBlocks (generation *gen) { - return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks; + W_ nonmoving_blocks = 0; + // The nonmoving heap contains some blocks that live outside the regular generation structure. + if (gen == oldest_gen && RtsFlags.GcFlags.useNonmoving){ + nonmoving_blocks = n_nonmoving_large_blocks + n_nonmoving_marked_large_blocks + n_nonmoving_compact_blocks + n_nonmoving_marked_compact_blocks; + } + return gen->n_blocks + gen->n_large_blocks + gen->n_compact_blocks + nonmoving_blocks; } W_ gcThreadLiveWords (uint32_t i, uint32_t g) @@ -1711,6 +1717,9 @@ StgWord calcTotalLargeObjectsW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_large_words; } + + totalW += nonmoving_large_words; + return totalW; } @@ -1722,6 +1731,9 @@ StgWord calcTotalCompactW (void) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { totalW += generations[g].n_compact_blocks * BLOCK_SIZE_W; } + + totalW += nonmoving_compact_words; + return totalW; } ===================================== testsuite/tests/rts/T17574.hs ===================================== @@ -0,0 +1,40 @@ +-- | Check that large objects are properly accounted for by GHC.Stats +module Main (main) where + +import Control.Monad +import Control.Exception +import Control.Concurrent +import System.Mem +import System.Exit +import GHC.Stats +import GHC.Compact +import Data.List (replicate) + +import qualified Data.ByteString.Char8 as BS + +doGC :: IO () +doGC = do + performMajorGC + threadDelay 1000 -- small delay to allow GC to run when using concurrent gc + +main :: IO () +main = do + let size = 4096*2 + largeString <- evaluate $ BS.replicate size 'A' + compactString <- compact $ replicate size 'A' + doGC + doGC -- run GC twice to make sure the objects end up in the oldest gen + stats <- getRTSStats + let large_obj_bytes = gcdetails_large_objects_bytes $ gc stats + let compact_obj_bytes = gcdetails_compact_bytes $ gc stats + -- assert that large_obj_bytes is at least as big as size + -- this indicates that `largeString` is being accounted for by the stats department + when (large_obj_bytes < fromIntegral size) $ do + putStrLn $ "large_obj_bytes is: " <> show large_obj_bytes <> " but expected at least: " <> show size + exitFailure + when (compact_obj_bytes < fromIntegral size) $ do + putStrLn $ "compact_obj_bytes is: " <> show large_obj_bytes <> " but expected at least: " <> show size + exitFailure + -- keep them alive + print $ BS.length largeString + print $ length $ getCompact compactString ===================================== testsuite/tests/rts/T17574.stdout ===================================== @@ -0,0 +1,2 @@ +8192 +8192 ===================================== testsuite/tests/rts/all.T ===================================== @@ -356,7 +356,7 @@ test('T10904', [ omit_ways(['ghci']), extra_run_opts('20000') ], test('T10728', [extra_run_opts('+RTS -maxN3 -RTS'), only_ways(['threaded2'])], compile_and_run, ['']) -test('T9405', [when(opsys('mingw32'), expect_broken(21361))], makefile_test, ['T9405']) +test('T9405', normal, makefile_test, ['T9405']) test('T11788', when(ghc_dynamic(), skip), makefile_test, ['T11788']) @@ -489,3 +489,5 @@ test('decodeMyStack', normal, compile_and_run, ['-finfo-table-map']) test('decodeMyStack_underflowFrames', [extra_run_opts('+RTS -kc8K -RTS')], compile_and_run, ['-finfo-table-map -rtsopts']) # -finfo-table-map intentionally missing test('decodeMyStack_emptyListForMissingFlag', [ignore_stdout, ignore_stderr], compile_and_run, ['']) + +test('T17574', [], compile_and_run, ['-with-rtsopts -T']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ac1c43dd13a6b515ee8fd0158690949e862b75d...d52ea64e11e86577aecfc3b31dd3dc9aa8465192 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ac1c43dd13a6b515ee8fd0158690949e862b75d...d52ea64e11e86577aecfc3b31dd3dc9aa8465192 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:18:08 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Apr 2023 04:18:08 -0400 Subject: [Git][ghc/ghc][master] rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <64390c406a584_10a80d2eb4e53c495077@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - 1 changed file: - rts/StablePtr.c Changes: ===================================== rts/StablePtr.c ===================================== @@ -98,8 +98,13 @@ */ +// the global stable pointer entry table spEntry *stable_ptr_table = NULL; + +// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after static spEntry *stable_ptr_free = NULL; + +// current stable pointer table size static unsigned int SPT_size = 0; #define INIT_SPT_SIZE 64 @@ -117,6 +122,7 @@ static unsigned int SPT_size = 0; #error unknown SIZEOF_VOID_P #endif +// old stable pointer tables static spEntry *old_SPTs[MAX_N_OLD_SPTS]; static uint32_t n_old_SPTs = 0; @@ -149,8 +155,9 @@ stablePtrUnlock(void) * -------------------------------------------------------------------------- */ STATIC_INLINE void -initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free) +initSpEntryFreeList(spEntry *table, uint32_t n) { + spEntry* free = NULL; spEntry *p; for (p = table + n - 1; p >= table; p--) { p->addr = (P_)free; @@ -166,7 +173,7 @@ initStablePtrTable(void) SPT_size = INIT_SPT_SIZE; stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry), "initStablePtrTable"); - initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL); + initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE); #if defined(THREADED_RTS) initMutex(&stable_ptr_mutex); @@ -181,6 +188,8 @@ initStablePtrTable(void) static void enlargeStablePtrTable(void) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + uint32_t old_SPT_size = SPT_size; spEntry *new_stable_ptr_table; @@ -206,7 +215,8 @@ enlargeStablePtrTable(void) */ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table); - initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); + // add the new entries to the free list + initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size); } /* Note [Enlarging the stable pointer table] @@ -245,6 +255,7 @@ exitStablePtrTable(void) { if (stable_ptr_table) stgFree(stable_ptr_table); + stable_ptr_table = NULL; SPT_size = 0; @@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp) void freeStablePtrUnsafe(StgStablePtr sp) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + // see Note [NULL StgStablePtr] if (sp == NULL) { return; } + StgWord spw = (StgWord)sp - 1; + ASSERT(spw < SPT_size); + freeSpEntry(&stable_ptr_table[spw]); } @@ -278,25 +294,35 @@ void freeStablePtr(StgStablePtr sp) { stablePtrLock(); + freeStablePtrUnsafe(sp); + stablePtrUnlock(); } /* ----------------------------------------------------------------------------- - * Looking up + * Allocating stable pointers * -------------------------------------------------------------------------- */ StgStablePtr getStablePtr(StgPtr p) { - StgWord sp; - stablePtrLock(); - if (!stable_ptr_free) enlargeStablePtrTable(); - sp = stable_ptr_free - stable_ptr_table; - stable_ptr_free = (spEntry*)(stable_ptr_free->addr); - RELAXED_STORE(&stable_ptr_table[sp].addr, p); + + if (!stable_ptr_free) + enlargeStablePtrTable(); + + // find the index of free stable ptr + StgWord sp = stable_ptr_free - stable_ptr_table; + + // unlink the table entry we grabbed from the free list + stable_ptr_free = (spEntry*)(stable_ptr_free->addr); + + // release store to pair with acquire load in deRefStablePtr + RELEASE_STORE(&stable_ptr_table[sp].addr, p); + stablePtrUnlock(); + // see Note [NULL StgStablePtr] sp = sp + 1; return (StgStablePtr)(sp); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a34aa8da1293f997ce9212ccdc2ec56df4a2e9c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a34aa8da1293f997ce9212ccdc2ec56df4a2e9c1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:18:45 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Apr 2023 04:18:45 -0400 Subject: [Git][ghc/ghc][master] docs: Generate docs/index.html with version number Message-ID: <64390c65c2a99_10a80d2eb4e53c4998e2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - 3 changed files: - docs/index.html → docs/index.html.in - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs Changes: ===================================== docs/index.html → docs/index.html.in ===================================== @@ -39,7 +39,7 @@

  • - GHC API + GHC API

    Documentation for the GHC API. ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -193,7 +193,7 @@ buildHtmlDocumentation = do | SphinxHTML `Set.member` doctargets ] need $ map ((root -/-) . pathIndex) targets - copyFileUntracked "docs/index.html" file + copyFile "docs/index.html" file -- | Compile a Sphinx ReStructured Text package to HTML. buildSphinxHtml :: FilePath -> Rules () ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -305,10 +305,10 @@ rtsCabalFlags = mconcat flag = interpolateCabalFlag packageVersions :: Interpolations -packageVersions = foldMap f [ base, ghcPrim, ghc, cabal, templateHaskell, ghcCompact, array ] +packageVersions = foldMap f [ base, ghcPrim, compiler, ghc, cabal, templateHaskell, ghcCompact, array ] where f :: Package -> Interpolations - f pkg = interpolateVar var $ show . version <$> readPackageData pkg + f pkg = interpolateVar var $ version <$> readPackageData pkg where var = "LIBRARY_" <> pkgName pkg <> "_VERSION" templateRule :: FilePath -> Interpolations -> Rules () @@ -335,6 +335,7 @@ templateRules = do templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion templateRule "libraries/prologue.txt" $ packageVersions + templateRule "docs/index.html" $ packageVersions -- Generators View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7a768a415c3bd575a20b20ae9a3953aa5886ed7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7a768a415c3bd575a20b20ae9a3953aa5886ed7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:19:20 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Apr 2023 04:19:20 -0400 Subject: [Git][ghc/ghc][master] Stop if type constructors have kind errors Message-ID: <64390c889a7d7_10a80d2edbac8050312@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 6 changed files: - compiler/GHC/Tc/TyCl.hs - testsuite/tests/dependent/should_fail/T15743c.hs - testsuite/tests/dependent/should_fail/T15743c.stderr - + testsuite/tests/roles/should_fail/T23252.hs - + testsuite/tests/roles/should_fail/T23252.stderr - testsuite/tests/roles/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -248,7 +248,13 @@ tcTyClDecls tyclds kisig_env role_annots = do { -- Step 1: kind-check this group and returns the final -- (possibly-polymorphic) kind of each TyCon and Class -- See Note [Kind checking for type and class decls] - (tc_tycons, kindless) <- kcTyClGroup kisig_env tyclds + (tc_tycons, kindless) <- checkNoErrs $ + kcTyClGroup kisig_env tyclds + -- checkNoErrs: If the TyCons are ill-kinded, stop now. Else we + -- can get follow-on errors. Example: #23252, where the TyCon + -- had an ill-scoped kind forall (d::k) k (a::k). blah + -- and that ill-scoped kind made role inference fall over. + ; traceTc "tcTyAndCl generalized kinds" (vcat (map ppr_tc_tycon tc_tycons)) -- Step 2: type-check all groups together, returning ===================================== testsuite/tests/dependent/should_fail/T15743c.hs ===================================== @@ -8,4 +8,4 @@ import Data.Proxy data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type data T k (c :: k) (a :: Proxy c) b (x :: SimilarKind a b) -data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) + ===================================== testsuite/tests/dependent/should_fail/T15743c.stderr ===================================== @@ -13,18 +13,3 @@ T15743c.hs:10:1: error: (b :: Proxy d) (x :: SimilarKind a b) • In the data type declaration for ‘T’ - -T15743c.hs:11:1: error: - • The kind of ‘T2’ is ill-scoped - Inferred kind: T2 :: forall (d :: k). - forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> - SimilarKind a b -> * - NB: Specified variables (namely: (d :: k)) always come first - Perhaps try this order instead: - k - (d :: k) - (c :: k) - (a :: Proxy c) - (b :: Proxy d) - (x :: SimilarKind a b) - • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/T23252.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE PolyKinds, DataKinds, ExplicitForAll #-} +{-# LANGUAGE RoleAnnotations #-} + +module T15743 where + +import Data.Kind +import Data.Proxy + +data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type + +data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) +type role T2 nominal nominal nominal nominal -- Too few! ===================================== testsuite/tests/roles/should_fail/T23252.stderr ===================================== @@ -0,0 +1,14 @@ +T23252.hs:11:1: error: + • The kind of ‘T2’ is ill-scoped + Inferred kind: T2 :: forall (d :: k). + forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> + SimilarKind a b -> * + NB: Specified variables (namely: (d :: k)) always come first + Perhaps try this order instead: + k + (d :: k) + (c :: k) + (a :: Proxy c) + (b :: Proxy d) + (x :: SimilarKind a b) + • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/all.T ===================================== @@ -8,3 +8,4 @@ test('Roles12', [], makefile_test, []) test('T8773', normal, compile_fail, ['']) test('T9204', [], makefile_test, []) test('RolesIArray', normal, compile_fail, ['']) +test('T23252', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d48fbfea5f7b760ec3d13dd2947257986c095b75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d48fbfea5f7b760ec3d13dd2947257986c095b75 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:37:40 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 14 Apr 2023 04:37:40 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] darwin ci: Explicitly pass desired build triple to configure Message-ID: <643910d4bc17e_10a80d2efeb1085074f0@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: ce47e2c5 by Matthew Pickering at 2023-04-14T14:07:25+05:30 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 1 changed file: - .gitlab/darwin/toolchain.nix Changes: ===================================== .gitlab/darwin/toolchain.nix ===================================== @@ -98,6 +98,6 @@ pkgs.writeTextFile { export CABAL="$CABAL_INSTALL" sdk_path="$(xcrun --sdk macosx --show-sdk-path)" - export CONFIGURE_ARGS="$CONFIGURE_ARGS --with-ffi-libraries=$sdk_path/usr/lib --with-ffi-includes=$sdk_path/usr/include/ffi" + export CONFIGURE_ARGS="$CONFIGURE_ARGS --with-ffi-libraries=$sdk_path/usr/lib --with-ffi-includes=$sdk_path/usr/include/ffi --build=${targetTriple}" ''; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce47e2c5a5cacc7e7a13b0d83f7d335c0b3f14ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce47e2c5a5cacc7e7a13b0d83f7d335c0b3f14ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:39:44 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 14 Apr 2023 04:39:44 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] Store bootstrap_llvm_target and use it to set LlvmTarget in bindists Message-ID: <64391150c4174_10a80d2fa766a4508578@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: baccc79d by Matthew Pickering at 2023-04-14T14:09:29+05:30 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 (cherry picked from commit 64286132cc0db4e227637887f98f5a3ecf7d326a) (cherry picked from commit 48a9e688331fbc2ac91392c654bb7457c5f8a876) - - - - - 3 changed files: - configure.ac - distrib/configure.ac.in - m4/ghc_llvm_target.m4 Changes: ===================================== configure.ac ===================================== @@ -694,6 +694,8 @@ GHC_LLVM_TARGET_SET_VAR # we intend to pass trough --targets to llvm as is. LLVMTarget_CPP=` echo "$LlvmTarget"` AC_SUBST(LLVMTarget_CPP) +# The target is substituted into the distrib/configure.ac file +AC_SUBST(LlvmTarget) dnl ** See whether cc supports --target= and set dnl CONF_CC_OPTS_STAGE[012] accordingly. ===================================== distrib/configure.ac.in ===================================== @@ -18,6 +18,8 @@ dnl-------------------------------------------------------------------- dnl Various things from the source distribution configure bootstrap_target=@TargetPlatform@ +bootstrap_llvm_target=@LlvmTarget@ + TargetHasRTSLinker=@TargetHasRTSLinker@ AC_SUBST(TargetHasRTSLinker) ===================================== m4/ghc_llvm_target.m4 ===================================== @@ -50,5 +50,10 @@ AC_DEFUN([GHC_LLVM_TARGET], [ # require it. AC_DEFUN([GHC_LLVM_TARGET_SET_VAR], [ AC_REQUIRE([FPTOOLS_SET_PLATFORMS_VARS]) - GHC_LLVM_TARGET([$target],[$target_cpu],[$target_vendor],[$target_os],[LlvmTarget]) + if test "$bootstrap_llvm_target" != "" + then + LlvmTarget=$bootstrap_llvm_target + else + GHC_LLVM_TARGET([$target],[$target_cpu],[$target_vendor],[$target_os],[LlvmTarget]) + fi ]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/baccc79d6e96fc7a670b71e2d1c85f47954a6fe4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/baccc79d6e96fc7a670b71e2d1c85f47954a6fe4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:58:11 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 04:58:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t22549 Message-ID: <643915a3a28dc_10a80d2fed4f98521122@gitlab.mail> Matthew Pickering pushed new branch wip/t22549 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t22549 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:58:17 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 14 Apr 2023 04:58:17 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] 11 commits: Allow generation of TTH syntax with TH Message-ID: <643915a9d597e_10a80d2fed0f4c521338@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 82a69424 by Josh Meredith at 2023-04-14T08:57:55+00:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Literal.hs - docs/index.html → docs/index.html.in - docs/users_guide/index.rst - + docs/users_guide/javascript.rst - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - + libraries/base/GHC/JS/Foreign/Callback.hs - libraries/base/GHC/JS/Prim.hs - libraries/base/base.cabal - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Ppr.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - rts/StablePtr.c - testsuite/tests/dependent/should_fail/T15743c.hs - testsuite/tests/dependent/should_fail/T15743c.stderr - testsuite/tests/ghc-api/target-contents/all.T - + testsuite/tests/ghci/should_run/T23229.hs - + testsuite/tests/ghci/should_run/T23229.script - testsuite/tests/ghci/should_run/all.T - testsuite/tests/javascript/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8926212a519458f16122aee72b53223169e65f3...82a694245439e3d463c0ea84402b711472daab63 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8926212a519458f16122aee72b53223169e65f3...82a694245439e3d463c0ea84402b711472daab63 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 08:58:23 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 04:58:23 -0400 Subject: [Git][ghc/ghc][wip/t22549] Transfer DFunId-ness onto specialised bindings Message-ID: <643915afd72a7_10a80d2fed50d85217d4@gitlab.mail> Matthew Pickering pushed to branch wip/t22549 at Glasgow Haskell Compiler / GHC Commits: 7ecb2983 by GHC GitLab CI at 2023-04-14T09:58:15+01:00 Transfer DFunId-ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analysers knows not to apply the `-fstrict-dicts` Fixes #22549 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Specialise.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,11 +48,12 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, setIdDetails ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Error +import GHC.Types.Id.Info import GHC.Utils.Error ( mkMCDiagnostic ) import GHC.Utils.Monad ( foldlM ) @@ -3444,11 +3445,22 @@ newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id newSpecIdSM old_id new_ty join_arity_maybe = do { uniq <- getUniqueM ; let name = idName old_id + details = idDetails old_id new_occ = mkSpecOcc (nameOccName name) new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) `asJoinId_maybe` join_arity_maybe + -- See Note [Transfer DFunId-ness during specialisation] + `transferDFun` details ; return new_id } + +infixl 1 `transferDFun` +transferDFun :: Id -> IdDetails -> Id +transferDFun id id_details = + case id_details of + DFunId {} -> id `setIdDetails` id_details + _ -> id + {- Old (but interesting) stuff about unboxed bindings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3517,4 +3529,20 @@ Answer: When they at the top-level (where it is necessary) or when inlining would duplicate work (or possibly code depending on options). However, the _Lifting will still be eliminated if the strictness analyser deems the lifted binding strict. + +Note [Transfer DFunId-ness during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` +flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does +not apply because the constraint solver can create recursive groups of dictionaries. + +In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. + +The problem was that the specialiser would specialise a DFunId and turn it into a +VanillaId and so the demand analyser didn't know to apply special treatment to the binding +anymore and the whole recursive group was optimised to bottom. + +The solution is to transfer over the DFunId-ness of the binding in the specialiser so +that the demand analysers knows not to apply the `-fstrict-dicts` -} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ecb2983d05c7ff8f45c86fa273875d3cf376f2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ecb2983d05c7ff8f45c86fa273875d3cf376f2e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 09:00:45 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 05:00:45 -0400 Subject: [Git][ghc/ghc][wip/t22549] Transfer DFunId-ness onto specialised bindings Message-ID: <6439163d1706d_10a80d2fed50ec52372b@gitlab.mail> Matthew Pickering pushed to branch wip/t22549 at Glasgow Haskell Compiler / GHC Commits: b30f7c06 by Matthew Pickering at 2023-04-14T10:00:36+01:00 Transfer DFunId-ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analysers knows not to apply the `-fstrict-dicts` Fixes #22549 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Specialise.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,11 +48,12 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, setIdDetails ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Error +import GHC.Types.Id.Info import GHC.Utils.Error ( mkMCDiagnostic ) import GHC.Utils.Monad ( foldlM ) @@ -3444,11 +3445,22 @@ newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id newSpecIdSM old_id new_ty join_arity_maybe = do { uniq <- getUniqueM ; let name = idName old_id + details = idDetails old_id new_occ = mkSpecOcc (nameOccName name) new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) `asJoinId_maybe` join_arity_maybe + -- See Note [Transfer DFunId-ness during specialisation] + `transferDFun` details ; return new_id } + +infixl 1 `transferDFun` +transferDFun :: Id -> IdDetails -> Id +transferDFun id id_details = + case id_details of + DFunId {} -> id `setIdDetails` id_details + _ -> id + {- Old (but interesting) stuff about unboxed bindings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3517,4 +3529,20 @@ Answer: When they at the top-level (where it is necessary) or when inlining would duplicate work (or possibly code depending on options). However, the _Lifting will still be eliminated if the strictness analyser deems the lifted binding strict. + +Note [Transfer DFunId-ness during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` +flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does +not apply because the constraint solver can create recursive groups of dictionaries. + +In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. + +The problem was that the specialiser would specialise a DFunId and turn it into a +VanillaId and so the demand analyser didn't know to apply special treatment to the binding +anymore and the whole recursive group was optimised to bottom. + +The solution is to transfer over the DFunId-ness of the binding in the specialiser so +that the demand analysers knows not to apply the `-fstrict-dicts` -} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b30f7c064ec9ac0b620124100427f3d146a1c146 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b30f7c064ec9ac0b620124100427f3d146a1c146 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 09:58:42 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Apr 2023 05:58:42 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 3 commits: Things Message-ID: <643923d2c2eb1_10a80d31010cf854024f@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: c632f481 by Ben Gamari at 2023-04-13T18:50:32-04:00 Things - - - - - 1bf60a63 by Ben Gamari at 2023-04-14T05:57:48-04:00 rts/IPE: Fix unused mutex warning - - - - - a4106472 by Ben Gamari at 2023-04-14T05:58:23-04:00 rts: Relax info pointer stores - - - - - 8 changed files: - compiler/GHC/Cmm/Info.hs - rts/Apply.cmm - rts/IPE.c - rts/ThreadPaused.c - rts/Updates.h - rts/include/Cmm.h - rts/include/rts/storage/ClosureMacros.h - rts/include/stg/SMP.h Changes: ===================================== compiler/GHC/Cmm/Info.hs ===================================== @@ -450,7 +450,7 @@ wordAligned platform align_check e -- | Takes a closure pointer and returns the info table pointer closureInfoPtr :: Platform -> DoAlignSanitisation -> CmmExpr -> CmmExpr closureInfoPtr platform align_check e = - cmmLoadBWord platform (wordAligned platform align_check e) + CmmMachOp (MO_RelaxedRead (wordWidth platform)) [wordAligned platform align_check e] -- | Takes an info pointer (the first word of a closure) and returns its entry -- code ===================================== rts/Apply.cmm ===================================== @@ -694,7 +694,7 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK") // Can't add StgInd_indirectee(ap) to UpdRemSet here because the old value is // not reachable. %release StgInd_indirectee(ap) = CurrentTSO; - SET_INFO_RELEASE(ap, __stg_EAGER_BLACKHOLE_info); + SET_INFO_RELAXED(ap, __stg_EAGER_BLACKHOLE_info); /* ensure there is at least AP_STACK_SPLIM words of headroom available * after unpacking the AP_STACK. See bug #1466 */ ===================================== rts/IPE.c ===================================== @@ -57,7 +57,6 @@ this all IPE lists of all IpeBufferListNode are traversed to insert all IPEs. After the content of a IpeBufferListNode has been inserted, it's freed. */ -static Mutex ipeMapLock; static HashTable *ipeMap = NULL; // Accessed atomically @@ -65,6 +64,8 @@ static IpeBufferListNode *ipeBufferList = NULL; #if defined(THREADED_RTS) +static Mutex ipeMapLock; + void initIpe(void) { initMutex(&ipeMapLock); } void exitIpe(void) { closeMutex(&ipeMapLock); } ===================================== rts/ThreadPaused.c ===================================== @@ -353,7 +353,7 @@ threadPaused(Capability *cap, StgTSO *tso) // The payload of the BLACKHOLE points to the TSO RELEASE_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso); - SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info); + SET_INFO_RELAXED(bh,&stg_BLACKHOLE_info); // .. and we need a write barrier, since we just mutated the closure: recordClosureMutated(cap,bh); ===================================== rts/Updates.h ===================================== @@ -86,7 +86,7 @@ INLINE_HEADER void updateWithIndirection (Capability *cap, } OVERWRITING_CLOSURE(p1); RELEASE_STORE(&((StgInd *)p1)->indirectee, p2); - SET_INFO_RELEASE(p1, &stg_BLACKHOLE_info); + SET_INFO_RELAXED(p1, &stg_BLACKHOLE_info); LDV_RECORD_CREATE(p1); } ===================================== rts/include/Cmm.h ===================================== @@ -596,6 +596,7 @@ /* Getting/setting the info pointer of a closure */ #define SET_INFO(p,info) StgHeader_info(p) = info #define SET_INFO_RELEASE(p,info) %release StgHeader_info(p) = info +#define SET_INFO_RELAXED(p,info) %relaxed StgHeader_info(p) = info #define GET_INFO(p) StgHeader_info(p) #define GET_INFO_ACQUIRE(p) %acquire GET_INFO(p) ===================================== rts/include/rts/storage/ClosureMacros.h ===================================== @@ -47,6 +47,11 @@ EXTERN_INLINE void SET_INFO(StgClosure *c, const StgInfoTable *info); EXTERN_INLINE void SET_INFO(StgClosure *c, const StgInfoTable *info) { + c->header.info = info; +} + +EXTERN_INLINE void SET_INFO_RELAXED(StgClosure *c, const StgInfoTable *info); +EXTERN_INLINE void SET_INFO_RELAXED(StgClosure *c, const StgInfoTable *info) { RELAXED_STORE(&c->header.info, info); } ===================================== rts/include/stg/SMP.h ===================================== @@ -124,6 +124,47 @@ EXTERN_INLINE void store_load_barrier(void); EXTERN_INLINE void load_load_barrier(void); /* + * Note [C11 memory model] + * ~~~~~~~~~~~~~~~~~~~~~~~ + * When it comes to memory, real multiprocessors provide a wide range of + * concurrency semantics due to out-of-order execution and caching. + * To provide consistent reasoning across architectures, GHC relies the C11 + * memory model. Not only does this provide a well-studied, fairly + * easy-to-understand conceptual model, but the C11 memory model gives us + * access to a number of tools which help us verify the compiler (see Note + * [ThreadSanitizer] in rts/include/rts/TSANUtils.h). + * + * Under the C11 model, each processor can be imagined to have a potentially + * out-of-date view onto the system's memory, which can be manipulated with two + * classes of memory operations: + * + * - non-atomic operations (e.g. loads and stores) operate strictly on the + * processor's local view of memory and consequently may not be visible + * from other processors. + * + * - atomic operations (e.g. load, store, fetch-and-{add,subtract,and,or}, + * exchange, and compare-and-swap) parametrized by ordering semantics. + * + * The ordering semantics of an operation (acquire, release, or sequentially + * consistent) will determine the amount of synchronization the operation + * requires. + * + * A processor may synchronize its + * view of memory with that of another processor by performing an atomic + * memory operation. + * + * While non-atomic operations can be thought of as operating on a local + * + * See also: + * + * - The C11 standard, ISO/IEC 14882 2011. + * + * - Boehm, Adve. "Foundations of the C++ Concurrency Memory Model." + * PLDI '08. + * + * - Batty, Owens, Sarkar, Sewall, Weber. "Mathematizing C++ Concurrency." + * POPL '11. + * * Note [Heap memory barriers] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Machines with weak memory ordering semantics have consequences for how @@ -132,23 +173,32 @@ EXTERN_INLINE void load_load_barrier(void); * stores which formed the new object are visible (e.g. stores are flushed from * cache and the relevant cachelines invalidated in other cores). * - * To ensure this we must use memory barriers. Which barriers are required to - * access a field depends upon the identity of the field. In general, fields come - * in three flavours: + * To ensure this we must issue memory barriers when accessing closures and + * their fields. Since reasoning about concurrent memory access with barriers tends to be + * subtle and platform dependent, it is more common to instead write programs + * in terms of an abstract memory model and let the compiler (GHC and the + * system's C compiler) worry about what barriers are needed to realize the + * requested semantics on the target system. GHC relies on the widely used C11 + * memory model for this; see Note [C11 memory model] for a brief introduction. + * + * Also note that the majority of this Note are only concerned with mutation + * by the mutator. The GC is free to change nearly any field (which is + * necessary for a moving GC). Naturally, doing this safely requires care which + * we discuss in the "Barriers during GC" section below. + * + * Field access + * ------------ + * Which barriers are required to access a field of a closure depends upon the + * identity of the field. In general, fields come in three flavours: * - * * Mutable GC Pointers (C type StgClosure*, Cmm type StgPtr) - * * Immutable GC Pointers (C type MUT_FIELD StgClosure*, Cmm type StgPtr) - * * Non-pointers (C type StgWord, Cmm type StdWord) + * * Mutable GC Pointers (C type `StgClosure*`, Cmm type `StgPtr`) + * * Immutable GC Pointers (C type `MUT_FIELD StgClosure*`, Cmm type `StgPtr`) + * * Non-pointers (C type `StgWord`, Cmm type `StgWord`) * * Note that Addr# fields are *not* GC pointers and therefore are classified * as non-pointers. In this case responsibility for barriers lies with the * party dereferencing the Addr#. * - * Also note that we are only concerned with mutation by the mutator. The GC - * is free to change nearly any field as this is necessary for a moving GC. - * Naturally, doing this safely requires care which we discuss in section - * below. - * * Immutable pointer fields are those which the mutator cannot change after * an object is made visible on the heap. Most objects' fields are of this * flavour (e.g. all data constructor fields). As these fields are written @@ -156,7 +206,7 @@ EXTERN_INLINE void load_load_barrier(void); * safe due to an argument hinging on causality: Consider an immutable field F * of an object O which refers to object O'. Naturally, O' must have been * visible to the creator of O when O was constructed. Consequently, if O is - * visible to a reader, O' must also be visible to the same reader.. + * visible to a reader, O' must also be visible to the same reader. * * Mutable pointer fields are those which can be modified by the mutator. These * require a bit more care as they may break the causality argument given @@ -165,6 +215,10 @@ EXTERN_INLINE void load_load_barrier(void); * into F. Without explicit synchronization O' may not be visible to another * thread attempting to dereference F. * + * To ensure the visibility of the referent, writing to a mutable pointer field + * must be done via a release-store. Conversely, reading from such a field is + * done via an acquire-load. + * * Mutable fields include: * * - StgMutVar: var @@ -180,9 +234,6 @@ EXTERN_INLINE void load_load_barrier(void); * - StgTSO: block_info * - StgInd: indirectee * - * Writing to a mutable pointer field must be done via a release-store. - * Reading from such a field is done via an acquire-load. - * * Finally, non-pointer fields can be safely mutated without barriers as * they do not refer to other memory locations. Technically, concurrent * accesses to non-pointer fields still do need to be atomic in many cases to @@ -217,7 +268,7 @@ EXTERN_INLINE void load_load_barrier(void); * As noted above, thunks are a rather special (yet quite common) case. In * particular, they have the unique property of being updatable (that is, can * be transformed from a thunk into an indirection after evaluation). This - * transformation requires its own synchronization protocol mediating the + * transformation requires its own synchronization protocol to mediate the * interaction between the updater and the reader. In particular, we * must ensure that a reader examining a thunk being updated by another core * can see the indirectee. Consequently, a thunk update (see rts/Updates.h) @@ -357,6 +408,11 @@ EXTERN_INLINE void load_load_barrier(void); * The work-stealing queue (WSDeque) also requires barriers; these are * documented in WSDeque.c. * + * Verifying memory ordering + * ------------------------- + * To verify that GHC's RTS and the code produced by the compiler are free of + * data races. + * */ /* ---------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/589a4dc3c0caac8ffeb6dd260e6e5defacf5e224...a4106472154c2f815129acb6149eab933bdc390c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/589a4dc3c0caac8ffeb6dd260e6e5defacf5e224...a4106472154c2f815129acb6149eab933bdc390c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 10:07:24 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Fri, 14 Apr 2023 06:07:24 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Message-ID: <643925dc81e7_10a80d31449af45433e1@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 08a41807 by Matthew Pickering at 2023-04-14T15:37:06+05:30 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 (cherry picked from commit 926cd4ee097106cf9c6d1ae1fc32375e7fc45ff2) - - - - - 1 changed file: - distrib/configure.ac.in Changes: ===================================== distrib/configure.ac.in ===================================== @@ -167,6 +167,11 @@ FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAG # Stage 3 won't be supported by cross-compilation FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE2],[CONF_GCC_LINKER_OPTS_STAGE2],[CONF_LD_LINKER_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2]) +FP_LD_NO_FIXUP_CHAINS([target], [LDFLAGS]) +FP_LD_NO_FIXUP_CHAINS([build], [CONF_GCC_LINKER_OPTS_STAGE0]) +FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE1]) +FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE2]) + AC_SUBST(CONF_CC_OPTS_STAGE0) AC_SUBST(CONF_CC_OPTS_STAGE1) AC_SUBST(CONF_CC_OPTS_STAGE2) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/08a41807a17e5060f24a2a1e4dcd56aec9800fea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/08a41807a17e5060f24a2a1e4dcd56aec9800fea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 12:04:10 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 08:04:10 -0400 Subject: [Git][ghc/ghc][wip/t22549] Transfer DFunId-ness onto specialised bindings Message-ID: <6439413a9083f_10a80d3332b0bc552129@gitlab.mail> Matthew Pickering pushed to branch wip/t22549 at Glasgow Haskell Compiler / GHC Commits: 1efcc6e4 by Matthew Pickering at 2023-04-14T13:03:59+01:00 Transfer DFunId-ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analysers knows not to apply the `-fstrict-dicts` Fixes #22549 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Specialise.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,11 +48,12 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, setIdDetails ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id import GHC.Types.Error +import GHC.Types.Id.Info import GHC.Utils.Error ( mkMCDiagnostic ) import GHC.Utils.Monad ( foldlM ) @@ -3444,11 +3445,22 @@ newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id newSpecIdSM old_id new_ty join_arity_maybe = do { uniq <- getUniqueM ; let name = idName old_id + details = idDetails old_id new_occ = mkSpecOcc (nameOccName name) new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) `asJoinId_maybe` join_arity_maybe + -- See Note [Transfer DFunId-ness during specialisation] + `transferDFun` details ; return new_id } + +infixl 1 `transferDFun` +transferDFun :: Id -> IdDetails -> Id +transferDFun id id_details = + case id_details of + DFunId {} -> id `setIdDetails` id_details + _ -> id + {- Old (but interesting) stuff about unboxed bindings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3517,4 +3529,28 @@ Answer: When they at the top-level (where it is necessary) or when inlining would duplicate work (or possibly code depending on options). However, the _Lifting will still be eliminated if the strictness analyser deems the lifted binding strict. + +Note [Transfer DFunId-ness during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When creating the binding for a specialisation we need to transfer over the `IdDetails` +of the original binding in the cases that it applies. These are the cases where the +specialisation continues to obey the property and these are relied on by further +passes in the compiler. + +* For join points, the arity may decrease but the specialisation will still be a join point +* For DFunIds, the specialisation is still a DFunId + +In particular, whether a binding is a DFunId or not has consequences for the `-fdicts-strict` +flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does +not apply because the constraint solver can create recursive groups of dictionaries. + +The problem (in #22549) was that the specialiser would specialise a DFunId and turn it into a +VanillaId and so the demand analyser didn't know to apply special treatment to the binding +anymore and the whole recursive group was optimised to bottom. + +The solution is to transfer over the DFunId-ness of the binding in the specialiser so +that the demand analysers knows not to apply the `-fstrict-dicts` + +This problem was discussed in #22549 -} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1efcc6e47c24796f5779573247dd23ff4bcb3178 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1efcc6e47c24796f5779573247dd23ff4bcb3178 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 12:50:10 2023 From: gitlab at gitlab.haskell.org (David (@knothed)) Date: Fri, 14 Apr 2023 08:50:10 -0400 Subject: [Git][ghc/ghc][wip/or-pats-amendment] Prohibit TyApps Message-ID: <64394c02572dd_10a80d342fde405753d8@gitlab.mail> David pushed to branch wip/or-pats-amendment at Glasgow Haskell Compiler / GHC Commits: 80d0af35 by David Knothe at 2023-04-14T14:50:03+02:00 Prohibit TyApps - - - - - 8 changed files: - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Types/Error/Codes.hs Changes: ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -47,6 +47,8 @@ module GHC.Hs.Pat ( collectEvVarsPat, collectEvVarsPats, + patHasTyAppsL, + pprParendLPat, pprConArgs, pprLPat ) where @@ -732,6 +734,7 @@ collectEvVarsPat pat = BangPat _ p -> collectEvVarsLPat p ListPat _ ps -> unionManyBags $ map collectEvVarsLPat ps TuplePat _ ps _ -> unionManyBags $ map collectEvVarsLPat ps + OrPat _ ps -> unionManyBags $ map collectEvVarsLPat ps SumPat _ p _ _ -> collectEvVarsLPat p ConPat { pat_args = args @@ -749,6 +752,29 @@ collectEvVarsPat pat = ExpansionPat _ p -> collectEvVarsPat p _other_pat -> emptyBag +{- +% True if the pattern contains a type application, ignoring nested or-patterns. +-} +patHasTyApps :: Pat GhcPs -> Bool +patHasTyApps pat = + case pat of + LazyPat _ p -> patHasTyAppsL p + AsPat _ _ _ p -> patHasTyAppsL p + ParPat _ _ p _ -> patHasTyAppsL p + BangPat _ p -> patHasTyAppsL p + ListPat _ ps -> any patHasTyAppsL ps + TuplePat _ ps _ -> any patHasTyAppsL ps + OrPat _ _ -> False -- this prohibits redundant error messages + SumPat _ p _ _ -> patHasTyAppsL p + ConPat { pat_args = args } -> case args of + PrefixCon ts ps -> not (null ts) || any patHasTyAppsL ps + RecCon fs -> any (patHasTyAppsL . hfbRHS . unXRec @GhcPs) (rec_flds fs) + InfixCon p1 p2 -> any patHasTyAppsL [p1,p2] + SigPat _ p _ -> patHasTyAppsL p + _other_pat -> False + +patHasTyAppsL :: GenLocated l (Pat GhcPs) -> Bool +patHasTyAppsL = patHasTyApps . unLoc {- ************************************************************************ * * ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1220,7 +1220,7 @@ collect_pat flag pat bndrs = case pat of ListPat _ pats -> foldr (collect_lpat flag) bndrs pats TuplePat _ pats _ -> foldr (collect_lpat flag) bndrs pats -- Evidence binders in an OrPat currently aren't visible outside their - -- binding pattern. This makes error messages more specific. + -- binding pattern. This prohibits redundant error messages. OrPat _ _ -> [] SumPat _ pat _ _ -> collect_lpat flag pat bndrs LitPat _ _ -> bndrs ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -44,6 +44,7 @@ import {-# SOURCE #-} GHC.Rename.Expr ( rnLExpr ) import {-# SOURCE #-} GHC.Rename.Splice ( rnSplicePat ) import GHC.Hs +import GHC.Hs.Pat ( patHasTyAppsL ) import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Zonk ( hsOverLitName ) @@ -612,7 +613,12 @@ rnPatAndThen mk (TuplePat _ pats boxed) rnPatAndThen mk (OrPat _ pats) = do { pats' <- rnLPatsAndThen mk pats - ; return (OrPat noExtField pats') } + ; let orpat :: Pat GhcRn = OrPat noExtField pats' + ; let varBnds = collectPatsBinders CollNoDictBinders pats + -- mapM_ (\(b,i) -> pprTraceM ("bnds " ++ show i) b) (zip (map ppr bnds) [0..]) + ; liftCps $ checkErr (null varBnds) (TcRnOrPatBindsVariables orpat) + ; liftCps $ checkErr (not $ any patHasTyAppsL pats) (TcRnOrPatHasVisibleTyApps orpat) + ; return orpat } rnPatAndThen mk (SumPat _ pat alt arity) = do { pat <- rnLPatAndThen mk pat ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1246,9 +1246,12 @@ instance Diagnostic TcRnMessage where False -> text (TH.pprint item)) TcRnReportCustomQuasiError _ msg -> mkSimpleDecorated $ text msg TcRnInterfaceLookupError _ sdoc -> mkSimpleDecorated sdoc - TcRnOrPatBindsVariables pat vars -> case vars of - True -> mkSimpleDecorated $ text "An or-pattern may not bind (type) variables:" <+> ppr pat - False -> mkSimpleDecorated $ text "An or-pattern may not bind (type) variables nor type class or equality constraints:" <+> ppr pat + TcRnOrPatBindsVariables pat + -> mkSimpleDecorated $ + text "An or-pattern may not bind variables:" <+> ppr pat + TcRnOrPatHasVisibleTyApps pat + -> mkSimpleDecorated $ + text "An or-pattern may not contain visible type applications:" <+> ppr pat TcRnUnsatisfiedMinimalDef mindef -> mkSimpleDecorated $ vcat [text "No explicit implementation for" @@ -2095,6 +2098,8 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnOrPatBindsVariables{} -> ErrorWithoutFlag + TcRnOrPatHasVisibleTyApps{} + -> ErrorWithoutFlag TcRnUnsatisfiedMinimalDef{} -> WarningWithFlag (Opt_WarnMissingMethods) TcRnMisplacedInstSig{} @@ -2673,6 +2678,8 @@ instance Diagnostic TcRnMessage where -> noHints TcRnOrPatBindsVariables{} -> noHints + TcRnOrPatHasVisibleTyApps{} + -> noHints TcRnUnsatisfiedMinimalDef{} -> noHints TcRnMisplacedInstSig{} ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2730,15 +2730,24 @@ data TcRnMessage where -} TcRnInterfaceLookupError :: !Name -> !SDoc -> TcRnMessage - {-| TcRnOrPatBindsVariables is an error that happens when an - or-pattern binds variables or has dictionary or evidence biders, e.g. (one of A, B x). + {-| TcRnOrPatBindsVariables is an error that happens when + a pattern nested in an or-pattern binds variables, e.g. (one of A; B x). Test case: testsuite/tests/typecheck/should_fail/Or3 -} TcRnOrPatBindsVariables - :: Pat GhcTc -- the or-pattern - -> Bool -- True => pattern contains just (type) variables; False => pattern contains other dictionary/evidence binders + :: Pat GhcRn -- the or-pattern + -> TcRnMessage + + {-| TcRnOrPatHasVisibleTyApps is an error that happens when + a pattern nested in an or-pattern uses a visible type application e.g. (one of Just @Int _). + + Test case: + todo + -} + TcRnOrPatHasVisibleTyApps + :: Pat GhcRn -- the or-pattern -> TcRnMessage {- | TcRnUnsatisfiedMinimalDef is a warning that occurs when a class instance ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -402,7 +402,8 @@ tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of ; return (BangPat x pat', res) } OrPat _ pats -> do -- or-patterns with variables are rejected later, after zonking - { (pats', res) <- tc_lpats (map (const pat_ty) pats) penv pats thing_inside + { (pats', (res, pat_ct)) <- tc_lpats (map (const pat_ty) pats) penv pats (captureConstraints thing_inside) + ; emitConstraints pat_ct ; pat_ty <- expTypeToType (scaledThing pat_ty) ; return (OrPat pat_ty pats', res) } ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -1347,14 +1347,7 @@ zonk_pat env (TuplePat tys pats boxed) zonk_pat env p@(OrPat ty pats) = do { ty' <- zonkTcTypeToTypeX env ty ; (env', pats') <- zonkPats env pats - ; checkNoVarsBound pats' p ; return (env', OrPat ty' pats') } - where - checkNoVarsBound :: [LPat GhcTc] -> Pat GhcTc -> TcRn () - checkNoVarsBound pats orpat = do - let bnds = collectPatsBinders CollWithDictBinders pats - let varBnds = collectPatsBinders CollNoDictBinders pats - unless (null bnds) $ addErr (TcRnOrPatBindsVariables orpat (varBnds `equalLength` bnds)) zonk_pat env (SumPat tys pat alt arity ) = do { tys' <- mapM (zonkTcTypeToTypeX env) tys ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -473,6 +473,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnSpecialiseNotVisible" = 85337 GhcDiagnosticCode "TcRnIllegalTypeOperatorDecl" = 50649 GhcDiagnosticCode "TcRnOrPatBindsVariables" = 81303 + GhcDiagnosticCode "TcRnOrPatHasVisibleTyApps" = 28418 GhcDiagnosticCode "TcRnBindVarAlreadyInScope" = 69710 GhcDiagnosticCode "TcRnBindMultipleVariables" = 92957 GhcDiagnosticCode "TcRnIllegalKind" = 64861 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/80d0af35c2f2b469185ec41d233fc5ea919eebd5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/80d0af35c2f2b469185ec41d233fc5ea919eebd5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 13:00:28 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 14 Apr 2023 09:00:28 -0400 Subject: [Git][ghc/ghc][wip/T18927] 2349 commits: Abstract BangOpts Message-ID: <64394e6ccb262_10a80d3454f64457573b@gitlab.mail> Ben Gamari pushed to branch wip/T18927 at Glasgow Haskell Compiler / GHC Commits: 7b0c9384 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Abstract BangOpts Avoid requiring to pass DynFlags to mkDataConRep/buildDataCon. When we load an interface file, these functions don't use the flags. This is preliminary work to decouple the loader from the type-checker for #14335. - - - - - a31ace56 by Sylvain Henry at 2022-01-12T23:25:49-05:00 Untangled GHC.Types.Id.Make from the driver - - - - - 81a8f7a7 by Zubin Duggal at 2022-01-12T23:26:24-05:00 testsuite: Fix import on python 3.10 - - - - - 66831b94 by Ben Gamari at 2022-01-13T14:50:13-05:00 hadrian: Include bash completion script in bindist See #20802. - - - - - be33d61a by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to CPR analysis - - - - - c2a6c3eb by Sebastian Graf at 2022-01-13T14:50:49-05:00 release notes: Changes to Demand analysis - - - - - 9ccc445a by Eric Lindblad at 2022-01-14T10:35:46-05:00 add NUMJOBS - - - - - 564b89ae by Eric Lindblad at 2022-01-14T10:35:46-05:00 Revert "add NUMJOBS" This reverts commit c0b854e929f82c680530e944e12fad24f9e14f8e - - - - - 2dfc268c by Eric Lindblad at 2022-01-14T10:35:46-05:00 update URLs - - - - - 1aace894 by Eric Lindblad at 2022-01-14T10:35:46-05:00 reinsert target - - - - - 52a4f5ab by Andreas Klebinger at 2022-01-14T10:36:21-05:00 Add test for #20938. - - - - - e2b60be8 by Ben Gamari at 2022-01-15T03:41:16-05:00 rts: Consolidate RtsSymbols from libc Previously (9ebda74ec5331911881d734b21fbb31c00a0a22f) `environ` was added to `RtsSymbols` to ensure that environment was correctly propagated when statically linking. However, this introduced #20577 since platforms are inconsistent in whether they provide a prototype for `environ`. I fixed this by providing a prototype but while doing so dropped symbol-table entry, presumably thinking that it was redundant due to the entry in the mingw-specific table. Here I reintroduce the symbol table entry for `environ` and move libc symbols shared by Windows and Linux into a new macro, `RTS_LIBC_SYMBOLS`, avoiding this potential confusion. - - - - - 0dc72395 by Tamar Christina at 2022-01-15T03:41:55-05:00 winio: fix heap corruption and various leaks. - - - - - 4031ef62 by Eric Lindblad at 2022-01-15T20:11:55+00:00 wikipedia link - - - - - a13aff98 by Eric Lindblad at 2022-01-17T08:25:51-05:00 ms link - - - - - f161e890 by sheaf at 2022-01-17T14:52:50+00:00 Use diagnostic infrastructure in GHC.Tc.Errors - - - - - 18c797b8 by Jens Petersen at 2022-01-18T16:12:14-05:00 hadrian BinaryDist: version ghc in ghciScriptWrapper like we do for the non-Hadrian wrapper script. Otherwise if $bindir/ghc is a different ghc version then versioned ghci will incorrectly run the other ghc version instead. (Normally this would only happen if there are parallel ghc versions installed in bindir.) All the other wrapper scripts already have versioned executablename - - - - - 310424d0 by Matthew Pickering at 2022-01-18T16:12:50-05:00 Correct type of static forms in hsExprType The simplest way to do this seemed to be to persist the whole type in the extension field from the typechecker so that the few relevant places * Desugaring can work out the return type by splitting this type rather than calling `dsExpr` (slightly more efficient). * hsExprType can just return the correct type. * Zonking has to now zonk the type as well The other option we considered was wiring in StaticPtr but that is actually quite tricky because StaticPtr refers to StaticPtrInfo which has field selectors (which we can't easily wire in). Fixes #20150 - - - - - 7ec783de by Matthew Pickering at 2022-01-18T16:12:50-05:00 Add test for using type families with static pointers Issue was reported on #13306 - - - - - 2d205154 by Sebastian Graf at 2022-01-18T16:13:25-05:00 Stricten the Strict State monad I found it weird that most of the combinators weren't actually strict. Making `pure` strict in the state should hopefully give Nested CPR an easier time to unbox the nested state. - - - - - 5a6efd21 by Ben Gamari at 2022-01-18T16:14:01-05:00 rts/winio: Fix #18382 Here we refactor WinIO's IO completion scheme, squashing a memory leak and fixing #18382. To fix #18382 we drop the special thread status introduced for IoPort blocking, BlockedOnIoCompletion, as well as drop the non-threaded RTS's special dead-lock detection logic (which is redundant to the GC's deadlock detection logic), as proposed in #20947. Previously WinIO relied on foreign import ccall "wrapper" to create an adjustor thunk which can be attached to the OVERLAPPED structure passed to the operating system. It would then use foreign import ccall "dynamic" to back out the original continuation from the adjustor. This roundtrip is significantly more expensive than the alternative, using a StablePtr. Furthermore, the implementation let the adjustor leak, meaning that every IO request would leak a page of memory. Fixes T18382. - - - - - 01254ceb by Matthew Pickering at 2022-01-18T16:14:37-05:00 Add note about heap invariant Closed #20904 - - - - - 21510698 by Sergey Vinokurov at 2022-01-18T16:15:12-05:00 Improve detection of lld linker Newer lld versions may include vendor info in --version output and thus the version string may not start with ‘LLD’. Fixes #20907 - - - - - 95e7964b by Peter Trommler at 2022-01-18T20:46:08-05:00 Fix T20638 on big-endian architectures The test reads a 16 bit value from an array of 8 bit values. Naturally, that leads to different values read on big-endian architectures than on little-endian. In this case the value read is 0x8081 on big-endian and 0x8180 on little endian. This patch changes the argument of the `and` machop to mask bit 7 which is the only bit different. The test still checks that bit 15 is zero, which was the original issue in #20638. Fixes #20906. - - - - - fd0019a0 by Eric Lindblad at 2022-01-18T20:46:48-05:00 ms and gh links - - - - - 85dc61ee by Zubin Duggal at 2022-01-18T20:47:23-05:00 ci: Fix subtlety with not taking effect because of time_it (#20898) - - - - - 592e4113 by Anselm Schüler at 2022-01-19T13:31:49-05:00 Note that ImpredicativeTypes doesn’t allow polymorphic instances See #20939 - - - - - 3b009e1a by Ben Gamari at 2022-01-19T13:32:25-05:00 base: Add CTYPE pragmas to all foreign types Fixes #15531 by ensuring that we know the corresponding C type for all marshalling wrappers. Closes #15531. - - - - - 516eeb9e by Robert Hensing at 2022-01-24T21:28:24-05:00 Add -fcompact-unwind This gives users the choice to enable __compact_unwind sections when linking. These were previously hardcoded to be removed. This can be used to solved the problem "C++ does not catch exceptions when used with Haskell-main and linked by ghc", https://gitlab.haskell.org/ghc/ghc/-/issues/11829 It does not change the default behavior, because I can not estimate the impact this would have. When Apple first introduced the compact unwind ABI, a number of open source projects have taken the easy route of disabling it, avoiding errors or even just warnings shortly after its introduction. Since then, about a decade has passed, so it seems quite possible that Apple itself, and presumably many programs with it, have successfully switched to the new format, to the point where the old __eh_frame section support is in disrepair. Perhaps we should get along with the program, but for now we can test the waters with this flag, and use it to fix packages that need it. - - - - - 5262b1e5 by Robert Hensing at 2022-01-24T21:28:24-05:00 Add test case for C++ exception handling - - - - - a5c94092 by Sebastian Graf at 2022-01-24T21:29:00-05:00 Write Note [Strict State monad] to explain what G.U.M.State.Strict does As requested by Simon after review of !7342. I also took liberty to define the `Functor` instance by hand, as the derived one subverts the invariants maintained by the pattern synonym (as already stated in `Note [The one-shot state monad trick]`). - - - - - 9b0d56d3 by Eric Lindblad at 2022-01-24T21:29:38-05:00 links - - - - - 4eac8e72 by Ben Gamari at 2022-01-24T21:30:13-05:00 ghc-heap: Drop mention of BlockedOnIOCompletion Fixes bootstrap with GHC 9.0 after 5a6efd218734dbb5c1350531680cd3f4177690f1 - - - - - 7d7b9a01 by Ryan Scott at 2022-01-24T21:30:49-05:00 Hadrian: update the index-state to allow building with GHC 9.0.2 Fixes #20984. - - - - - aa50e118 by Peter Trommler at 2022-01-24T21:31:25-05:00 testsuite: Mark test that require RTS linker - - - - - 871ce2a3 by Matthew Pickering at 2022-01-25T17:27:30-05:00 ci: Move (most) deb9 jobs to deb10 deb9 is now end-of-life so we are dropping support for producing bindists. - - - - - 9d478d51 by Ryan Scott at 2022-01-25T17:28:06-05:00 DeriveGeneric: look up datacon fixities using getDataConFixityFun Previously, `DeriveGeneric` would look up the fixity of a data constructor using `getFixityEnv`, but this is subtly incorrect for data constructors defined in external modules. This sort of situation can happen with `StandaloneDeriving`, as noticed in #20994. In fact, the same bug has occurred in the past in #9830, and while that bug was fixed for `deriving Read` and `deriving Show`, the fix was never extended to `DeriveGeneric` due to an oversight. This patch corrects that oversight. Fixes #20994. - - - - - 112e9e9e by Zubin Duggal at 2022-01-25T17:28:41-05:00 Fix Werror on alpine - - - - - 781323a3 by Matthew Pickering at 2022-01-25T17:29:17-05:00 Widen T12545 acceptance window This test has been the scourge of contributors for a long time. It has caused many failed CI runs and wasted hours debugging a test which barely does anything. The fact is does nothing is the reason for the flakiness and it's very sensitive to small changes in initialisation costs, in particular adding wired-in things can cause this test to fluctuate quite a bit. Therefore we admit defeat and just bump the threshold up to 10% to catch very large regressions but otherwise don't care what this test does. Fixes #19414 - - - - - e471a680 by sheaf at 2022-01-26T12:01:45-05:00 Levity-polymorphic arrays and mutable variables This patch makes the following types levity-polymorphic in their last argument: - Array# a, SmallArray# a, Weak# b, StablePtr# a, StableName# a - MutableArray# s a, SmallMutableArray# s a, MutVar# s a, TVar# s a, MVar# s a, IOPort# s a The corresponding primops are also made levity-polymorphic, e.g. `newArray#`, `readArray#`, `writeMutVar#`, `writeIOPort#`, etc. Additionally, exception handling functions such as `catch#`, `raise#`, `maskAsyncExceptions#`,... are made levity/representation-polymorphic. Now that Array# and MutableArray# also work with unlifted types, we can simply re-define ArrayArray# and MutableArrayArray# in terms of them. This means that ArrayArray# and MutableArrayArray# are no longer primitive types, but simply unlifted newtypes around Array# and MutableArrayArray#. This completes the implementation of the Pointer Rep proposal https://github.com/ghc-proposals/ghc-proposals/pull/203 Fixes #20911 ------------------------- Metric Increase: T12545 ------------------------- ------------------------- Metric Decrease: T12545 ------------------------- - - - - - 6e94ba54 by Andreas Klebinger at 2022-01-26T12:02:21-05:00 CorePrep: Don't try to wrap partial applications of primops in profiling ticks. This fixes #20938. - - - - - b55d7db3 by sheaf at 2022-01-26T12:03:01-05:00 Ensure that order of instances doesn't matter The insert_overlapping used in lookupInstEnv used to return different results depending on the order in which instances were processed. The problem was that we could end up discarding an overlapping instance in favour of a more specific non-overlapping instance. This is a problem because, even though we won't choose the less-specific instance for matching, it is still useful for pruning away other instances, because it has the overlapping flag set while the new instance doesn't. In insert_overlapping, we now keep a list of "guard" instances, which are instances which are less-specific that one that matches (and hence which we will discard in the end), but want to keep around solely for the purpose of eliminating other instances. Fixes #20946 - - - - - 61f62062 by sheaf at 2022-01-26T12:03:40-05:00 Remove redundant SOURCE import in FitTypes Fixes #20995 - - - - - e8405829 by sheaf at 2022-01-26T12:04:15-05:00 Fix haddock markup in GHC.Tc.Errors.Types - - - - - 590a2918 by Simon Peyton Jones at 2022-01-26T19:45:22-05:00 Make RULE matching insensitive to eta-expansion This patch fixes #19790 by making the rule matcher do on-the-fly eta reduction. See Note [Eta reduction the target] in GHC.Core.Rules I found I also had to careful about casts when matching; see Note [Casts in the target] and Note [Casts in the template] Lots more comments and Notes in the rule matcher - - - - - c61ac4d8 by Matthew Pickering at 2022-01-26T19:45:58-05:00 alwaysRerun generation of ghcconfig This file needs to match exactly what is passed as the testCompiler. Before this change the settings for the first compiler to be tested woudl be stored and not regenerated if --test-compiler changed. - - - - - b5132f86 by Matthew Pickering at 2022-01-26T19:45:58-05:00 Pass config.stage argument to testsuite - - - - - 83d3ad31 by Zubin Duggal at 2022-01-26T19:45:58-05:00 hadrian: Allow testing of the stage1 compiler (#20755) - - - - - a5924b38 by Joachim Breitner at 2022-01-26T19:46:34-05:00 Simplifier: Do the right thing if doFloatFromRhs = False If `doFloatFromRhs` is `False` then the result from `prepareBinding` should not be used. Previously it was in ways that are silly (but not completly wrong, as the simplifier would clean that up again, so no test case). This was spotted by Simon during a phone call. Fixes #20976 - - - - - ce488c2b by Simon Peyton Jones at 2022-01-26T19:47:09-05:00 Better occurrence analysis with casts This patch addresses #20988 by refactoring the way the occurrence analyser deals with lambdas. Previously it used collectBinders to split off a group of binders, and deal with them together. Now I deal with them one at a time in occAnalLam, which allows me to skip casts easily. See Note [Occurrence analysis for lambda binders] about "lambda-groups" This avoidance of splitting out a list of binders has some good consequences. Less code, more efficient, and I think, more clear. The Simplifier needed a similar change, now that lambda-groups can inlude casts. It turned out that I could simplify the code here too, in particular elminating the sm_bndrs field of StrictBind. Simpler, more efficient. Compile-time metrics improve slightly; here are the ones that are +/- 0.5% or greater: Baseline Test Metric value New value Change -------------------------------------------------------------------- T11303b(normal) ghc/alloc 40,736,702 40,543,992 -0.5% T12425(optasm) ghc/alloc 90,443,459 90,034,104 -0.5% T14683(normal) ghc/alloc 2,991,496,696 2,956,277,288 -1.2% T16875(normal) ghc/alloc 34,937,866 34,739,328 -0.6% T17977b(normal) ghc/alloc 37,908,550 37,709,096 -0.5% T20261(normal) ghc/alloc 621,154,237 618,312,480 -0.5% T3064(normal) ghc/alloc 190,832,320 189,952,312 -0.5% T3294(normal) ghc/alloc 1,604,674,178 1,604,608,264 -0.0% T5321FD(normal) ghc/alloc 270,540,489 251,888,480 -6.9% GOOD T5321Fun(normal) ghc/alloc 300,707,814 281,856,200 -6.3% GOOD WWRec(normal) ghc/alloc 588,460,916 585,536,400 -0.5% geo. mean -0.3% Metric Decrease: T5321FD T5321Fun - - - - - 4007905d by Roland Senn at 2022-01-26T19:47:47-05:00 Cleanup tests in directory ghci.debugger. Fixes #21009 * Remove wrong comment about panic in `break003.script`. * Improve test `break008`. * Add test `break028` to `all.T` * Fix wrong comments in `print019.script`, `print026.script` and `result001.script`. * Remove wrong comments from `print024.script` and `print031.script`. * Replace old module name with current name in `print035.script`. - - - - - 3577defb by Matthew Pickering at 2022-01-26T19:48:22-05:00 ci: Move source-tarball and test-bootstrap into full-build - - - - - 6e09b3cf by Matthew Pickering at 2022-01-27T02:39:35-05:00 ci: Add ENABLE_NUMA flag to explicitly turn on libnuma dependency In recent releases a libnuma dependency has snuck into our bindists because the images have started to contain libnuma. We now explicitly pass `--disable-numa` to configure unless explicitly told not to by using the `ENABLE_NUMA` environment variable. So this is tested, there is one random validate job which builds with --enable-numa so that the code in the RTS is still built. Fixes #20957 and #15444 - - - - - f4ce4186 by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Improve partial signatures As #20921 showed, with partial signatures, it is helpful to use the same algorithm (namely findInferredDiff) for * picking the constraints to retain for the /group/ in Solver.decideQuantification * picking the contraints to retain for the /individual function/ in Bind.chooseInferredQuantifiers This is still regrettably declicate, but it's a step forward. - - - - - 0573aeab by Simon Peyton Jones at 2022-01-27T02:40:11-05:00 Add an Outputable instance for RecTcChecker - - - - - f0adea14 by Ryan Scott at 2022-01-27T02:40:47-05:00 Expand type synonyms in markNominal `markNominal` is repsonsible for setting the roles of type variables that appear underneath an `AppTy` to be nominal. However, `markNominal` previously did not expand type synonyms, so in a data type like this: ```hs data M f a = MkM (f (T a)) type T a = Int ``` The `a` in `M f a` would be marked nominal, even though `T a` would simply expand to `Int`. The fix is simple: call `coreView` as appropriate in `markNominal`. This is much like the fix for #14101, but in a different spot. Fixes #20999. - - - - - 18df4013 by Simon Peyton Jones at 2022-01-27T08:22:30-05:00 Define and use restoreLclEnv This fixes #20981. See Note [restoreLclEnv vs setLclEnv] in GHC.Tc.Utils.Monad. I also use updLclEnv rather than get/set when I can, because it's then much clearer that it's an update rather than an entirely new TcLclEnv coming from who-knows-where. - - - - - 31088dd3 by David Feuer at 2022-01-27T08:23:05-05:00 Add test supplied in T20996 which uses data family result kind polymorphism David (@treeowl) writes: > Following @kcsongor, I've used ridiculous data family result kind > polymorphism in `linear-generics`, and am currently working on getting > it into `staged-gg`. If it should be removed, I'd appreciate a heads up, > and I imagine Csongor would too. > > What do I need by ridiculous polymorphic result kinds? Currently, data > families are allowed to have result kinds that end in `Type` (or maybe > `TYPE r`? I'm not sure), but not in concrete data kinds. However, they > *are* allowed to have polymorphic result kinds. This leads to things I > think most of us find at least quite *weird*. For example, I can write > > ```haskell > data family Silly :: k > data SBool :: Bool -> Type where > SFalse :: SBool False > STrue :: SBool True > SSSilly :: SBool Silly > type KnownBool b where > kb :: SBool b > instance KnownBool False where kb = SFalse > instance KnownBool True where kb = STrue > instance KnownBool Silly where kb = Silly > ``` > > Basically, every kind now has potentially infinitely many "legit" inhabitants. > > As horrible as that is, it's rather useful for GHC's current native > generics system. It's possible to use these absurdly polymorphic result > kinds to probe the structure of generic representations in a relatively > pleasant manner. It's a sort of "formal type application" reminiscent of > the notion of a formal power series (see the test case below). I suspect > a system more like `kind-generics` wouldn't need this extra probing > power, but nothing like that is natively available as yet. > > If the ridiculous result kind polymorphism is banished, we'll still be > able to do what we need as long as we have stuck type families. It's > just rather less ergonomical: a stuck type family has to be used with a > concrete marker type argument. Closes #20996 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 8fd2ac25 by Andreas Abel at 2022-01-27T18:34:54-05:00 Whitespace only - - - - - 7a854743 by Andreas Abel at 2022-01-27T18:34:54-05:00 Ctd. #18087: complete :since: info for all warnings in users guide Some warnings have been there "forever" and I could not trace back the exact genesis, so I wrote "since at least 5.04". The flag `helpful-errors` could have been added in 7.2 already. I wrote 7.4 since I have no 7.2 available and it is not recognized by 7.0. - - - - - f75411e8 by Andreas Abel at 2022-01-27T18:34:54-05:00 Re #18087 user's guide: add a note that -Wxxx used to be -fwarn-xxx The warning option syntax -W was introduced in GHC 8. The note should clarify what e.g. "since 7.6" means in connection with "-Wxxx": That "-fwarn-xxx" was introduced in 7.6.1. [ci skip] - - - - - 3cae7fde by Peter Trommler at 2022-01-27T18:35:30-05:00 testsuite: Fix AtomicPrimops test on big endian - - - - - 6cc6080c by Ben Gamari at 2022-01-27T18:36:05-05:00 users-guide: Document GHC_CHARENC environment variable As noted in #20963, this was introduced in 1b56c40578374a15b4a2593895710c68b0e2a717 but was no documentation was added at that point. Closes #20963. - - - - - ee21e2de by Ben Gamari at 2022-01-27T18:36:41-05:00 rts: Clean up RTS flags usage message Align flag descriptions and acknowledge that some flags may not be available unless the user linked with `-rtsopts` (as noted in #20961). Fixes #20961. - - - - - 7f8ce19e by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Fix getHasGivenEqs The second component is supposed to be "insoluble equalities arising from givens". But we were getting wanteds too; and that led to an outright duplication of constraints. It's not harmful, but it's not right either. I came across this when debugging something else. Easily fixed. - - - - - f9ef2d26 by Simon Peyton Jones at 2022-01-27T18:37:17-05:00 Set the TcLclEnv when solving a ForAll constraint Fix a simple omission in GHC.Tc.Solver.Canonical.solveForAll, where we ended up with the wrong TcLclEnv captured in an implication. Result: unhelpful error message (#21006) - - - - - bc6ba8ef by Sylvain Henry at 2022-01-28T12:14:41-05:00 Make most shifts branchless - - - - - 62a6d037 by Simon Peyton Jones at 2022-01-28T12:15:17-05:00 Improve boxity in deferAfterPreciseException As #20746 showed, the demand analyser behaved badly in a key I/O library (`GHC.IO.Handle.Text`), by unnessarily boxing and reboxing. This patch adjusts the subtle function deferAfterPreciseException; it's quite easy, just a bit subtle. See the new Note [deferAfterPreciseException] And this MR deals only with Problem 2 in #20746. Problem 1 is still open. - - - - - 42c47cd6 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/trace: Shrink tracing flags - - - - - cee66e71 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/EventLog: Mark various internal globals as static - - - - - 6b0cea29 by Ben Gamari at 2022-01-29T02:40:45-05:00 Propagate PythonCmd to make build system - - - - - 2e29edb7 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts: Refactor event types Previously we would build the eventTypes array at runtime during RTS initialization. However, this is completely unnecessary; it is completely static data. - - - - - bb15c347 by Ben Gamari at 2022-01-29T02:40:45-05:00 rts/eventlog: Ensure that flushCount is initialized - - - - - 268efcc9 by Matthew Pickering at 2022-01-29T02:41:21-05:00 Rework the handling of SkolemInfo The main purpose of this patch is to attach a SkolemInfo directly to each SkolemTv. This fixes the large number of bugs which have accumulated over the years where we failed to report errors due to having "no skolem info" for particular type variables. Now the origin of each type varible is stored on the type variable we can always report accurately where it cames from. Fixes #20969 #20732 #20680 #19482 #20232 #19752 #10946 #19760 #20063 #13499 #14040 The main changes of this patch are: * SkolemTv now contains a SkolemInfo field which tells us how the SkolemTv was created. Used when reporting errors. * Enforce invariants relating the SkolemInfoAnon and level of an implication (ic_info, ic_tclvl) to the SkolemInfo and level of the type variables in ic_skols. * All ic_skols are TcTyVars -- Check is currently disabled * All ic_skols are SkolemTv * The tv_lvl of the ic_skols agrees with the ic_tclvl * The ic_info agrees with the SkolInfo of the implication. These invariants are checked by a debug compiler by checkImplicationInvariants. * Completely refactor kcCheckDeclHeader_sig which kept doing my head in. Plus, it wasn't right because it wasn't skolemising the binders as it decomposed the kind signature. The new story is described in Note [kcCheckDeclHeader_sig]. The code is considerably shorter than before (roughly 240 lines turns into 150 lines). It still has the same awkward complexity around computing arity as before, but that is a language design issue. See Note [Arity inference in kcCheckDeclHeader_sig] * I added new type synonyms MonoTcTyCon and PolyTcTyCon, and used them to be clear which TcTyCons have "finished" kinds etc, and which are monomorphic. See Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon] * I renamed etaExpandAlgTyCon to splitTyConKind, becuase that's a better name, and it is very useful in kcCheckDeclHeader_sig, where eta-expansion isn't an issue. * Kill off the nasty `ClassScopedTvEnv` entirely. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 0a1d0944 by Ben Gamari at 2022-01-29T14:52:55-05:00 Drop SPARC NCG - - - - - 313afb3d by Ben Gamari at 2022-01-29T14:52:56-05:00 A few comment cleanups - - - - - d85a527f by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out SPARC register support - - - - - c6bede69 by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Rip out SPARC support - - - - - a67c2471 by Ben Gamari at 2022-01-29T14:52:56-05:00 Rip out remaining SPARC support - - - - - 5771b690 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop RegPair SPARC was its last and only user. - - - - - 512ed3f1 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Make RealReg a newtype Now that RegPair is gone we no longer need to pay for the additional box. - - - - - 88fea6aa by Ben Gamari at 2022-01-29T14:52:56-05:00 rts: Drop redundant #include <Arena.h> - - - - - ea2a4034 by Ben Gamari at 2022-01-29T14:52:56-05:00 CmmToAsm: Drop ncgExpandTop This was only needed for SPARC's synthetic instructions. - - - - - 88fce740 by Ben Gamari at 2022-01-29T14:54:04-05:00 rel-notes: Note dropping of SPARC support - - - - - eb956cf1 by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Force-enable caret diagnostics in T17786 Otherwise GHC realizes that it's not attached to a proper tty and will disable caret diagnostics. - - - - - d07799ab by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite: Make T7275 more robust against CCid changes The cost-center numbers are somewhat unstable; normalise them out. - - - - - c76c8050 by Ben Gamari at 2022-01-30T06:27:19-05:00 rts: Don't allocate closurePtrs# pointers on C stack Previously `closurePtrs#` would allocate an aray of the size of the closure being decoded on the C stack. This was ripe for overflowing the C stack overflow. This resulted in `T12492` failing on Windows. - - - - - 3af95f7a by Ben Gamari at 2022-01-30T06:27:19-05:00 testsuite/T4029: Don't depend on echo On Windows the `cmd.exe` shell may be used to execute the command, which will print `ECHO is on.` instead of a newline if you give it no argument. Avoid this by rather using `printf`. - - - - - 3531c478 by Ben Gamari at 2022-01-30T06:27:19-05:00 Use PATH_FMT instead of %s to format `pathchar *` A few %s occurrences have snuck in over the past months. - - - - - ee5c4f9d by Zubin Duggal at 2022-01-31T16:51:55+05:30 Improve migration strategy for the XDG compliance change to the GHC application directory. We want to always use the old path (~/.ghc/..) if it exists. But we never want to create the old path. This ensures that the migration can eventually be completed once older GHC versions are no longer in circulation. Fixes #20684, #20669, #20660 - - - - - 60a54a8f by doyougnu at 2022-01-31T18:46:11-05:00 StgToCmm: decouple DynFlags, add StgToCmmConfig StgToCmm: add Config, remove CgInfoDownwards StgToCmm: runC api change to take StgToCmmConfig StgToCmm: CgInfoDownad -> StgToCmmConfig StgToCmm.Monad: update getters/setters/withers StgToCmm: remove CallOpts in StgToCmm.Closure StgToCmm: remove dynflag references StgToCmm: PtrOpts removed StgToCmm: add TMap to config, Prof - dynflags StgToCmm: add omit yields to config StgToCmm.ExtCode: remove redundant import StgToCmm.Heap: remove references to dynflags StgToCmm: codeGen api change, DynFlags -> Config StgToCmm: remove dynflags in Env and StgToCmm StgToCmm.DataCon: remove dynflags references StgToCmm: remove dynflag references in DataCon StgToCmm: add backend avx flags to config StgToCmm.Prim: remove dynflag references StgToCmm.Expr: remove dynflag references StgToCmm.Bind: remove references to dynflags StgToCmm: move DoAlignSanitisation to Cmm.Type StgToCmm: remove PtrOpts in Cmm.Parser.y DynFlags: update ipInitCode api StgToCmm: Config Module is single source of truth StgToCmm: Lazy config breaks IORef deadlock testsuite: bump countdeps threshold StgToCmm.Config: strictify fields except UpdFrame Strictifying UpdFrameOffset causes the RTS build with stage1 to deadlock. Additionally, before the deadlock performance of the RTS is noticeably slower. StgToCmm.Config: add field descriptions StgToCmm: revert strictify on Module in config testsuite: update CountDeps tests StgToCmm: update comment, fix exports Specifically update comment about loopification passed into dynflags then stored into stgToCmmConfig. And remove getDynFlags from Monad.hs exports Types.Name: add pprFullName function StgToCmm.Ticky: use pprFullname, fixup ExtCode imports Cmm.Info: revert cmmGetClosureType removal StgToCmm.Bind: use pprFullName, Config update comments StgToCmm: update closureDescription api StgToCmm: SAT altHeapCheck StgToCmm: default render for Info table, ticky Use default rendering contexts for info table and ticky ticky, which should be independent of command line input. testsuite: bump count deps pprFullName: flag for ticky vs normal style output convertInfoProvMap: remove unused parameter StgToCmm.Config: add backend flags to config StgToCmm.Config: remove Backend from Config StgToCmm.Prim: refactor Backend call sites StgToCmm.Prim: remove redundant imports StgToCmm.Config: refactor vec compatibility check StgToCmm.Config: add allowQuotRem2 flag StgToCmm.Ticky: print internal names with parens StgToCmm.Bind: dispatch ppr based on externality StgToCmm: Add pprTickyname, Fix ticky naming Accidently removed the ctx for ticky SDoc output. The only relevant flag is sdocPprDebug which was accidental set to False due to using defaultSDocContext without altering the flag. StgToCmm: remove stateful fields in config fixup: config: remove redundant imports StgToCmm: move Sequel type to its own module StgToCmm: proliferate getCallMethod updated api StgToCmm.Monad: add FCodeState to Monad Api StgToCmm: add second reader monad to FCode fixup: Prim.hs: missed a merge conflict fixup: Match countDeps tests to HEAD StgToCmm.Monad: withState -> withCgState To disambiguate it from mtl withState. This withState shouldn't be returning the new state as a value. However, fixing this means tackling the knot tying in CgState and so is very difficult since it changes when the thunk of the knot is forced which either leads to deadlock or to compiler panic. - - - - - 58eccdbc by Ben Gamari at 2022-01-31T18:46:47-05:00 codeGen: Fix two buglets in -fbounds-check logic @Bodigrim noticed that the `compareByteArray#` bounds-checking logic had flipped arguments and an off-by-one. For the sake of clarity I also refactored occurrences of `cmmOffset` to rather use `cmmOffsetB`. I suspect the former should be retired. - - - - - 584f03fa by Simon Peyton Jones at 2022-01-31T18:47:23-05:00 Make typechecker trace less strict Fixes #21011 - - - - - 60ac7300 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH case pprint (fixes #20893) This patch ensures that the pretty printer formats `case` statements using braces (instead of layout) to remain consistent with the formatting of other statements (like `do`) - - - - - fdda93b0 by Elton at 2022-02-01T12:28:49-05:00 Use braces in TH LambdaCase and where clauses This patch ensures that the pretty printer formats LambdaCase and where clauses using braces (instead of layout) to remain consistent with the formatting of other statements (like `do` and `case`) - - - - - 06185102 by Ben Gamari at 2022-02-01T12:29:26-05:00 Consistently upper-case "Note [" This was achieved with git ls-tree --name-only HEAD -r | xargs sed -i -e 's/note \[/Note \[/g' - - - - - 88fba8a4 by Ben Gamari at 2022-02-01T12:29:26-05:00 Fix a few Note inconsistencies - - - - - 05548a22 by Douglas Wilson at 2022-02-02T19:26:06-05:00 rts: Address failures to inline - - - - - 074945de by Simon Peyton Jones at 2022-02-02T19:26:41-05:00 Two small improvements in the Simplifier As #20941 describes, this patch implements a couple of small fixes to the Simplifier. They make a difference principally with -O0, so few people will notice. But with -O0 they can reduce the number of Simplifer iterations. * In occurrence analysis we avoid making x = (a,b) into a loop breaker because we want to be able to inline x, or (more likely) do case-elimination. But HEAD does not treat x = let y = blah in (a,b) in the same way. We should though, because we are going to float that y=blah out of the x-binding. A one-line fix in OccurAnal. * The crucial function exprIsConApp_maybe uses getUnfoldingInRuleMatch (rightly) but the latter was deeply strange. In HEAD, if rule-rewriting was off (-O0) we only looked inside stable unfoldings. Very stupid. The patch simplifies. * I also noticed that in simplStableUnfolding we were failing to delete the DFun binders from the usage. So I added that. Practically zero perf change across the board, except that we get more compiler allocation in T3064 (which is compiled with -O0). There's a good reason: we get better code. But there are lots of other small compiler allocation decreases: Metrics: compile_time/bytes allocated --------------------- Baseline Test Metric value New value Change ----------------------------------------------------------------- PmSeriesG(normal) ghc/alloc 44,260,817 44,184,920 -0.2% PmSeriesS(normal) ghc/alloc 52,967,392 52,891,632 -0.1% PmSeriesT(normal) ghc/alloc 75,498,220 75,421,968 -0.1% PmSeriesV(normal) ghc/alloc 52,341,849 52,265,768 -0.1% T10421(normal) ghc/alloc 109,702,291 109,626,024 -0.1% T10421a(normal) ghc/alloc 76,888,308 76,809,896 -0.1% T10858(normal) ghc/alloc 125,149,038 125,073,648 -0.1% T11276(normal) ghc/alloc 94,159,364 94,081,640 -0.1% T11303b(normal) ghc/alloc 40,230,059 40,154,368 -0.2% T11822(normal) ghc/alloc 107,424,540 107,346,088 -0.1% T12150(optasm) ghc/alloc 76,486,339 76,426,152 -0.1% T12234(optasm) ghc/alloc 55,585,046 55,507,352 -0.1% T12425(optasm) ghc/alloc 88,343,288 88,265,312 -0.1% T13035(normal) ghc/alloc 98,919,768 98,845,600 -0.1% T13253-spj(normal) ghc/alloc 121,002,153 120,851,040 -0.1% T16190(normal) ghc/alloc 290,313,131 290,074,152 -0.1% T16875(normal) ghc/alloc 34,756,121 34,681,440 -0.2% T17836b(normal) ghc/alloc 45,198,100 45,120,288 -0.2% T17977(normal) ghc/alloc 39,479,952 39,404,112 -0.2% T17977b(normal) ghc/alloc 37,213,035 37,137,728 -0.2% T18140(normal) ghc/alloc 79,430,588 79,350,680 -0.1% T18282(normal) ghc/alloc 128,303,182 128,225,384 -0.1% T18304(normal) ghc/alloc 84,904,713 84,831,952 -0.1% T18923(normal) ghc/alloc 66,817,241 66,731,984 -0.1% T20049(normal) ghc/alloc 86,188,024 86,107,920 -0.1% T5837(normal) ghc/alloc 35,540,598 35,464,568 -0.2% T6048(optasm) ghc/alloc 99,812,171 99,736,032 -0.1% T9198(normal) ghc/alloc 46,380,270 46,304,984 -0.2% geo. mean -0.0% Metric Increase: T3064 - - - - - d2cce453 by Morrow at 2022-02-02T19:27:21-05:00 Fix @since annotation on Nat - - - - - 6438fed9 by Simon Peyton Jones at 2022-02-02T19:27:56-05:00 Refactor the escaping kind check for data constructors As #20929 pointed out, we were in-elegantly checking for escaping kinds in `checkValidType`, even though that check was guaranteed to succeed for type signatures -- it's part of kind-checking a type. But for /data constructors/ we kind-check the pieces separately, so we still need the check. This MR is a pure refactor, moving the test from `checkValidType` to `checkValidDataCon`. No new tests; external behaviour doesn't change. - - - - - fb05e5ac by Andreas Klebinger at 2022-02-02T19:28:31-05:00 Replace sndOfTriple with sndOf3 I also cleaned up the imports slightly while I was at it. - - - - - fbc77d3a by Matthew Pickering at 2022-02-02T19:29:07-05:00 testsuite: Honour PERF_BASELINE_COMMIT when computing allowed metric changes We now get all the commits between the PERF_BASELINE_COMMIT and HEAD and check any of them for metric changes. Fixes #20882 - - - - - 0a82ae0d by Simon Peyton Jones at 2022-02-02T23:49:58-05:00 More accurate unboxing This patch implements a fix for #20817. It ensures that * The final strictness signature for a function accurately reflects the unboxing done by the wrapper See Note [Finalising boxity for demand signatures] and Note [Finalising boxity for let-bound Ids] * A much better "layer-at-a-time" implementation of the budget for how many worker arguments we can have See Note [Worker argument budget] Generally this leads to a bit more worker/wrapper generation, because instead of aborting entirely if the budget is exceeded (and then lying about boxity), we unbox a bit. Binary sizes in increase slightly (around 1.8%) because of the increase in worker/wrapper generation. The big effects are to GHC.Ix, GHC.Show, GHC.IO.Handle.Internals. If we did a better job of dropping dead code, this effect might go away. Some nofib perf improvements: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- VSD +1.8% -0.5% 0.017 0.017 0.0% awards +1.8% -0.1% +2.3% +2.3% 0.0% banner +1.7% -0.2% +0.3% +0.3% 0.0% bspt +1.8% -0.1% +3.1% +3.1% 0.0% eliza +1.8% -0.1% +1.2% +1.2% 0.0% expert +1.7% -0.1% +9.6% +9.6% 0.0% fannkuch-redux +1.8% -0.4% -9.3% -9.3% 0.0% kahan +1.8% -0.1% +22.7% +22.7% 0.0% maillist +1.8% -0.9% +21.2% +21.6% 0.0% nucleic2 +1.7% -5.1% +7.5% +7.6% 0.0% pretty +1.8% -0.2% 0.000 0.000 0.0% reverse-complem +1.8% -2.5% +12.2% +12.2% 0.0% rfib +1.8% -0.2% +2.5% +2.5% 0.0% scc +1.8% -0.4% 0.000 0.000 0.0% simple +1.7% -1.3% +17.0% +17.0% +7.4% spectral-norm +1.8% -0.1% +6.8% +6.7% 0.0% sphere +1.7% -2.0% +13.3% +13.3% 0.0% tak +1.8% -0.2% +3.3% +3.3% 0.0% x2n1 +1.8% -0.4% +8.1% +8.1% 0.0% -------------------------------------------------------------------------------- Min +1.1% -5.1% -23.6% -23.6% 0.0% Max +1.8% +0.0% +36.2% +36.2% +7.4% Geometric Mean +1.7% -0.1% +6.8% +6.8% +0.1% Compiler allocations in CI have a geometric mean of +0.1%; many small decreases but there are three bigger increases (7%), all because we do more worker/wrapper than before, so there is simply more code to compile. That's OK. Perf benchmarks in perf/should_run improve in allocation by a geo mean of -0.2%, which is good. None get worse. T12996 improves by -5.8% Metric Decrease: T12996 Metric Increase: T18282 T18923 T9630 - - - - - d1ef6288 by Peter Trommler at 2022-02-02T23:50:34-05:00 Cmm: fix equality of expressions Compare expressions and types when comparing `CmmLoad`s. Fixes #21016 - - - - - e59446c6 by Peter Trommler at 2022-02-02T23:50:34-05:00 Check type first then expression - - - - - b0e1ef4a by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add failing test for #20791 The test produces different output on static vs dynamic GHC builds. - - - - - cae1fb17 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Frontend01 passes with static GHC - - - - - e343526b by Matthew Pickering at 2022-02-03T14:44:17-05:00 Don't initialise plugins when there are no pipelines to run - - - - - abac45fc by Matthew Pickering at 2022-02-03T14:44:17-05:00 Mark prog003 as expected_broken on static way #20704 - - - - - 13300dfd by Matthew Pickering at 2022-02-03T14:44:17-05:00 Filter out -rtsopts in T16219 to make static/dynamic ways agree - - - - - d89439f2 by Matthew Pickering at 2022-02-03T14:44:17-05:00 T13168: Filter out rtsopts for consistency between dynamic and static ways - - - - - 00180cdf by Matthew Pickering at 2022-02-03T14:44:17-05:00 Accept new output for T14335 test This test was previously not run due to #20960 - - - - - 1accdcff by Matthew Pickering at 2022-02-03T14:44:17-05:00 Add flushes to plugin tests which print to stdout Due to #20791 you need to explicitly flush as otherwise the output from these tests doesn't make it to stdout. - - - - - d820f2e8 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Remove ghc_plugin_way Using ghc_plugin_way had the unintended effect of meaning certain tests weren't run at all when ghc_dynamic=true, if you delete this modifier then the tests work in both the static and dynamic cases. - - - - - aa5ef340 by Matthew Pickering at 2022-02-03T14:44:17-05:00 Unbreak T13168 on windows Fixes #14276 - - - - - 84ab0153 by Matthew Pickering at 2022-02-03T14:44:53-05:00 Rewrite CallerCC parser using ReadP This allows us to remove the dependency on parsec and hence transitively on text. Also added some simple unit tests for the parser and fixed two small issues in the documentation. Fixes #21033 - - - - - 4e6780bb by Matthew Pickering at 2022-02-03T14:45:28-05:00 ci: Add debian 11 jobs (validate/release/nightly) Fixes #21002 - - - - - eddaa591 by Ben Gamari at 2022-02-04T10:01:59-05:00 compiler: Introduce and use RoughMap for instance environments Here we introduce a new data structure, RoughMap, inspired by the previous `RoughTc` matching mechanism for checking instance matches. This allows [Fam]InstEnv to be implemented as a trie indexed by these RoughTc signatures, reducing the complexity of instance lookup and FamInstEnv merging (done during the family instance conflict test) from O(n) to O(log n). The critical performance improvement currently realised by this patch is in instance matching. In particular the RoughMap mechanism allows us to discount many potential instances which will never match for constraints involving type variables (see Note [Matching a RoughMap]). In realistic code bases matchInstEnv was accounting for 50% of typechecker time due to redundant work checking instances when simplifying instance contexts when deriving instances. With this patch the cost is significantly reduced. The larger constants in InstEnv creation do mean that a few small tests regress in allocations slightly. However, the runtime of T19703 is reduced by a factor of 4. Moreover, the compilation time of the Cabal library is slightly improved. A couple of test cases are included which demonstrate significant improvements in compile time with this patch. This unfortunately does not fix the testcase provided in #19703 but does fix #20933 ------------------------- Metric Decrease: T12425 Metric Increase: T13719 T9872a T9872d hard_hole_fits ------------------------- Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 62d670eb by Matthew Pickering at 2022-02-04T10:02:35-05:00 testsuite: Run testsuite dependency calculation before GHC is built The main motivation for this patch is to allow tests to be added to the testsuite which test things about the source tree without needing to build GHC. In particular the notes linter can easily start failing and by integrating it into the testsuite the process of observing these changes is caught by normal validation procedures rather than having to run the linter specially. With this patch I can run ``` ./hadrian/build test --flavour=devel2 --only="uniques" ``` In a clean tree to run the checkUniques linter without having to build GHC. Fixes #21029 - - - - - 4bd52410 by Hécate Moonlight at 2022-02-04T16:14:10-05:00 Add the Ix class to Foreign C integral types Related CLC proposal is here: https://github.com/haskell/core-libraries-committee/issues/30 - - - - - de6d7692 by Ben Gamari at 2022-02-04T16:14:47-05:00 Drop dead code - - - - - b79206f1 by Ben Gamari at 2022-02-04T16:14:47-05:00 Add comments - - - - - 58d7faac by Ben Gamari at 2022-02-04T16:14:47-05:00 cmm: Introduce cmmLoadBWord and cmmLoadGCWord - - - - - 7217156c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment in CmmLoad - - - - - 99ea5f2c by Ben Gamari at 2022-02-04T16:14:47-05:00 Introduce alignment to CmmStore - - - - - 606b59a5 by Ben Gamari at 2022-02-04T16:14:47-05:00 Fix array primop alignment - - - - - 1cf9616a by Ben Gamari at 2022-02-04T16:14:47-05:00 llvmGen: Handle unaligned loads/stores This allows us to produce valid code for indexWord8ArrayAs*# on platforms that lack unaligned memory access. - - - - - 8c18feba by Ben Gamari at 2022-02-04T16:14:47-05:00 primops: Fix documentation of setByteArray# Previously the documentation was subtly incorrect regarding the bounds of the operation. Fix this and add a test asserting that a zero-length operation is in fact a no-op. - - - - - 88480e55 by nineonine at 2022-02-04T20:35:45-05:00 Fix unsound behavior of unlifted datatypes in ghci (#20194) Previously, directly calling a function that pattern matches on an unlifted data type which has at least two constructors in GHCi resulted in a segfault. This happened due to unaccounted return frame info table pointer. The fix is to pop the above mentioned frame info table pointer when unlifted things are returned. See Note [Popping return frame for unlifted things] authors: bgamari, nineonine - - - - - a5c7068c by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add Outputable instance for Messages c.f. #20980 - - - - - bf495f72 by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Add a missing restoreLclEnv The commit commit 18df4013f6eaee0e1de8ebd533f7e96c4ee0ff04 Date: Sat Jan 22 01:12:30 2022 +0000 Define and use restoreLclEnv omitted to change one setLclEnv to restoreLclEnv, namely the one in GHC.Tc.Errors.warnRedundantConstraints. This new commit fixes the omission. - - - - - 6af8e71e by Simon Peyton Jones at 2022-02-04T20:36:20-05:00 Improve errors for non-existent labels This patch fixes #17469, by improving matters when you use non-existent field names in a record construction: data T = MkT { x :: Int } f v = MkT { y = 3 } The check is now made in the renamer, in GHC.Rename.Env.lookupRecFieldOcc. That in turn led to a spurious error in T9975a, which is fixed by making GHC.Rename.Names.extendGlobalRdrEnvRn fail fast if it finds duplicate bindings. See Note [Fail fast on duplicate definitions] in that module for more details. This patch was originated and worked on by Alex D (@nineonine) - - - - - 299acff0 by nineonine at 2022-02-05T19:21:49-05:00 Exit with failure when -e fails (fixes #18411 #9916 #17560) - - - - - 549292eb by Matthew Pickering at 2022-02-05T19:22:25-05:00 Make implication tidying agree with Note [Tidying multiple names at once] Note [Tidying multiple names at once] indicates that if multiple variables have the same name then we shouldn't prioritise one of them and instead rename them all to a1, a2, a3... etc This patch implements that change, some error message changes as expected. Closes #20932 - - - - - 2e9248b7 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Accept any address within 4GB of program text Previously m32 would assume that the program image was located near the start of the address space and therefore assume that it wanted pages in the bottom 4GB of address space. Instead we now check whether they are within 4GB of whereever the program is loaded. This is necessary on Windows, which now tends to place the image in high memory. The eventual goal is to use m32 to allocate memory for linker sections on Windows. - - - - - 86589b89 by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts: Generalize mmapForLinkerMarkExecutable Renamed to mprotectForLinker and allowed setting of arbitrary protection modes. - - - - - 88ef270a by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Add consistency-checking infrastructure This adds logic, enabled in the `-debug` RTS for checking the internal consistency of the m32 allocator. This area has always made me a bit nervous so this should help me sleep better at night in exchange for very little overhead. - - - - - 2d6f0b17 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts/m32: Free large objects back to the free page pool Not entirely convinced that this is worth doing. - - - - - e96f50be by GHC GitLab CI at 2022-02-06T01:43:56-05:00 rts/m32: Increase size of free page pool to 256 pages - - - - - fc083b48 by Ben Gamari at 2022-02-06T01:43:56-05:00 rts: Dump memory map on memory mapping failures Fixes #20992. - - - - - 633296bc by Ben Gamari at 2022-02-06T01:43:56-05:00 Fix macro redefinition warnings for PRINTF * Move `PRINTF` macro from `Stats.h` to `Stats.c` as it's only needed in the latter. * Undefine `PRINTF` at the end of `Messages.h` to avoid leaking it. - - - - - 37d435d2 by John Ericson at 2022-02-06T01:44:32-05:00 Purge DynFlags from GHC.Stg Also derive some more instances. GHC doesn't need them, but downstream consumers may need to e.g. put stuff in maps. - - - - - 886baa34 by Peter Trommler at 2022-02-06T10:58:18+01:00 RTS: Fix cabal specification In 35bea01b xxhash.c was removed. Remove the extra-source-files stanza referring to it. - - - - - 27581d77 by Alex D at 2022-02-06T20:50:44-05:00 hadrian: remove redundant import - - - - - 4ff19981 by John Ericson at 2022-02-07T11:04:43-05:00 GHC.HsToCore.Coverage: No more HscEnv, less DynFlags Progress towards #20730 - - - - - b09389a6 by John Ericson at 2022-02-07T11:04:43-05:00 Create `CoverageConfig` As requested by @mpickering to collect the information we project from `HscEnv` - - - - - ff867c46 by Greg Steuck at 2022-02-07T11:05:24-05:00 Avoid using removed utils/checkUniques in validate Asked the question: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7460/diffs#4061f4d17546e239dd10d78c6b48668c2a288e02_1_0 - - - - - a9355e84 by sheaf at 2022-02-08T05:27:25-05:00 Allow HasField in quantified constraints We perform validity checking on user-written HasField instances, for example to disallow: data Foo a = Foo { fld :: Int } instance HasField "fld" (Foo a) Bool However, these checks were also being made on quantified constraints, e.g. data Bar where Bar :: (forall a. HasField s (Foo a) Int) => Proxy s -> Bar This patch simply skips validity checking for quantified constraints, in line with what we already do for equality constraints such as Coercible. Fixes #20989 - - - - - 6d77d3d8 by sheaf at 2022-02-08T05:28:05-05:00 Relax TyEq:N: allow out-of-scope newtype DataCon The 'bad_newtype' assertion in GHC.Tc.Solver.Canonical.canEqCanLHSFinish failed to account for the possibility that the newtype constructor might not be in scope, in which case we don't provide any guarantees about canonicalising away a newtype on the RHS of a representational equality. Fixes #21010 - - - - - a893d2f3 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Remove linter dependency on lint-submods - - - - - 457a5b9c by Ben Gamari at 2022-02-08T05:28:42-05:00 notes-util: initial commit - - - - - 1a943859 by Ben Gamari at 2022-02-08T05:28:42-05:00 gitlab-ci: Add lint-notes job - - - - - bc5cbce6 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add notes linter to testsuite - - - - - 38c6e301 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Fix some notes - - - - - c3aac0f8 by Matthew Pickering at 2022-02-08T05:28:42-05:00 Add suggestion mode to notes-util - - - - - 5dd29aea by Cale Gibbard at 2022-02-08T05:29:18-05:00 `hscSimpleIface` drop fingerprint param and ret `hscSimpleIface` does not depend on or modify the `Maybe Fingerprint` it is given, only passes it through, so get rid of the extraneous passing. Perhaps the intent was that there would be an iface fingerprint check of some sort? but this was never done. If/when we we want to do that, we can add it back then. - - - - - 4bcbd731 by Cale Gibbard at 2022-02-08T05:29:54-05:00 Document `hscIncrementalFrontend` and flip bool - - - - - b713db1e by John Ericson at 2022-02-08T05:30:29-05:00 StgToCmm: Get rid of GHC.Driver.Session imports `DynFlags` is gone, but let's move a few trivial things around to get rid of its module too. - - - - - f115c382 by Gleb Popov at 2022-02-08T05:31:05-05:00 Fix build on recent FreeBSD. Recent FreeBSD versions gained the sched_getaffinity function, which made two mutually exclusive #ifdef blocks to be enabled. - - - - - 3320ab40 by Ben Gamari at 2022-02-08T10:42:04-05:00 rts/MemoryMap: Use mach_-prefixed type names There appears to be some inconsistency in system-call type naming across Darwin toolchains. Specifically: * the `address` argument to `mach_vm_region` apparently wants to be a `mach_vm_address_t *`, not a `vm_address_t *` * the `vmsize` argument to `mach_vm_region` wants to be a `mach_vm_size_t`, not a `vm_size_t` - - - - - b33f0cfa by Richard Eisenberg at 2022-02-08T10:42:41-05:00 Document that reifyRoles includes kind parameters Close #21056 - - - - - bd493ed6 by PHO at 2022-02-08T10:43:19-05:00 Don't try to build stage1 with -eventlog if stage0 doesn't provide it Like -threaded, stage0 isn't guaranteed to have an event-logging RTS. - - - - - 03c2de0f by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Use absolute paths for config.libdir Fixes #21052 - - - - - ef294525 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Clean up old/redundant predicates - - - - - a39ed908 by Matthew Pickering at 2022-02-09T03:56:22-05:00 testsuite: Add missing dependency on ghcconfig - - - - - a172be07 by PHO at 2022-02-09T03:56:59-05:00 Implement System.Environment.getExecutablePath for NetBSD and also use it from GHC.BaseDir.getBaseDir - - - - - 62fa126d by PHO at 2022-02-09T03:57:37-05:00 Fix a portability issue in m4/find_llvm_prog.m4 `test A == B' is a Bash extension, which doesn't work on platforms where /bin/sh is not Bash. - - - - - fd9981e3 by Ryan Scott at 2022-02-09T03:58:13-05:00 Look through untyped TH splices in tcInferAppHead_maybe Previously, surrounding a head expression with a TH splice would defeat `tcInferAppHead_maybe`, preventing some expressions from typechecking that used to typecheck in previous GHC versions (see #21038 for examples). This is simple enough to fix: just look through `HsSpliceE`s in `tcInferAppHead_maybe`. I've added some additional prose to `Note [Application chains and heads]` in `GHC.Tc.Gen.App` to accompany this change. Fixes #21038. - - - - - 00975981 by sheaf at 2022-02-09T03:58:53-05:00 Add test for #21037 This program was rejected by GHC 9.2, but is accepted on newer versions of GHC. This patch adds a regression test. Closes #21037 - - - - - fad0b2b0 by Ben Gamari at 2022-02-09T08:29:46-05:00 Rename -merge-objs flag to --merge-objs For consistency with --make and friends. - - - - - 1dbe5b2a by Matthew Pickering at 2022-02-09T08:30:22-05:00 driver: Filter out our own boot module in hptSomeThingsBelow hptSomeThingsBelow would return a list of modules which contain the .hs-boot file for a particular module. This caused some problems because we would try and find the module in the HPT (but it's not there when we're compiling the module itself). Fixes #21058 - - - - - 2b1cced1 by Sylvain Henry at 2022-02-09T20:42:23-05:00 NCG: minor code factorization - - - - - e01ffec2 by Sylvain Henry at 2022-02-09T20:42:23-05:00 ByteCode: avoid out-of-bound read Cf https://gitlab.haskell.org/ghc/ghc/-/issues/18431#note_287139 - - - - - 53c26e79 by Ziyang Liu at 2022-02-09T20:43:02-05:00 Include ru_name in toHsRule message See #18147 - - - - - 3df06922 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Rename MemoryMap.[ch] -> ReportMemoryMap.[ch] - - - - - e219ac82 by Ben Gamari at 2022-02-09T20:43:39-05:00 rts: Move mmapForLinker and friends to linker/MMap.c They are not particularly related to linking. - - - - - 30e205ca by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker: Drop dead IA64 code - - - - - 4d3a306d by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/linker/MMap: Use MemoryAccess in mmapForLinker - - - - - 1db4f1fe by Ben Gamari at 2022-02-09T20:43:39-05:00 linker: Don't use MAP_FIXED As noted in #21057, we really shouldn't be using MAP_FIXED. I would much rather have the process crash with a "failed to map" error than randomly overwrite existing mappings. Closes #21057. - - - - - 1eeae25c by Ben Gamari at 2022-02-09T20:43:39-05:00 rts/mmap: Refactor mmapForLinker Here we try to separate the policy decisions of where to place mappings from the mechanism of creating the mappings. This makes things significantly easier to follow. - - - - - ac2d18a7 by sheaf at 2022-02-09T20:44:18-05:00 Add some perf tests for coercions This patch adds some performance tests for programs that create large coercions. This is useful because the existing test coverage is not very representative of real-world situations. In particular, this adds a test involving an extensible records library, a common pain-point for users. - - - - - 48f25715 by Andreas Klebinger at 2022-02-10T04:35:35-05:00 Add late cost centre support This allows cost centres to be inserted after the core optimization pipeline has run. - - - - - 0ff70427 by Andreas Klebinger at 2022-02-10T04:36:11-05:00 Docs:Mention that safe calls don't keep their arguments alive. - - - - - 1d3ed168 by Ben Gamari at 2022-02-10T04:36:46-05:00 PEi386: Drop Windows Vista fallback in addLibrarySearchPath We no longer support Windows Vista. - - - - - 2a6f2681 by Ben Gamari at 2022-02-10T04:36:46-05:00 linker/PEi386: Make addLibrarySearchPath long-path aware Previously `addLibrarySearchPath` failed to normalise the added path to UNC form before passing it to `AddDllDirectory`. Consequently, the call was subject to the MAX_PATH restriction, leading to the failure of `test-defaulting-plugin-fail`, among others. Happily, this also nicely simplifies the implementation. Closes #21059. - - - - - 2a47ee9c by Daniel Gröber at 2022-02-10T19:18:58-05:00 ghc-boot: Simplify writePackageDb permissions handling Commit ef8a3fbf1 ("ghc-boot: Fix metadata handling of writeFileAtomic") introduced a somewhat over-engineered fix for #14017 by trying to preserve the current permissions if the target file already exists. The problem in the issue is simply that the package db cache file should be world readable but isn't if umask is too restrictive. In fact the previous fix only handles part of this problem. If the file isn't already there in a readable configuration it wont make it so which isn't really ideal either. Rather than all that we now simply always force all the read access bits to allow access while leaving the owner at the system default as it's just not our business to mess with it. - - - - - a1d97968 by Ben Gamari at 2022-02-10T19:19:34-05:00 Bump Cabal submodule Adapts GHC to the factoring-out of `Cabal-syntax`. Fixes #20991. Metric Decrease: haddock.Cabal - - - - - 89cf8caa by Morrow at 2022-02-10T19:20:13-05:00 Add metadata to integer-gmp.cabal - - - - - c995b7e7 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of EVENT_IPE This leads to corrupted eventlogs because the size of EVENT_IPE is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 59ba8fb3 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix event type of MEM_RETURN This leads to corrupted eventlogs because the size of EVENT_MEM_RETURN is completely wrong. Fixes a bug introduced in 2e29edb7421c21902b47d130d45f60d3f584a0de - - - - - 19413d09 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Delete misleading comment in gen_event_types.py Not all events start with CapNo and there's not logic I could see which adds this to the length. - - - - - e06f49c0 by Matthew Pickering at 2022-02-10T19:20:48-05:00 eventlog: Fix size of TICKY_COUNTER_BEGIN_SAMPLE - - - - - 2f99255b by Matthew Pickering at 2022-02-10T19:21:24-05:00 Fix copy-pasto in prof-late-ccs docs - - - - - 19deb002 by Matthew Pickering at 2022-02-10T19:21:59-05:00 Refine tcSemigroupWarnings to work in ghc-prim ghc-prim doesn't depend on base so can't have any Monoid or Semigroup instances. However, attempting to load these definitions ran into issues when the interface for `GHC.Base` did exist as that would try and load the interface for `GHC.Types` (which is the module we are trying to compile and has no interface). The fix is to just not do this check when we are compiling a module in ghc-prim. Fixes #21069 - - - - - 34dec6b7 by sheaf at 2022-02-11T17:55:34-05:00 Decrease the size of the LargeRecord test This test was taking too long to run, so this patch makes it smaller. ------------------------- Metric Decrease: LargeRecord ------------------------- - - - - - 9cab90d9 by Matthew Pickering at 2022-02-11T22:27:19-05:00 Make sure all platforms have a release job The release bindists are currently a mixture of validate and release builds. This is bad because the validate builds don't have profiling libraries. The fix is to make sure there is a release job for each platform we want to produce a release for.t Fixes #21066 - - - - - 4bce3575 by Matthew Pickering at 2022-02-11T22:27:54-05:00 testsuite: Make sure all tests trigger ghc rebuild I made a mistake when implementing #21029 which meant that certain tests didn't trigger a GHC recompilation. By adding the `test:ghc` target to the default settings all tests will now depend on this target unless explicitly opting out via the no_deps modifier. - - - - - 90a26f8b by Sylvain Henry at 2022-02-11T22:28:34-05:00 Fix documentation about Word64Rep/Int64Rep (#16964) - - - - - 0e93023e by Andreas Klebinger at 2022-02-12T13:59:41+00:00 Tag inference work. This does three major things: * Enforce the invariant that all strict fields must contain tagged pointers. * Try to predict the tag on bindings in order to omit tag checks. * Allows functions to pass arguments unlifted (call-by-value). The former is "simply" achieved by wrapping any constructor allocations with a case which will evaluate the respective strict bindings. The prediction is done by a new data flow analysis based on the STG representation of a program. This also helps us to avoid generating redudant cases for the above invariant. StrictWorkers are created by W/W directly and SpecConstr indirectly. See the Note [Strict Worker Ids] Other minor changes: * Add StgUtil module containing a few functions needed by, but not specific to the tag analysis. ------------------------- Metric Decrease: T12545 T18698b T18140 T18923 LargeRecord Metric Increase: LargeRecord ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T15164 T18282 T18304 T18698a T1969 T20049 T3294 T4801 T5321FD T5321Fun T783 T9233 T9675 T9961 T19695 WWRec ------------------------- - - - - - 744f8a11 by Greg Steuck at 2022-02-12T17:13:55-05:00 Only check the exit code in derefnull & divbyzero tests on OpenBSD - - - - - eeead9fc by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/Adjustor: Ensure that allocateExecPage succeeded Previously we failed to handle the case that `allocateExecPage` failed. - - - - - afdfaff0 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Drop DEC Alpha adjustor implementation The last Alpha chip was produced in 2004. - - - - - 191dfd2d by Ben Gamari at 2022-02-13T03:26:14-05:00 rts/adjustor: Split Windows path out of NativeAmd64 - - - - - be591e27 by Ben Gamari at 2022-02-13T03:26:14-05:00 rts: Initial commit of AdjustorPool - - - - - d6d48b16 by Ben Gamari at 2022-02-13T03:26:14-05:00 Introduce initAdjustors - - - - - eab37902 by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64: Use AdjustorPool - - - - - 974e73af by Ben Gamari at 2022-02-13T03:26:14-05:00 adjustors/NativeAmd64Mingw: Use AdjustorPool - - - - - 95fab83f by Ben Gamari at 2022-02-13T03:26:14-05:00 configure: Fix result reporting of adjustors method check - - - - - ef5cf55d by nikshalark at 2022-02-13T03:26:16-05:00 (#21044) Documented arithmetic functions in base. Didn't get it right the ninth time. Now everything's formatted correctly. - - - - - acb482cc by Takenobu Tani at 2022-02-16T05:27:17-05:00 Relax load_load_barrier for aarch64 This patch relaxes the instruction for load_load_barrier(). Current load_load_barrier() implements full-barrier with `dmb sy`. It's too strong to order load-load instructions. We can relax it by using `dmb ld`. If current load_load_barrier() is used for full-barriers (load/store - load/store barrier), this patch is not suitable. See also linux-kernel's smp_rmb() implementation: https://github.com/torvalds/linux/blob/v5.14/arch/arm64/include/asm/barrier.h#L90 Hopefully, it's better to use `dmb ishld` rather than `dmb ld` to improve performance. However, I can't validate effects on a real many-core Arm machine. - - - - - 84eaa26f by Oleg Grenrus at 2022-02-16T05:27:56-05:00 Add test for #20562 - - - - - 2c28620d by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: remove struct StgRetry, it is never used - - - - - 74bf9bb5 by Adam Sandberg Ericsson at 2022-02-16T05:28:32-05:00 rts: document some closure types - - - - - 316312ec by nineonine at 2022-02-16T05:29:08-05:00 ghci: fix -ddump-stg-cg (#21052) The pre-codegen Stg AST dump was not available in ghci because it was performed in 'doCodeGen'. This was now moved to 'coreToStg' area. - - - - - a6411d74 by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: mention -fprof-late-ccs in the release notes And note which compiler version it was added in. - - - - - 4127e86d by Adam Sandberg Ericsson at 2022-02-16T05:29:43-05:00 docs: fix release notes formatting - - - - - 4e6c8019 by Matthew Pickering at 2022-02-17T05:25:28-05:00 Always define __GLASGOW_HASKELL_PATCHLEVEL1/2__ macros As #21076 reports if you are using `-Wcpp-undef` then you get warnings when using the `MIN_VERSION_GLASGOW_HASKELL` macro because __GLASGOW_HASKELL_PATCHLEVEL2__ is very rarely explicitliy set (as version numbers are not 4 components long). This macro was introduced in 3549c952b535803270872adaf87262f2df0295a4 and it seems the bug has existed ever since. Fixes #21076 - - - - - 67dd5724 by Ben Gamari at 2022-02-17T05:26:03-05:00 rts/AdjustorPool: Silence unused function warning bitmap_get is only used in the DEBUG RTS configuration. Fixes #21079. - - - - - 4b04f7e1 by Zubin Duggal at 2022-02-20T13:56:15-05:00 Track object file dependencies for TH accurately (#20604) `hscCompileCoreExprHook` is changed to return a list of `Module`s required by a splice. These modules are accumulated in the TcGblEnv (tcg_th_needed_mods). Dependencies on the object files of these modules are recording in the interface. The data structures in `LoaderState` are replaced with more efficient versions to keep track of all the information required. The MultiLayerModulesTH_Make allocations increase slightly but runtime is faster. Fixes #20604 ------------------------- Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - 92ab3ff2 by sheaf at 2022-02-20T13:56:55-05:00 Use diagnostics for "missing signature" errors This patch makes the "missing signature" errors from "GHC.Rename.Names" use the diagnostic infrastructure. This encompasses missing type signatures for top-level bindings and pattern synonyms, as well as missing kind signatures for type constructors. This patch also renames TcReportMsg to TcSolverReportMsg, and adds a few convenience functions to compute whether such a TcSolverReportMsg is an expected/actual message. - - - - - 845284a5 by sheaf at 2022-02-20T13:57:34-05:00 Generically: remove redundant Semigroup constraint This patch removes a redundant Semigroup constraint on the Monoid instance for Generically. This constraint can cause trouble when one wants to derive a Monoid instance via Generically through a type that doesn't itself have a Semigroup instance, for example: data Point2D a = Point2D !a !a newtype Vector2D a = Vector2D { tip :: Point2D a } deriving ( Semigroup, Monoid ) via Generically ( Point2D ( Sum a ) ) In this case, we should not require there to be an instance Semigroup ( Point2D ( Sum a ) ) as all we need is an instance for the generic representation of Point2D ( Sum a ), i.e. Semigroup ( Rep ( Point2D ( Sum a) ) () ). - - - - - 6b468f7f by Ben Gamari at 2022-02-20T13:58:10-05:00 Bump time submodule to 1.12.1 - - - - - 2f0ceecc by Zubin Duggal at 2022-02-20T19:06:19+00:00 hadrian: detect if 'main' is not a haskell file and add it to appropriate list of sources - - - - - 7ce1b694 by Zubin Duggal at 2022-02-21T11:18:58+00:00 Reinstallable GHC This patch allows ghc and its dependencies to be built using a normal invocation of cabal-install. Each componenent which relied on generated files or additional configuration now has a Setup.hs file. There are also various fixes to the cabal files to satisfy cabal-install. There is a new hadrian command which will build a stage2 compiler and then a stage3 compiler by using cabal. ``` ./hadrian/build build-cabal ``` There is also a new CI job which tests running this command. For the 9.4 release we will upload all the dependent executables to hackage and then end users will be free to build GHC and GHC executables via cabal. There are still some unresolved questions about how to ensure soundness when loading plugins into a reinstalled GHC (#20742) which will be tighted up in due course. Fixes #19896 - - - - - 78fbc3a3 by Matthew Pickering at 2022-02-21T15:14:28-05:00 hadrian: Enable late-ccs when building profiled_ghc - - - - - 2b890c89 by Matthew Pickering at 2022-02-22T15:59:33-05:00 testsuite: Don't print names of all fragile tests on all runs This information about fragile tests is pretty useless but annoying on CI where you have to scroll up a long way to see the actual issues. - - - - - 0b36801f by sheaf at 2022-02-22T16:00:14-05:00 Forbid standalone instances for built-in classes `check_special_inst_head` includes logic that disallows hand-written instances for built-in classes such as Typeable, KnownNat and KnownSymbol. However, it also allowed standalone deriving declarations. This was because we do want to allow standalone deriving instances with Typeable as they are harmless, but we certainly don't want to allow instances for e.g. KnownNat. This patch ensures that we don't allow derived instances for KnownNat, KnownSymbol (and also KnownChar, which was previously omitted entirely). Fixes #21087 - - - - - ace66dec by Krzysztof Gogolewski at 2022-02-22T16:30:59-05:00 Remove -Wunticked-promoted-constructors from -Wall Update manual; explain ticks as optional disambiguation rather than the preferred default. This is a part of #20531. - - - - - 558c7d55 by Hugo at 2022-02-22T16:31:01-05:00 docs: fix error in annotation guide code snippet - - - - - a599abba by Richard Eisenberg at 2022-02-23T08:16:07-05:00 Kill derived constraints Co-authored by: Sam Derbyshire Previously, GHC had three flavours of constraint: Wanted, Given, and Derived. This removes Derived constraints. Though serving a number of purposes, the most important role of Derived constraints was to enable better error messages. This job has been taken over by the new RewriterSets, as explained in Note [Wanteds rewrite wanteds] in GHC.Tc.Types.Constraint. Other knock-on effects: - Various new Notes as I learned about under-described bits of GHC - A reshuffling around the AST for implicit-parameter bindings, with better integration with TTG. - Various improvements around fundeps. These were caused by the fact that, previously, fundep constraints were all Derived, and Derived constraints would get dropped. Thus, an unsolved Derived didn't stop compilation. Without Derived, this is no longer possible, and so we have to be considerably more careful around fundeps. - A nice little refactoring in GHC.Tc.Errors to center the work on a new datatype called ErrorItem. Constraints are converted into ErrorItems at the start of processing, and this allows for a little preprocessing before the main classification. - This commit also cleans up the behavior in generalisation around functional dependencies. Now, if a variable is determined by functional dependencies, it will not be quantified. This change is user facing, but it should trim down GHC's strange behavior around fundeps. - Previously, reportWanteds did quite a bit of work, even on an empty WantedConstraints. This commit adds a fast path. - Now, GHC will unconditionally re-simplify constraints during quantification. See Note [Unconditionally resimplify constraints when quantifying], in GHC.Tc.Solver. Close #18398. Close #18406. Solve the fundep-related non-confluence in #18851. Close #19131. Close #19137. Close #20922. Close #20668. Close #19665. ------------------------- Metric Decrease: LargeRecord T9872b T9872b_defer T9872d TcPlugin_RewritePerf ------------------------- - - - - - 2ed22ba1 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Introduce predicate for when to enable source notes (needSourceNotes) There were situations where we were using debugLevel == 0 as a proxy for whether to retain source notes but -finfo-table-map also enables and needs source notes so we should act consistently in both cases. Ticket #20847 - - - - - 37deb893 by Matthew Pickering at 2022-02-23T08:16:43-05:00 Use SrcSpan from the binder as initial source estimate There are some situations where we end up with no source notes in useful positions in an expression. In this case we currently fail to provide any source information about where an expression came from. This patch improves the initial estimate by using the position from the top-binder as the guess for the location of the whole inner expression. It provides quite a course estimate but it's better than nothing. Ticket #20847 - - - - - 59b7f764 by Cheng Shao at 2022-02-23T08:17:24-05:00 Don't emit foreign exports initialiser code for empty CAF list - - - - - c7f32f76 by John Ericson at 2022-02-23T13:58:36-05:00 Prepare rechecking logic for new type in a few ways Combine `MustCompile and `NeedsCompile` into a single case. `CompileReason` is put inside to destinguish the two. This makes a number of things easier. `Semigroup RecompileRequired` is no longer used, to make sure we skip doing work where possible. `recompThen` is very similar, but helps remember. `checkList` is rewritten with `recompThen`. - - - - - e60d8df8 by John Ericson at 2022-02-23T13:58:36-05:00 Introduce `MaybeValidated` type to remove invalid states The old return type `(RecompRequired, Maybe _)`, was confusing because it was inhabited by values like `(UpToDate, Nothing)` that made no sense. The new type ensures: - you must provide a value if it is up to date. - you must provide a reason if you don't provide a value. it is used as the return value of: - `checkOldIface` - `checkByteCode` - `checkObjects` - - - - - f07b13e3 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor X86 codegen Preliminary work done to make working on #5444 easier. Mostly make make control-flow easier to follow: * renamed genCCall into genForeignCall * split genForeignCall into the part dispatching on PrimTarget (genPrim) and the one really generating code for a C call (cf ForeignTarget and genCCall) * made genPrim/genSimplePrim only dispatch on MachOp: each MachOp now has its own code generation function. * out-of-line primops are not handled in a partial `outOfLineCmmOp` anymore but in the code generation functions directly. Helper functions have been introduced (e.g. genLibCCall) for code sharing. * the latter two bullets make code generated for primops that are only sometimes out-of-line (e.g. Pdep or Memcpy) and the logic to select between inline/out-of-line much more localized * avoided passing is32bit as an argument as we can easily get it from NatM state when we really need it * changed genCCall type to avoid it being partial (it can't handle PrimTarget) * globally removed 12 calls to `panic` thanks to better control flow and types ("parse, don't validate" ftw!). - - - - - 6fa7591e by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: refactor the way registers are handled * add getLocalRegReg to avoid allocating a CmmLocal just to call getRegisterReg * 64-bit registers: in the general case we must always use the virtual higher part of the register, so we might as well always return it with the lower part. The only exception is to implement 64-bit to 32-bit conversions. We now have to explicitly discard the higher part when matching on Reg64/RegCode64 datatypes instead of explicitly fetching the higher part from the lower part: much safer default. - - - - - bc8de322 by Sylvain Henry at 2022-02-23T13:59:23-05:00 NCG: inline some 64-bit primops on x86/32-bit (#5444) Several 64-bit operation were implemented with FFI calls on 32-bit architectures but we can easily implement them with inline assembly code. Also remove unused hs_int64ToWord64 and hs_word64ToInt64 C functions. - - - - - 7b7c6b95 by Matthew Pickering at 2022-02-23T14:00:00-05:00 Simplify/correct implementation of getModuleInfo - - - - - 6215b04c by Matthew Pickering at 2022-02-23T14:00:00-05:00 Remove mg_boot field from ModuleGraph It was unused in the compiler so I have removed it to streamline ModuleGraph. - - - - - 818ff2ef by Matthew Pickering at 2022-02-23T14:00:01-05:00 driver: Remove needsTemplateHaskellOrQQ from ModuleGraph The idea of the needsTemplateHaskellOrQQ query is to check if any of the modules in a module graph need Template Haskell then enable -dynamic-too if necessary. This is quite imprecise though as it will enable -dynamic-too for all modules in the module graph even if only one module uses template haskell, with multiple home units, this is obviously even worse. With -fno-code we already have similar logic to enable code generation just for the modules which are dependeded on my TemplateHaskell modules so we use the same code path to decide whether to enable -dynamic-too rather than using this big hammer. This is part of the larger overall goal of moving as much statically known configuration into the downsweep as possible in order to have fully decided the build plan and all the options before starting to build anything. I also included a fix to #21095, a long standing bug with with the logic which is supposed to enable the external interpreter if we don't have the internal interpreter. Fixes #20696 #21095 - - - - - b6670af6 by Matthew Pickering at 2022-02-23T14:00:40-05:00 testsuite: Normalise output of ghci011 and T7627 The outputs of these tests vary on the order interface files are loaded so we normalise the output to correct for these inconsequential differences. Fixes #21121 - - - - - 9ed3bc6e by Peter Trommler at 2022-02-23T14:01:16-05:00 testsuite: Fix ipeMap test Pointers to closures must be untagged before use. Produce closures of different types so we get different info tables. Fixes #21112 - - - - - 7d426148 by Ziyang Liu at 2022-02-24T04:53:34-05:00 Allow `return` in more cases in ApplicativeDo The doc says that the last statement of an ado-block can be one of `return E`, `return $ E`, `pure E` and `pure $ E`. But `return` is not accepted in a few cases such as: ```haskell -- The ado-block only has one statement x :: F () x = do return () -- The ado-block only has let-statements besides the `return` y :: F () y = do let a = True return () ``` These currently require `Monad` instances. This MR fixes it. Normally `return` is accepted as the last statement because it is stripped in constructing an `ApplicativeStmt`, but this cannot be done in the above cases, so instead we replace `return` by `pure`. A similar but different issue (when the ado-block contains `BindStmt` or `BodyStmt`, the second last statement cannot be `LetStmt`, even if the last statement uses `pure`) is fixed in !6786. - - - - - a5ea7867 by John Ericson at 2022-02-24T20:23:49-05:00 Clarify laws of TestEquality It is unclear what `TestEquality` is for. There are 3 possible choices. Assuming ```haskell data Tag a where TagInt1 :: Tag Int TagInt2 :: Tag Int ``` Weakest -- type param equality semi-decidable --------------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params may or may not be not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Nothing -- oopsie is allowed testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` This option is better demonstrated with a different type: ```haskell data Tag' a where TagInt1 :: Tag Int TagInt2 :: Tag a ``` ```haskell instance TestEquality Tag' where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Nothing -- can't be sure testEquality TagInt2 TagInt1 = Nothing -- can't be sure testEquality TagInt2 TagInt2 = Nothing -- can't be sure ``` Weaker -- type param equality decidable --------------------------------------- `Just Refl` merely means the type params are equal, the values being compared might not be. `Nothing` means the type params are not equal. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt1 TagInt2 = Just Refl testEquality TagInt2 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl ``` Strong -- Like `Eq` ------------------- `Just Refl` means the type params are equal, and the values are equal according to `Eq`. ```haskell instance TestEquality Tag where testEquality TagInt1 TagInt1 = Just Refl testEquality TagInt2 TagInt2 = Just Refl testEquality _ _ = Nothing ``` Strongest -- unique value concrete type --------------------------------------- `Just Refl` means the type params are equal, and the values are equal, and the class assume if the type params are equal the values must also be equal. In other words, the type is a singleton type when the type parameter is a closed term. ```haskell -- instance TestEquality -- invalid instance because two variants for `Int` ``` ------ The discussion in https://github.com/haskell/core-libraries-committee/issues/21 has decided on the "Weaker" option (confusingly formerly called the "Weakest" option). So that is what is implemented. - - - - - 06c18990 by Zubin Duggal at 2022-02-24T20:24:25-05:00 TH: fix pretty printing of GADTs with multiple constuctors (#20842) - - - - - 6555b68c by Matthew Pickering at 2022-02-24T20:25:06-05:00 Move linters into the tree This MR moves the GHC linters into the tree, so that they can be run directly using Hadrian. * Query all files tracked by Git instead of using changed files, so that we can run the exact same linting step locally and in a merge request. * Only check that the changelogs don't contain TBA when RELEASE=YES. * Add hadrian/lint script, which runs all the linting steps. * Ensure the hlint job exits with a failure if hlint is not installed (otherwise we were ignoring the failure). Given that hlint doesn't seem to be available in CI at the moment, I've temporarily allowed failure in the hlint job. * Run all linting tests in CI using hadrian. - - - - - b99646ed by Matthew Pickering at 2022-02-24T20:25:06-05:00 Add rule for generating HsBaseConfig.h If you are running the `lint:{base/compiler}` command locally then this improves the responsiveness because we don't re-run configure everytime if the header file already exists. - - - - - d0deaaf4 by Matthew Pickering at 2022-02-24T20:25:06-05:00 Suggestions due to hlint It turns out this job hasn't been running for quite a while (perhaps ever) so there are quite a few failures when running the linter locally. - - - - - 70bafefb by nineonine at 2022-02-24T20:25:42-05:00 ghci: show helpful error message when loading module with SIMD vector operations (#20214) Previously, when trying to load module with SIMD vector operations, ghci would panic in 'GHC.StgToByteCode.findPushSeq'. Now, a more helpful message is displayed. - - - - - 8ed3d5fd by Matthew Pickering at 2022-02-25T10:24:12+00:00 Remove test-bootstrap and cabal-reinstall jobs from fast-ci [skip ci] - - - - - 8387dfbe by Mario Blažević at 2022-02-25T21:09:41-05:00 template-haskell: Fix two prettyprinter issues Fix two issues regarding printing numeric literals. Fixing #20454. - - - - - 4ad8ce0b by sheaf at 2022-02-25T21:10:22-05:00 GHCi: don't normalise partially instantiated types This patch skips performing type normalisation when we haven't fully instantiated the type. That is, in tcRnExpr (used only for :type in GHCi), skip normalisation if the result type responds True to isSigmaTy. Fixes #20974 - - - - - f35aca4d by Ben Gamari at 2022-02-25T21:10:57-05:00 rts/adjustor: Always place adjustor templates in data section @nrnrnr points out that on his machine ld.lld rejects text relocations. Generalize the Darwin text-relocation avoidance logic to account for this. - - - - - cddb040a by Andreas Klebinger at 2022-02-25T21:11:33-05:00 Ticky: Gate tag-inference dummy ticky-counters behind a flag. Tag inference included a way to collect stats about avoided tag-checks. This was dony by emitting "dummy" ticky entries with counts corresponding to predicted/unpredicated tag checks. This behaviour for ticky is now gated behind -fticky-tag-checks. I also documented ticky-LNE in the process. - - - - - 948bf2d0 by Ben Gamari at 2022-02-25T21:12:09-05:00 Fix comment reference to T4818 - - - - - 9c3edeb8 by Ben Gamari at 2022-02-25T21:12:09-05:00 simplCore: Correctly extend in-scope set in rule matching Note [Matching lets] in GHC.Core.Rules claims the following: > We use GHC.Core.Subst.substBind to freshen the binding, using an > in-scope set that is the original in-scope variables plus the > rs_bndrs (currently floated let-bindings). However, previously the implementation didn't actually do extend the in-scope set with rs_bndrs. This appears to be a regression which was introduced by 4ff4d434e9a90623afce00b43e2a5a1ccbdb4c05. Moreover, the originally reasoning was subtly wrong: we must rather use the in-scope set from rv_lcl, extended with rs_bndrs, not that of `rv_fltR` Fixes #21122. - - - - - 7f9f49c3 by sheaf at 2022-02-25T21:12:47-05:00 Derive some stock instances for OverridingBool This patch adds some derived instances to `GHC.Data.Bool.OverridingBool`. It also changes the order of the constructors, so that the derived `Ord` instance matches the behaviour for `Maybe Bool`. Fixes #20326 - - - - - 140438a8 by nineonine at 2022-02-25T21:13:23-05:00 Add test for #19271 - - - - - ac9f4606 by sheaf at 2022-02-25T21:14:04-05:00 Allow qualified names in COMPLETE pragmas The parser didn't allow qualified constructor names to appear in COMPLETE pragmas. This patch fixes that. Fixes #20551 - - - - - 677c6c91 by Sylvain Henry at 2022-02-25T21:14:44-05:00 Testsuite: remove arch conditional in T8832 Taken from !3658 - - - - - ad04953b by Sylvain Henry at 2022-02-25T21:15:23-05:00 Allow hscGenHardCode to not return CgInfos This is a minor change in preparation for the JS backend: CgInfos aren't mandatory and the JS backend won't return them. - - - - - 929c280f by Sylvain Henry at 2022-02-25T21:15:24-05:00 Derive Enum instances for CCallConv and Safety This is used by the JS backend for serialization. - - - - - 75e4e090 by Sebastian Graf at 2022-02-25T21:15:59-05:00 base: Improve documentation of `throwIO` (#19854) Now it takes a better account of precise vs. imprecise exception semantics. Fixes #19854. - - - - - 61a203ba by Matthew Pickering at 2022-02-26T02:06:51-05:00 Make typechecking unfoldings from interfaces lazier The old logic was unecessarily strict in loading unfoldings because when reading the unfolding we would case on the result of attempting to load the template before commiting to which type of unfolding we were producing. Hence trying to inspect any of the information about an unfolding would force the template to be loaded. This also removes a potentially hard to discover bug where if the template failed to be typechecked for some reason then we would just not return an unfolding. Instead we now panic so these bad situations which should never arise can be identified. - - - - - 2be74460 by Matthew Pickering at 2022-02-26T02:06:51-05:00 Use a more up-to-date snapshot of the current rules in the simplifier As the prescient (now deleted) note warns in simplifyPgmIO we have to be a bit careful about when we gather rules from the EPS so that we get the rules for imported bindings. ``` -- Get any new rules, and extend the rule base -- See Note [Overall plumbing for rules] in GHC.Core.Rules -- We need to do this regularly, because simplification can -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply -- miss the rules for Ids hidden inside imported inlinings ``` Given the previous commit, the loading of unfoldings is now even more delayed so we need to be more careful to read the EPS rule base closer to the point where we decide to try rules. Without this fix GHC performance regressed by a noticeably amount because the `zip` rule was not brought into scope eagerly enough which led to a further series of unfortunate events in the simplifer which tipped `substTyWithCoVars` over the edge of the size threshold, stopped it being inlined and increased allocations by 10% in some cases. Furthermore, this change is noticeably in the testsuite as it changes T19790 so that the `length` rules from GHC.List fires earlier. ------------------------- Metric Increase: T9961 ------------------------- - - - - - b8046195 by Matthew Pickering at 2022-02-26T02:06:52-05:00 Improve efficiency of extending a RuleEnv with a new RuleBase Essentially we apply the identity: > lookupNameEnv n (plusNameEnv_C (++) rb1 rb2) > = lookupNameEnv n rb1 ++ lookupNameEnv n rb2 The latter being more efficient as we don't construct an intermediate map. This is now quite important as each time we try and apply rules we need to combine the current EPS RuleBase with the HPT and ModGuts rule bases. - - - - - 033e9f0f by sheaf at 2022-02-26T02:07:30-05:00 Error on anon wildcards in tcAnonWildCardOcc The code in tcAnonWildCardOcc assumed that it could never encounter anonymous wildcards in illegal positions, because the renamer would have ruled them out. However, it's possible to sneak past the checks in the renamer by using Template Haskell. It isn't possible to simply pass on additional information when renaming Template Haskell brackets, because we don't know in advance in what context the bracket will be spliced in (see test case T15433b). So we accept that we might encounter these bogus wildcards in the typechecker and throw the appropriate error. This patch also migrates the error messages for illegal wildcards in types to use the diagnostic infrastructure. Fixes #15433 - - - - - 32d8fe3a by sheaf at 2022-02-26T14:15:33+01:00 Core Lint: ensure primops can be eta-expanded This patch adds a check to Core Lint, checkCanEtaExpand, which ensures that primops and other wired-in functions with no binding such as unsafeCoerce#, oneShot, rightSection... can always be eta-expanded, by checking that the remaining argument types have a fixed RuntimeRep. Two subtleties came up: - the notion of arity in Core looks through newtypes, so we may need to unwrap newtypes in this check, - we want to avoid calling hasNoBinding on something whose unfolding we are in the process of linting, as this would cause a loop; to avoid this we add some information to the Core Lint environment that holds this information. Fixes #20480 - - - - - 0a80b436 by Peter Trommler at 2022-02-26T17:21:59-05:00 testsuite: Require LLVM for T15155l - - - - - 38cb920e by Oleg Grenrus at 2022-02-28T07:14:04-05:00 Add Monoid a => Monoid (STM a) instance - - - - - d734ef8f by Hécate Moonlight at 2022-02-28T07:14:42-05:00 Make modules in base stable. fix #18963 - - - - - fbf005e9 by Sven Tennie at 2022-02-28T19:16:01-05:00 Fix some hlint issues in ghc-heap This does not fix all hlint issues as the criticised index and length expressions seem to be fine in context. - - - - - adfddf7d by Matthew Pickering at 2022-02-28T19:16:36-05:00 hadrian: Suggest to the user to run ./configure if missing a setting If a setting is missing from the configuration file it's likely the user needs to reconfigure. Fixes #20476 - - - - - 4f0208e5 by Andreas Klebinger at 2022-02-28T19:17:12-05:00 CLabel cleanup: Remove these smart constructors for these reasons: * mkLocalClosureTableLabel : Does the same as the non-local variant. * mkLocalClosureLabel : Does the same as the non-local variant. * mkLocalInfoTableLabel : Decide if we make a local label based on the name and just use mkInfoTableLabel everywhere. - - - - - 065419af by Matthew Pickering at 2022-02-28T19:17:47-05:00 linking: Don't pass --hash-size and --reduce-memory-overhead to ld These flags were added to help with the high linking cost of the old split-objs mode. Now we are using split-sections these flags appear to make no difference to memory usage or time taken to link. I tested various configurations linking together the ghc library with -split-sections enabled. | linker | time (s) | | ------ | ------ | | gold | 0.95 | | ld | 1.6 | | ld (hash-size = 31, reduce-memory-overheads) | 1.6 | | ldd | 0.47 | Fixes #20967 - - - - - 3e65ef05 by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix typo in docstring for Overlap - - - - - 80f9133e by Teo Camarasu at 2022-02-28T19:18:27-05:00 template-haskell: fix docstring for Bytes It seems like a commented out section of code was accidentally included in the docstring for a field. - - - - - 54774268 by Matthew Pickering at 2022-03-01T16:23:10-05:00 Fix longstanding issue with moduleGraphNodes - no hs-boot files case In the case when we tell moduleGraphNodes to drop hs-boot files the idea is to collapse hs-boot files into their hs file nodes. In the old code * nodeDependencies changed edges from IsBoot to NonBoot * moduleGraphNodes just dropped boot file nodes The net result is that any dependencies of the hs-boot files themselves were dropped. The correct thing to do is * nodeDependencies changes edges from IsBoot to NonBoot * moduleGraphNodes merges dependencies of IsBoot and NonBoot nodes. The result is a properly quotiented dependency graph which contains no hs-boot files nor hs-boot file edges. Why this didn't cause endless issues when compiling with boot files, we will never know. - - - - - c84dc506 by Matthew Pickering at 2022-03-01T16:23:10-05:00 driver: Properly add an edge between a .hs and its hs-boot file As noted in #21071 we were missing adding this edge so there were situations where the .hs file would get compiled before the .hs-boot file which leads to issues with -j. I fixed this properly by adding the edge in downsweep so the definition of nodeDependencies can be simplified to avoid adding this dummy edge in. There are plenty of tests which seem to have these redundant boot files anyway so no new test. #21094 tracks the more general issue of identifying redundant hs-boot and SOURCE imports. - - - - - 7aeb6d29 by sheaf at 2022-03-01T16:23:51-05:00 Core Lint: collect args through floatable ticks We were not looking through floatable ticks when collecting arguments in Core Lint, which caused `checkCanEtaExpand` to fail on something like: ```haskell reallyUnsafePtrEquality = \ @a -> (src<loc> reallyUnsafePtrEquality#) @Lifted @a @Lifted @a ``` We fix this by using `collectArgsTicks tickishFloatable` instead of `collectArgs`, to be consistent with the behaviour of eta expansion outlined in Note [Eta expansion and source notes] in GHC.Core.Opt.Arity. Fixes #21152. - - - - - 75caafaa by Matthew Pickering at 2022-03-02T01:14:59-05:00 Ticky profiling improvements. This adds a number of changes to ticky-ticky profiling. When an executable is profiled with IPE profiling it's now possible to associate id-related ticky counters to their source location. This works by emitting the info table address as part of the counter which can be looked up in the IPE table. Add a `-ticky-ap-thunk` flag. This flag prevents the use of some standard thunks which are precompiled into the RTS. This means reduced cache locality and increased code size. But it allows better attribution of execution cost to specific source locations instead of simple attributing it to the standard thunk. ticky-ticky now uses the `arg` field to emit additional information about counters in json format. When ticky-ticky is used in combination with the eventlog eventlog2html can be used to generate a html table from the eventlog similar to the old text output for ticky-ticky. - - - - - aeea6bd5 by doyougnu at 2022-03-02T01:15:39-05:00 StgToCmm.cgTopBinding: no isNCG, use binBlobThresh This is a one line change. It is a fixup from MR!7325, was pointed out in review of MR!7442, specifically: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7442#note_406581 The change removes isNCG check from cgTopBinding. Instead it changes the type of binBlobThresh in DynFlags from Word to Maybe Word, where a Just 0 or a Nothing indicates an infinite threshold and thus the disable CmmFileEmbed case in the original check. This improves the cohesion of the module because more NCG related Backend stuff is moved into, and checked in, StgToCmm.Config. Note, that the meaning of a Just 0 or a Nothing in binBlobThresh is indicated in a comment next to its field in GHC.StgToCmm.Config. DynFlags: binBlobThresh: Word -> Maybe Word StgToCmm.Config: binBlobThesh add not ncg check DynFlags.binBlob: move Just 0 check to dflags init StgToCmm.binBlob: only check isNCG, Just 0 check to dflags StgToCmm.Config: strictify binBlobThresh - - - - - b27b2af3 by sheaf at 2022-03-02T14:08:36-05:00 Introduce ConcreteTv metavariables This patch introduces a new kind of metavariable, by adding the constructor `ConcreteTv` to `MetaInfo`. A metavariable with `ConcreteTv` `MetaInfo`, henceforth a concrete metavariable, can only be unified with a type that is concrete (that is, a type that answers `True` to `GHC.Core.Type.isConcrete`). This solves the problem of dangling metavariables in `Concrete#` constraints: instead of emitting `Concrete# ty`, which contains a secret existential metavariable, we simply emit a primitive equality constraint `ty ~# concrete_tv` where `concrete_tv` is a fresh concrete metavariable. This means we can avoid all the complexity of canonicalising `Concrete#` constraints, as we can just re-use the existing machinery for `~#`. To finish things up, this patch then removes the `Concrete#` special predicate, and instead introduces the special predicate `IsRefl#` which enforces that a coercion is reflexive. Such a constraint is needed because the canonicaliser is quite happy to rewrite an equality constraint such as `ty ~# concrete_tv`, but such a rewriting is not handled by the rest of the compiler currently, as we need to make use of the resulting coercion, as outlined in the FixedRuntimeRep plan. The big upside of this approach (on top of simplifying the code) is that we can now selectively implement PHASE 2 of FixedRuntimeRep, by changing individual calls of `hasFixedRuntimeRep_MustBeRefl` to `hasFixedRuntimeRep` and making use of the obtained coercion. - - - - - 81b7c436 by Matthew Pickering at 2022-03-02T14:09:13-05:00 Make -dannot-lint not panic on let bound type variables After certain simplifier passes we end up with let bound type variables which are immediately inlined in the next pass. The core diff utility implemented by -dannot-lint failed to take these into account and paniced. Progress towards #20965 - - - - - f596c91a by sheaf at 2022-03-02T14:09:51-05:00 Improve out-of-order inferred type variables Don't instantiate type variables for :type in `GHC.Tc.Gen.App.tcInstFun`, to avoid inconsistently instantianting `r1` but not `r2` in the type forall {r1} (a :: TYPE r1) {r2} (b :: TYPE r2). ... This fixes #21088. This patch also changes the primop pretty-printer to ensure that we put all the inferred type variables first. For example, the type of reallyUnsafePtrEquality# is now forall {l :: Levity} {k :: Levity} (a :: TYPE (BoxedRep l)) (b :: TYPE (BoxedRep k)). a -> b -> Int# This means we avoid running into issue #21088 entirely with the types of primops. Users can still write a type signature where the inferred type variables don't come first, however. This change to primops had a knock-on consequence, revealing that we were sometimes performing eta reduction on keepAlive#. This patch updates tryEtaReduce to avoid eta reducing functions with no binding, bringing it in line with tryEtaReducePrep, and thus fixing #21090. - - - - - 1617fed3 by Richard Eisenberg at 2022-03-02T14:10:28-05:00 Make inert_cycle_breakers into a stack. Close #20231. - - - - - c8652a0a by Richard Eisenberg at 2022-03-02T14:11:03-05:00 Make Constraint not *apart* from Type. More details in Note [coreView vs tcView] Close #21092. - - - - - 91a10cb0 by doyougnu at 2022-03-02T14:11:43-05:00 GenStgAlt 3-tuple synonym --> Record type This commit alters GenStgAlt from a type synonym to a Record with field accessors. In pursuit of #21078, this is not a required change but cleans up several areas for nicer code in the upcoming js-backend, and in GHC itself. GenStgAlt: 3-tuple -> record Stg.Utils: GenStgAlt 3-tuple -> record Stg.Stats: StgAlt 3-tuple --> record Stg.InferTags.Rewrite: StgAlt 3-tuple -> record Stg.FVs: GenStgAlt 3-tuple -> record Stg.CSE: GenStgAlt 3-tuple -> record Stg.InferTags: GenStgAlt 3-tuple --> record Stg.Debug: GenStgAlt 3-tuple --> record Stg.Lift.Analysis: GenStgAlt 3-tuple --> record Stg.Lift: GenStgAlt 3-tuple --> record ByteCode.Instr: GenStgAlt 3-tuple --> record Stg.Syntax: add GenStgAlt helper functions Stg.Unarise: GenStgAlt 3-tuple --> record Stg.BcPrep: GenStgAlt 3-tuple --> record CoreToStg: GenStgAlt 3-tuple --> record StgToCmm.Expr: GenStgAlt 3-tuple --> record StgToCmm.Bind: GenStgAlt 3-tuple --> record StgToByteCode: GenStgAlt 3-tuple --> record Stg.Lint: GenStgAlt 3-tuple --> record Stg.Syntax: strictify GenStgAlt GenStgAlt: add haddock, some cleanup fixup: remove calls to pure, single ViewPattern StgToByteCode: use case over viewpatterns - - - - - 73864f00 by Matthew Pickering at 2022-03-02T14:12:19-05:00 base: Remove default method from bitraversable The default instance leads to an infinite loop. bisequenceA is defined in terms of bisquence which is defined in terms of bitraverse. ``` bitraverse f g = (defn of bitraverse) bisequenceA . bimap f g = (defn of bisequenceA) bitraverse id id . bimap f g = (defn of bitraverse) ... ``` Any instances defined without an explicitly implementation are currently broken, therefore removing it will alert users to an issue in their code. CLC issue: https://github.com/haskell/core-libraries-committee/issues/47 Fixes #20329 #18901 - - - - - 9579bf35 by Matthew Pickering at 2022-03-02T14:12:54-05:00 ci: Add check to CI to ensure compiler uses correct BIGNUM_BACKEND - - - - - c48a7c3a by Sylvain Henry at 2022-03-03T07:37:12-05:00 Use Word64# primops in Word64 Num instance Taken froù!3658 - - - - - ce65d0cc by Matthew Pickering at 2022-03-03T07:37:48-05:00 hadrian: Correctly set whether we have a debug compiler when running tests For example, running the `slow-validate` flavour would incorrectly run the T16135 test which would fail with an assertion error, despite the fact that is should be skipped when we have a debug compiler. - - - - - e0c3e757 by Matthew Pickering at 2022-03-03T13:48:41-05:00 docs: Add note to unsafeCoerce function that you might want to use coerce [skip ci] Fixes #15429 - - - - - 559d4cf3 by Matthew Pickering at 2022-03-03T13:49:17-05:00 docs: Add note to RULES documentation about locally bound variables [skip ci] Fixes #20100 - - - - - c534b3dd by Matthew Pickering at 2022-03-03T13:49:53-05:00 Replace ad-hoc CPP with constant from GHC.Utils.Constant Fixes #21154 - - - - - de56cc7e by Krzysztof Gogolewski at 2022-03-04T12:44:26-05:00 Update documentation of LiberalTypeSynonyms We no longer require LiberalTypeSynonyms to use 'forall' or an unboxed tuple in a synonym. I also removed that kind checking before expanding synonyms "could be changed". This was true when type synonyms were thought of macros, but with the extensions such as SAKS or matchability I don't see it changing. - - - - - c0a39259 by Simon Jakobi at 2022-03-04T12:45:01-05:00 base: Mark GHC.Bits not-home for haddock Most (all) of the exports are re-exported from the preferable Data.Bits. - - - - - 3570eda5 by Sylvain Henry at 2022-03-04T12:45:42-05:00 Fix comments about Int64/Word64 primops - - - - - 6f84ee33 by Artem Pelenitsyn at 2022-03-05T01:06:47-05:00 remove MonadFail instances of ST CLC proposal: https://github.com/haskell/core-libraries-committee/issues/33 The instances had `fail` implemented in terms of `error`, whereas the idea of the `MonadFail` class is that the `fail` method should be implemented in terms of the monad itself. - - - - - 584cd5ae by sheaf at 2022-03-05T01:07:25-05:00 Don't allow Float#/Double# literal patterns This patch does the following two things: 1. Fix the check in Core Lint to properly throw an error when it comes across Float#/Double# literal patterns. The check was incorrect before, because it expected the type to be Float/Double instead of Float#/Double#. 2. Add an error in the parser when the user writes a floating-point literal pattern such as `case x of { 2.0## -> ... }`. Fixes #21115 - - - - - 706deee0 by Greg Steuck at 2022-03-05T17:44:10-08:00 Make T20214 terminate promptly be setting input to /dev/null It was hanging and timing out on OpenBSD before. - - - - - 14e90098 by Simon Peyton Jones at 2022-03-07T14:05:41-05:00 Always generalise top-level bindings Fix #21023 by always generalising top-level binding; change the documentation of -XMonoLocalBinds to match. - - - - - c9c31c3c by Matthew Pickering at 2022-03-07T14:06:16-05:00 hadrian: Add little flavour transformer to build stage2 with assertions This can be useful to build a `perf+assertions` build or even better `default+no_profiled_libs+omit_pragmas+assertions`. - - - - - 89c14a6c by Matthew Pickering at 2022-03-07T14:06:16-05:00 ci: Convert all deb10 make jobs into hadrian jobs This is the first step in converting all the CI configs to use hadrian rather than make. (#21129) The metrics increase due to hadrian using --hyperlinked-source for haddock builds. (See #21156) ------------------------- Metric Increase: haddock.Cabal haddock.base haddock.compiler ------------------------- - - - - - 7bfae2ee by Matthew Pickering at 2022-03-07T14:06:16-05:00 Replace use of BIN_DIST_PREP_TAR_COMP with BIN_DIST_NAME And adds a check to make sure we are not accidently settings BIN_DIST_PREP_TAR_COMP when using hadrian. - - - - - 5b35ca58 by Matthew Pickering at 2022-03-07T14:06:16-05:00 Fix gen_contents_index logic for hadrian bindist - - - - - 273bc133 by Krzysztof Gogolewski at 2022-03-07T14:06:52-05:00 Fix reporting constraints in pprTcSolverReportMsg 'no_instance_msg' and 'no_deduce_msg' were omitting the first wanted. - - - - - 5874a30a by Simon Jakobi at 2022-03-07T14:07:28-05:00 Improve setBit for Natural Previously the default definition was used, which involved allocating intermediate Natural values. Fixes #21173. - - - - - 7a02aeb8 by Matthew Pickering at 2022-03-07T14:08:03-05:00 Remove leftover trace in testsuite - - - - - 6ce6c250 by Andreas Klebinger at 2022-03-07T23:48:56-05:00 Expand and improve the Note [Strict Worker Ids]. I've added an explicit mention of the invariants surrounding those. As well as adding more direct cross references to the Strict Field Invariant. - - - - - d0f892fe by Ryan Scott at 2022-03-07T23:49:32-05:00 Delete GenericKind_ in favor of GenericKind_DC When deriving a `Generic1` instance, we need to know what the last type variable of a data type is. Previously, there were two mechanisms to determine this information: * `GenericKind_`, where `Gen1_` stored the last type variable of a data type constructor (i.e., the `tyConTyVars`). * `GenericKind_DC`, where `Gen1_DC` stored the last universally quantified type variable in a data constructor (i.e., the `dataConUnivTyVars`). These had different use cases, as `GenericKind_` was used for generating `Rep(1)` instances, while `GenericKind_DC` was used for generating `from(1)` and `to(1)` implementations. This was already a bit confusing, but things went from confusing to outright wrong after !6976. This is because after !6976, the `deriving` machinery stopped using `tyConTyVars` in favor of `dataConUnivTyVars`. Well, everywhere with the sole exception of `GenericKind_`, which still continued to use `tyConTyVars`. This lead to disaster when deriving a `Generic1` instance for a GADT family instance, as the `tyConTyVars` do not match the `dataConUnivTyVars`. (See #21185.) The fix is to stop using `GenericKind_` and replace it with `GenericKind_DC`. For the most part, this proves relatively straightforward. Some highlights: * The `forgetArgVar` function was deleted entirely, as it no longer proved necessary after `GenericKind_`'s demise. * The substitution that maps from the last type variable to `Any` (see `Note [Generating a correctly typed Rep instance]`) had to be moved from `tc_mkRepTy` to `tc_mkRepFamInsts`, as `tc_mkRepTy` no longer has access to the last type variable. Fixes #21185. - - - - - a60ddffd by Matthew Pickering at 2022-03-08T22:51:37+00:00 Move bootstrap and cabal-reinstall test jobs to nightly CI is creaking under the pressure of too many jobs so attempt to reduce the strain by removing a couple of jobs. - - - - - 7abe3288 by Matthew Pickering at 2022-03-09T10:24:15+00:00 Add 10 minute timeout to linters job - - - - - 3cf75ede by Matthew Pickering at 2022-03-09T10:24:16+00:00 Revert "hadrian: Correctly set whether we have a debug compiler when running tests" Needing the arguments for "GHC/Utils/Constant.hs" implies a dependency on the previous stage compiler. Whilst we work out how to get around this I will just revert this commit (as it only affects running the testsuite in debug way). This reverts commit ce65d0cceda4a028f30deafa3c39d40a250acc6a. - - - - - 18b9ba56 by Matthew Pickering at 2022-03-09T11:07:23+00:00 ci: Fix save_cache function Each interation of saving the cache would copy the whole `cabal` store into a subfolder in the CACHE_DIR rather than copying the contents of the cabal store into the cache dir. This resulted in a cache which looked like: ``` /builds/ghc/ghc/cabal-cache/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/cabal/ ``` So it would get one layer deeper every CI run and take longer and longer to compress. - - - - - bc684dfb by Ben Gamari at 2022-03-10T03:20:07-05:00 mr-template: Mention timeframe for review - - - - - 7f5f4ede by Vladislav Zavialov at 2022-03-10T03:20:43-05:00 Bump submodules: containers, exceptions GHC Proposal #371 requires TypeOperators to use type equality a~b. This submodule update pulls in the appropriate forward-compatibility changes in 'libraries/containers' and 'libraries/exceptions' - - - - - 8532b8a9 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Add an inline pragma to lookupVarEnv The containers bump reduced the size of the Data.IntMap.Internal.lookup function so that it no longer experienced W/W. This means that the size of lookupVarEnv increased over the inlining threshold and it wasn't inlined into the hot code path in substTyVar. See containers#821, #21159 and !7638 for some more explanation. ------------------------- Metric Decrease: LargeRecord T12227 T13386 T15703 T18223 T5030 T8095 T9872a T9872b T9872c TcPlugin_RewritePerf ------------------------- - - - - - 844cf1e1 by Matthew Pickering at 2022-03-10T03:20:43-05:00 Normalise output of T10970 test The output of this test changes each time the containers submodule version updates. It's easier to apply the version normaliser so that the test checks that there is a version number, but not which one it is. - - - - - 24b6af26 by Ryan Scott at 2022-03-11T19:56:28-05:00 Refactor tcDeriving to generate tyfam insts before any bindings Previously, there was an awful hack in `genInst` (now called `genInstBinds` after this patch) where we had to return a continutation rather than directly returning the bindings for a derived instance. This was done for staging purposes, as we had to first infer the instance contexts for derived instances and then feed these contexts into the continuations to ensure the generated instance bindings had accurate instance contexts. `Note [Staging of tcDeriving]` in `GHC.Tc.Deriving` described this confusing state of affairs. The root cause of this confusing design was the fact that `genInst` was trying to generate instance bindings and associated type family instances for derived instances simultaneously. This really isn't possible, however: as `Note [Staging of tcDeriving]` explains, one needs to have access to the associated type family instances before one can properly infer the instance contexts for derived instances. The use of continuation-returning style was an attempt to circumvent this dependency, but it did so in an awkward way. This patch detangles this awkwardness by splitting up `genInst` into two functions: `genFamInsts` (for associated type family instances) and `genInstBinds` (for instance bindings). Now, the `tcDeriving` function calls `genFamInsts` and brings all the family instances into scope before calling `genInstBinds`. This removes the need for the awkward continuation-returning style seen in the previous version of `genInst`, making the code easier to understand. There are some knock-on changes as well: 1. `hasStockDeriving` now needs to return two separate functions: one that describes how to generate family instances for a stock-derived instance, and another that describes how to generate the instance bindings. I factored out this pattern into a new `StockGenFns` data type. 2. While documenting `StockGenFns`, I realized that there was some inconsistency regarding which `StockGenFns` functions needed which arguments. In particular, the function in `GHC.Tc.Deriv.Generics` which generates `Rep(1)` instances did not take a `SrcSpan` like other `gen_*` functions did, and it included an extra `[Type]` argument that was entirely redundant. As a consequence, I refactored the code in `GHC.Tc.Deriv.Generics` to more closely resemble other `gen_*` functions. A happy result of all this is that all `StockGenFns` functions now take exactly the same arguments, which makes everything more uniform. This is purely a refactoring that should not have any effect on user-observable behavior. The new design paves the way for an eventual fix for #20719. - - - - - 62caaa9b by Ben Gamari at 2022-03-11T19:57:03-05:00 gitlab-ci: Use the linters image in hlint job As the `hlint` executable is only available in the linters image. Fixes #21146. - - - - - 4abd7eb0 by Matthew Pickering at 2022-03-11T19:57:38-05:00 Remove partOfGhci check in the loader This special logic has been part of GHC ever since template haskell was introduced in 9af77fa423926fbda946b31e174173d0ec5ebac8. It's hard to believe in any case that this special logic pays its way at all. Given * The list is out-of-date, which has potential to lead to miscompilation when using "editline", which was removed in 2010 (46aed8a4). * The performance benefit seems negligable as each load only happens once anyway and packages specified by package flags are preloaded into the linker state at the start of compilation. Therefore we just remove this logic. Fixes #19791 - - - - - c40cbaa2 by Andreas Klebinger at 2022-03-11T19:58:14-05:00 Improve -dtag-inference-checks checks. FUN closures don't get tagged when evaluated. So no point in checking their tags. - - - - - ab00d23b by Simon Jakobi at 2022-03-11T19:58:49-05:00 Improve clearBit and complementBit for Natural Also optimize bigNatComplementBit#. Fixes #21175, #21181, #21194. - - - - - a6d8facb by Sebastian Graf at 2022-03-11T19:59:24-05:00 gitignore all (build) directories headed by _ - - - - - 524795fe by Sebastian Graf at 2022-03-11T19:59:24-05:00 Demand: Document why we need three additional equations of multSubDmd - - - - - 6bdcd557 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make 64-bit word splitting for 32-bit targets respect target endianness This used to been broken for little-endian targets. - - - - - 9e67c69e by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix Double# literal payload for 32-bit targets Contrary to the legacy comment, the splitting didn't happen and we ended up with a single StgWord64 literal in the output code! Let's just do the splitting here. - - - - - 1eee2e28 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: use __builtin versions of memcpyish functions to fix type mismatch Our memcpyish primop's type signatures doesn't match the C type signatures. It's not a problem for typical archs, since their C ABI permits dropping the result, but it doesn't work for wasm. The previous logic would cast the memcpyish function pointer to an incorrect type and perform an indirect call, which results in a runtime trap on wasm. The most straightforward fix is: don't emit EFF_ for memcpyish functions. Since we don't want to include extra headers in .hc to bring in their prototypes, we can just use the __builtin versions. - - - - - 9d8d4837 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: emit __builtin_unreachable() when CmmSwitch doesn't contain fallback case Otherwise the C compiler may complain "warning: non-void function does not return a value in all control paths [-Wreturn-type]". - - - - - 27da5540 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: make floatToWord32/doubleToWord64 faster Use castFloatToWord32/castDoubleToWord64 in base to perform the reinterpret cast. - - - - - c98e8332 by Cheng Shao at 2022-03-11T20:00:01-05:00 CmmToC: fix -Wunused-value warning in ASSIGN_BaseReg When ASSIGN_BaseReg is a no-op, we shouldn't generate any C code, otherwise C compiler complains a bunch of -Wunused-value warnings when doing unregisterised codegen. - - - - - 5932247c by Ben Gamari at 2022-03-11T20:00:36-05:00 users guide: Eliminate spurious \spxentry mentions We were failing to pass the style file to `makeindex`, as is done by the mklatex configuration generated by Sphinx. Fixes #20913. - - - - - e40cf4ef by Simon Jakobi at 2022-03-11T20:01:11-05:00 ghc-bignum: Tweak integerOr The result of ORing two BigNats is always greater or equal to the larger of the two. Therefore it is safe to skip the magnitude checks of integerFromBigNat#. - - - - - cf081476 by Vladislav Zavialov at 2022-03-12T07:02:40-05:00 checkUnboxedLitPat: use non-fatal addError This enables GHC to report more parse errors in a single pass. - - - - - 7fe07143 by Andreas Klebinger at 2022-03-12T07:03:16-05:00 Rename -fprof-late-ccs to -fprof-late - - - - - 88a94541 by Sylvain Henry at 2022-03-12T07:03:56-05:00 Hadrian: avoid useless allocations in trackArgument Cf ticky report before the change: Entries Alloc Alloc'd Non-void Arguments STG Name -------------------------------------------------------------------------------- 696987 29044128 0 1 L main:Target.trackArgument_go5{v r24kY} (fun) - - - - - 2509d676 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: avoid allocating in stageString (#19209) - - - - - c062fac0 by Sylvain Henry at 2022-03-12T07:04:36-05:00 Hadrian: remove useless imports Added for no reason in 7ce1b694f7be7fbf6e2d7b7eb0639e61fbe358c6 - - - - - c82fb934 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: avoid allocations in WayUnit's Read instance (#19209) - - - - - ed04aed2 by Sylvain Henry at 2022-03-12T07:05:16-05:00 Hadrian: use IntSet Binary instance for Way (#19209) - - - - - ad835531 by Simon Peyton Jones at 2022-03-13T18:12:12-04:00 Fix bug in weak loop-breakers in OccurAnal Note [Weak loop breakers] explains why we need to track variables free in RHS of rules. But we need to do this for /inactive/ rules as well as active ones, unlike the rhs_fv_env stuff. So we now have two fields in node Details, one for free vars of active rules, and one for free vars of all rules. This was shown up by #20820, which is now fixed. - - - - - 76b94b72 by Sebastian Graf at 2022-03-13T18:12:48-04:00 Worker/wrapper: Preserve float barriers (#21150) Issue #21150 shows that worker/wrapper allocated a worker function for a function with multiple calls that said "called at most once" when the first argument was absent. That's bad! This patch makes it so that WW preserves at least one non-one-shot value lambda (see `Note [Preserving float barriers]`) by passing around `void#` in place of absent arguments. Fixes #21150. Since the fix is pretty similar to `Note [Protecting the last value argument]`, I put the logic in `mkWorkerArgs`. There I realised (#21204) that `-ffun-to-thunk` is basically useless with `-ffull-laziness`, so I deprecated the flag, simplified and split into `needsVoidWorkerArg`/`addVoidWorkerArg`. SpecConstr is another client of that API. Fixes #21204. Metric Decrease: T14683 - - - - - 97db789e by romes at 2022-03-14T11:36:39-04:00 Fix up Note [Bind free vars] Move GHC-specific comments from Language.Haskell.Syntax.Binds to GHC.Hs.Binds It looks like the Note was deleted but there were actually two copies of it. L.H.S.B no longer references it, and GHC.Hs.Binds keeps an updated copy. (See #19252) There are other duplicated notes -- they will be fixed in the next commit - - - - - 135888dd by romes at 2022-03-14T11:36:39-04:00 TTG Pull AbsBinds and ABExport out of the main AST AbsBinds and ABExport both depended on the typechecker, and were thus removed from the main AST Expr. CollectPass now has a new function `collectXXHsBindsLR` used for the new HsBinds extension point Bumped haddock submodule to work with AST changes. The removed Notes from Language.Haskell.Syntax.Binds were duplicated (and not referenced) and the copies in GHC.Hs.Binds are kept (and referenced there). (See #19252) - - - - - 106413f0 by sheaf at 2022-03-14T11:37:21-04:00 Add two coercion optimisation perf tests - - - - - 8eadea67 by sheaf at 2022-03-14T15:08:24-04:00 Fix isLiftedType_maybe and handle fallout As #20837 pointed out, `isLiftedType_maybe` returned `Just False` in many situations where it should return `Nothing`, because it didn't take into account type families or type variables. In this patch, we fix this issue. We rename `isLiftedType_maybe` to `typeLevity_maybe`, which now returns a `Levity` instead of a boolean. We now return `Nothing` for types with kinds of the form `TYPE (F a1 ... an)` for a type family `F`, as well as `TYPE (BoxedRep l)` where `l` is a type variable. This fix caused several other problems, as other parts of the compiler were relying on `isLiftedType_maybe` returning a `Just` value, and were now panicking after the above fix. There were two main situations in which panics occurred: 1. Issues involving the let/app invariant. To uphold that invariant, we need to know whether something is lifted or not. If we get an answer of `Nothing` from `isLiftedType_maybe`, then we don't know what to do. As this invariant isn't particularly invariant, we can change the affected functions to not panic, e.g. by behaving the same in the `Just False` case and in the `Nothing` case (meaning: no observable change in behaviour compared to before). 2. Typechecking of data (/newtype) constructor patterns. Some programs involving patterns with unknown representations were accepted, such as T20363. Now that we are stricter, this caused further issues, culminating in Core Lint errors. However, the behaviour was incorrect the whole time; the incorrectness only being revealed by this change, not triggered by it. This patch fixes this by overhauling where the representation polymorphism involving pattern matching are done. Instead of doing it in `tcMatches`, we instead ensure that the `matchExpected` functions such as `matchExpectedFunTys`, `matchActualFunTySigma`, `matchActualFunTysRho` allow return argument pattern types which have a fixed RuntimeRep (as defined in Note [Fixed RuntimeRep]). This ensures that the pattern matching code only ever handles types with a known runtime representation. One exception was that patterns with an unknown representation type could sneak in via `tcConPat`, which points to a missing representation-polymorphism check, which this patch now adds. This means that we now reject the program in #20363, at least until we implement PHASE 2 of FixedRuntimeRep (allowing type families in RuntimeRep positions). The aforementioned refactoring, in which checks have been moved to `matchExpected` functions, is a first step in implementing PHASE 2 for patterns. Fixes #20837 - - - - - 8ff32124 by Sebastian Graf at 2022-03-14T15:09:01-04:00 DmdAnal: Don't unbox recursive data types (#11545) As `Note [Demand analysis for recursive data constructors]` describes, we now refrain from unboxing recursive data type arguments, for two reasons: 1. Relating to run/alloc perf: Similar to `Note [CPR for recursive data constructors]`, it seldomly improves run/alloc performance if we just unbox a finite number of layers of a potentially huge data structure. 2. Relating to ghc/alloc perf: Inductive definitions on single-product recursive data types like the one in T11545 will (diverge, and) have very deep demand signatures before any other abortion mechanism in Demand analysis is triggered. That leads to great and unnecessary churn on Demand analysis when ultimately we will never make use of any nested strictness information anyway. Conclusion: Discard nested demand and boxity information on such recursive types with the help of `Note [Detecting recursive data constructors]`. I also implemented `GHC.Types.Unique.MemoFun.memoiseUniqueFun` in order to avoid the overhead of repeated calls to `GHC.Core.Opt.WorkWrap.Utils.isRecDataCon`. It's nice and simple and guards against some smaller regressions in T9233 and T16577. ghc/alloc performance-wise, this patch is a very clear win: Test Metric value New value Change --------------------------------------------------------------------------------------- LargeRecord(normal) ghc/alloc 6,141,071,720 6,099,871,216 -0.7% MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,740,973,040 2,705,146,640 -1.3% T11545(normal) ghc/alloc 945,475,492 85,768,928 -90.9% GOOD T13056(optasm) ghc/alloc 370,245,880 326,980,632 -11.7% GOOD T18304(normal) ghc/alloc 90,933,944 76,998,064 -15.3% GOOD T9872a(normal) ghc/alloc 1,800,576,840 1,792,348,760 -0.5% T9872b(normal) ghc/alloc 2,086,492,432 2,073,991,848 -0.6% T9872c(normal) ghc/alloc 1,750,491,240 1,737,797,832 -0.7% TcPlugin_RewritePerf(normal) ghc/alloc 2,286,813,400 2,270,957,896 -0.7% geo. mean -2.9% No noteworthy change in run/alloc either. NoFib results show slight wins, too: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- constraints -1.9% -1.4% fasta -3.6% -2.7% reverse-complem -0.3% -0.9% treejoin -0.0% -0.3% -------------------------------------------------------------------------------- Min -3.6% -2.7% Max +0.1% +0.1% Geometric Mean -0.1% -0.1% Metric Decrease: T11545 T13056 T18304 - - - - - ab618309 by Vladislav Zavialov at 2022-03-15T18:34:38+03:00 Export (~) from Data.Type.Equality (#18862) * Users can define their own (~) type operator * Haddock can display documentation for the built-in (~) * New transitional warnings implemented: -Wtype-equality-out-of-scope -Wtype-equality-requires-operators Updates the haddock submodule. - - - - - 577135bf by Aaron Allen at 2022-03-16T02:27:48-04:00 Convert Diagnostics in GHC.Tc.Gen.Foreign Converts all uses of 'TcRnUnknownMessage' to proper diagnostics. - - - - - c1fed9da by Aaron Allen at 2022-03-16T02:27:48-04:00 Suggest FFI extensions as hints (#20116) - Use extension suggestion hints instead of suggesting extensions in the error message body for several FFI errors. - Adds a test case for `TcRnForeignImportPrimExtNotSet` - - - - - a33d1045 by Zubin Duggal at 2022-03-16T02:28:24-04:00 TH: allow negative patterns in quotes (#20711) We still don't allow negative overloaded patterns. Earler all negative patterns were treated as negative overloaded patterns. Now, we expliclty check the extension field to see if the pattern is actually a negative overloaded pattern - - - - - 1575c4a5 by Sebastian Graf at 2022-03-16T02:29:03-04:00 Demand: Let `Boxed` win in `lubBoxity` (#21119) Previously, we let `Unboxed` win in `lubBoxity`, which is unsoundly optimistic in terms ob Boxity analysis. "Unsoundly" in the sense that we sometimes unbox parameters that we better shouldn't unbox. Examples are #18907 and T19871.absent. Until now, we thought that this hack pulled its weight becuase it worked around some shortcomings of the phase separation between Boxity analysis and CPR analysis. But it is a gross hack which caused regressions itself that needed all kinds of fixes and workarounds. See for example #20767. It became impossible to work with in !7599, so I want to remove it. For example, at the moment, `lubDmd B dmd` will not unbox `dmd`, but `lubDmd A dmd` will. Given that `B` is supposed to be the bottom element of the lattice, it's hardly justifiable to get a better demand when `lub`bing with `A`. The consequence of letting `Boxed` win in `lubBoxity` is that we *would* regress #2387, #16040 and parts of #5075 and T19871.sumIO, until Boxity and CPR are able to communicate better. Fortunately, that is not the case since I could tweak the other source of optimism in Boxity analysis that is described in `Note [Unboxed demand on function bodies returning small products]` so that we *recursively* assume unboxed demands on function bodies returning small products. See the updated Note. `Note [Boxity for bottoming functions]` describes why we need bottoming functions to have signatures that say that they deeply unbox their arguments. In so doing, I had to tweak `finaliseArgBoxities` so that it will never unbox recursive data constructors. This is in line with our handling of them in CPR. I updated `Note [Which types are unboxed?]` to reflect that. In turn we fix #21119, #20767, #18907, T19871.absent and get a much simpler implementation (at least to think about). We can also drop the very ad-hoc definition of `deferAfterPreciseException` and its Note in favor of the simple, intuitive definition we used to have. Metric Decrease: T16875 T18223 T18698a T18698b hard_hole_fits Metric Increase: LargeRecord MultiComponentModulesRecomp T15703 T8095 T9872d Out of all the regresions, only the one in T9872d doesn't vanish in a perf build, where the compiler is bootstrapped with -O2 and thus SpecConstr. Reason for regressions: * T9872d is due to `ty_co_subst` taking its `LiftingContext` boxed. That is because the context is passed to a function argument, for example in `liftCoSubstTyVarBndrUsing`. * In T15703, LargeRecord and T8095, we get a bit more allocations in `expand_syn` and `piResultTys`, because a `TCvSubst` isn't unboxed. In both cases that guards against reboxing in some code paths. * The same is true for MultiComponentModulesRecomp, where we get less unboxing in `GHC.Unit.Finder.$wfindInstalledHomeModule`. In a perf build, allocations actually *improve* by over 4%! Results on NoFib: -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- awards -0.4% +0.3% cacheprof -0.3% +2.4% fft -1.5% -5.1% fibheaps +1.2% +0.8% fluid -0.3% -0.1% ida +0.4% +0.9% k-nucleotide +0.4% -0.1% last-piece +10.5% +13.9% lift -4.4% +3.5% mandel2 -99.7% -99.8% mate -0.4% +3.6% parser -1.0% +0.1% puzzle -11.6% +6.5% reverse-complem -3.0% +2.0% scs -0.5% +0.1% sphere -0.4% -0.2% wave4main -8.2% -0.3% -------------------------------------------------------------------------------- Summary excludes mandel2 because of excessive bias Min -11.6% -5.1% Max +10.5% +13.9% Geometric Mean -0.2% +0.3% -------------------------------------------------------------------------------- Not bad for a bug fix. The regression in `last-piece` could become a win if SpecConstr would work on non-recursive functions. The regression in `fibheaps` is due to `Note [Reboxed crud for bottoming calls]`, e.g., #21128. - - - - - bb779b90 by sheaf at 2022-03-16T02:29:42-04:00 Add a regression test for #21130 This problem was due to a bug in cloneWanted, which was incorrectly creating a coercion hole to hold an evidence variable. This bug was introduced by 8bb52d91 and fixed in 81740ce8. Fixes #21130 - - - - - 0f0e2394 by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Initial Windows C++ exception unwinding support - - - - - 36d20d4d by Tamar Christina at 2022-03-17T10:16:37-04:00 linker: Fix ADDR32NB relocations on Windows - - - - - 8a516527 by Tamar Christina at 2022-03-17T10:16:37-04:00 testsuite: properly escape string paths - - - - - 1a0dd008 by sheaf at 2022-03-17T10:17:13-04:00 Hadrian: account for change in late-ccs flag The late cost centre flag was renamed from -fprof-late-ccs to -fprof-late in 7fe07143, but this change hadn't been propagated to Hadrian. - - - - - 8561c1af by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor HsBracket - - - - - 19163397 by romes at 2022-03-18T05:10:58-04:00 Type-checking untyped brackets When HsExpr GhcTc, the HsBracket constructor should hold a HsBracket GhcRn, rather than an HsBracket GhcTc. We make use of the HsBracket p extension constructor (XBracket (XXBracket p)) to hold an HsBracket GhcRn when the pass is GhcTc See !4782 https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - 310890a5 by romes at 2022-03-18T05:10:58-04:00 Separate constructors for typed and untyped brackets Split HsBracket into HsTypedBracket and HsUntypedBracket. Unfortunately, we still cannot get rid of instance XXTypedBracket GhcTc = HsTypedBracket GhcRn despite no longer requiring it for typechecking, but rather because the TH desugarer works on GhcRn rather than GhcTc (See GHC.HsToCore.Quote) - - - - - 4a2567f5 by romes at 2022-03-18T05:10:58-04:00 TTG: Refactor bracket for desugaring during tc When desugaring a bracket we want to desugar /renamed/ rather than /typechecked/ code; So in (HsExpr GhcTc) tree, we must have a (HsExpr GhcRn) for the quotation itself. This commit reworks the TTG refactor on typed and untyped brackets by storing the /renamed/ code in the bracket field extension rather than in the constructor extension in `HsQuote` (previously called `HsUntypedBracket`) See Note [The life cycle of a TH quotation] and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - b056adc8 by romes at 2022-03-18T05:10:58-04:00 TTG: Make HsQuote GhcTc isomorphic to NoExtField An untyped bracket `HsQuote p` can never be constructed with `p ~ GhcTc`. This is because we don't typecheck `HsQuote` at all. That's OK, because we also never use `HsQuote GhcTc`. To enforce this at the type level we make `HsQuote GhcTc` isomorphic to `NoExtField` and impossible to construct otherwise, by using TTG field extensions to make all constructors, except for `XQuote` (which takes `NoExtField`), unconstructable, with `DataConCantHappen` This is explained more in detail in Note [The life cycle of a TH quotation] Related discussion: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782 - - - - - ac3b2e7d by romes at 2022-03-18T05:10:58-04:00 TTG: TH brackets finishing touches Rewrite the critical notes and fix outdated ones, use `HsQuote GhcRn` (in `HsBracketTc`) for desugaring regardless of the bracket being typed or untyped, remove unused `EpAnn` from `Hs*Bracket GhcRn`, zonkExpr factor out common brackets code, ppr_expr factor out common brackets code, and fix tests, to finish MR https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4782. ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - d147428a by Ben Gamari at 2022-03-18T05:11:35-04:00 codeGen: Fix signedness of jump table indexing Previously while constructing the jump table index we would zero-extend the discriminant before subtracting the start of the jump-table. This goes subtly wrong in the case of a sub-word, signed discriminant, as described in the included Note. Fix this in both the PPC and X86 NCGs. Fixes #21186. - - - - - 435a3d5d by Ben Gamari at 2022-03-18T05:11:35-04:00 testsuite: Add test for #21186 - - - - - e9d8de93 by Zubin Duggal at 2022-03-19T07:35:49-04:00 TH: Fix pretty printing of newtypes with operators and GADT syntax (#20868) The pretty printer for regular data types already accounted for these, and had some duplication with the newtype pretty printer. Factoring the logic out into a common function and using it for both newtypes and data declarations is enough to fix the bug. - - - - - 244da9eb by sheaf at 2022-03-19T07:36:24-04:00 List GHC.Event.Internal in base.cabal on Windows GHC.Event.Internal was not listed in base.cabal on Windows. This caused undefined reference errors. This patch adds it back, by moving it out of the OS-specific logic in base.cabal. Fixes #21245. - - - - - d1c03719 by Andreas Klebinger at 2022-03-19T07:37:00-04:00 Compact regions: Maintain tags properly Fixes #21251 - - - - - d45bb701 by romes at 2022-03-19T07:37:36-04:00 Remove dead code HsDoRn - - - - - c842611f by nineonine at 2022-03-20T21:16:06-04:00 Revamp derived Eq instance code generation (#17240) This patch improves code generation for derived Eq instances. The idea is to use 'dataToTag' to evaluate both arguments. This allows to 'short-circuit' when tags do not match. Unfortunately, inner evals are still present when we branch on tags. This is due to the way 'dataToTag#' primop evaluates its argument in the code generator. #21207 was created to explore further optimizations. Metric Decrease: LargeRecord - - - - - 52ffd38c by Sylvain Henry at 2022-03-20T21:16:46-04:00 Avoid some SOURCE imports - - - - - b91798be by Zubin Duggal at 2022-03-23T13:39:39-04:00 hi haddock: Lex and store haddock docs in interface files Names appearing in Haddock docstrings are lexed and renamed like any other names appearing in the AST. We currently rename names irrespective of the namespace, so both type and constructor names corresponding to an identifier will appear in the docstring. Haddock will select a given name as the link destination based on its own heuristics. This patch also restricts the limitation of `-haddock` being incompatible with `Opt_KeepRawTokenStream`. The export and documenation structure is now computed in GHC and serialised in .hi files. This can be used by haddock to directly generate doc pages without reparsing or renaming the source. At the moment the operation of haddock is not modified, that's left to a future patch. Updates the haddock submodule with the minimum changes needed. - - - - - 78db231f by Cheng Shao at 2022-03-23T13:40:17-04:00 configure: bump LlvmMaxVersion to 14 LLVM 13.0.0 is released in Oct 2021, and latest head validates against LLVM 13 just fine if LlvmMaxVersion is bumped. - - - - - b06e5dd8 by Adam Sandberg Ericsson at 2022-03-23T13:40:54-04:00 docs: clarify the eventlog format documentation a little bit - - - - - 4dc62498 by Matthew Pickering at 2022-03-23T13:41:31-04:00 Fix behaviour of -Wunused-packages in ghci Ticket #21110 points out that -Wunused-packages behaves a bit unusually in GHCi. Now we define the semantics for -Wunused-packages in interactive mode as follows: * If you use -Wunused-packages on an initial load then the warning is reported. * If you explicitly set -Wunused-packages on the command line then the warning is displayed (until it is disabled) * If you then subsequently modify the set of available targets by using :load or :cd (:cd unloads everything) then the warning is (silently) turned off. This means that every :r the warning is printed if it's turned on (but you did ask for it). Fixes #21110 - - - - - fed05347 by Ben Gamari at 2022-03-23T13:42:07-04:00 rts/adjustor: Place adjustor templates in data section on all OSs In !7604 we started placing adjustor templates in the data section on Linux as some toolchains there reject relocations in the text section. However, it turns out that OpenBSD also exhibits this restriction. Fix this by *always* placing adjustor templates in the data section. Fixes #21155. - - - - - db32bb8c by Zubin Duggal at 2022-03-23T13:42:44-04:00 Improve error message when warning about unsupported LLVM version (#20958) Change the wording to make it clear that the upper bound is non-inclusive. - - - - - f214349a by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Untag function field in scavenge_PAP_payload Previously we failed to untag the function closure when scavenging the payload of a PAP, resulting in an invalid closure pointer being passed to scavenge_large_bitmap and consequently #21254. Fix this. Fixes #21254 - - - - - e6d0e287 by Ben Gamari at 2022-03-23T13:43:20-04:00 rts: Don't mark object code in markCAFs unless necessary Previously `markCAFs` would call `markObjectCode` even in non-major GCs. This is problematic since `prepareUnloadCheck` is not called in such GCs, meaning that the section index has not been updated. Fixes #21254 - - - - - 1a7cf096 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Avoid redundant imports of GHC.Driver.Session Remove GHC.Driver.Session imports that weren't considered as redundant because of the reexport of PlatformConstants. Also remove this reexport as modules using this datatype should import GHC.Platform instead. - - - - - e3f60577 by Sylvain Henry at 2022-03-23T13:44:05-04:00 Reverse dependency between StgToCmm and Runtime.Heap.Layout - - - - - e6585ca1 by Sylvain Henry at 2022-03-23T13:44:46-04:00 Define filterOut with filter filter has fusion rules that filterOut lacks - - - - - c58d008c by Ryan Scott at 2022-03-24T06:10:43-04:00 Fix and simplify DeriveAnyClass's context inference using SubTypePredSpec As explained in `Note [Gathering and simplifying constraints for DeriveAnyClass]` in `GHC.Tc.Deriv.Infer`, `DeriveAnyClass` infers instance contexts by emitting implication constraints. Previously, these implication constraints were constructed by hand. This is a terribly trick thing to get right, as it involves a delicate interplay of skolemisation, metavariable instantiation, and `TcLevel` bumping. Despite much effort, we discovered in #20719 that the implementation was subtly incorrect, leading to valid programs being rejected. While we could scrutinize the code that manually constructs implication constraints and repair it, there is a better, less error-prone way to do things. After all, the heart of `DeriveAnyClass` is generating code which fills in each class method with defaults, e.g., `foo = $gdm_foo`. Typechecking this sort of code is tantamount to calling `tcSubTypeSigma`, as we much ensure that the type of `$gdm_foo` is a subtype of (i.e., more polymorphic than) the type of `foo`. As an added bonus, `tcSubTypeSigma` is a battle-tested function that handles skolemisation, metvariable instantiation, `TcLevel` bumping, and all other means of tricky bookkeeping correctly. With this insight, the solution to the problems uncovered in #20719 is simple: use `tcSubTypeSigma` to check if `$gdm_foo`'s type is a subtype of `foo`'s type. As a side effect, `tcSubTypeSigma` will emit exactly the implication constraint that we were attempting to construct by hand previously. Moreover, it does so correctly, fixing #20719 as a consequence. This patch implements the solution thusly: * The `PredSpec` data type (previously named `PredOrigin`) is now split into `SimplePredSpec`, which directly stores a `PredType`, and `SubTypePredSpec`, which stores the actual and expected types in a subtype check. `SubTypePredSpec` is only used for `DeriveAnyClass`; all other deriving strategies use `SimplePredSpec`. * Because `tcSubTypeSigma` manages the finer details of type variable instantiation and constraint solving under the hood, there is no longer any need to delicately split apart the method type signatures in `inferConstraintsAnyclass`. This greatly simplifies the implementation of `inferConstraintsAnyclass` and obviates the need to store skolems, metavariables, or given constraints in a `ThetaSpec` (previously named `ThetaOrigin`). As a bonus, this means that `ThetaSpec` now simply becomes a synonym for a list of `PredSpec`s, which is conceptually much simpler than it was before. * In `simplifyDeriv`, each `SubTypePredSpec` results in a call to `tcSubTypeSigma`. This is only performed for its side effect of emitting an implication constraint, which is fed to the rest of the constraint solving machinery in `simplifyDeriv`. I have updated `Note [Gathering and simplifying constraints for DeriveAnyClass]` to explain this in more detail. To make the changes in `simplifyDeriv` more manageable, I also performed some auxiliary refactoring: * Previously, every iteration of `simplifyDeriv` was skolemising the type variables at the start, simplifying, and then performing a reverse substitution at the end to un-skolemise the type variables. This is not necessary, however, since we can just as well skolemise once at the beginning of the `deriving` pipeline and zonk the `TcTyVar`s after `simplifyDeriv` is finished. This patch does just that, having been made possible by prior work in !7613. I have updated `Note [Overlap and deriving]` in `GHC.Tc.Deriv.Infer` to explain this, and I have also left comments on the relevant data structures (e.g., `DerivEnv` and `DerivSpec`) to explain when things might be `TcTyVar`s or `TyVar`s. * All of the aforementioned cleanup allowed me to remove an ad hoc deriving-related in `checkImplicationInvariants`, as all of the skolems in a `tcSubTypeSigma`–produced implication constraint should now be `TcTyVar` at the time the implication is created. * Since `simplifyDeriv` now needs a `SkolemInfo` and `UserTypeCtxt`, I have added `ds_skol_info` and `ds_user_ctxt` fields to `DerivSpec` to store these. Similarly, I have also added a `denv_skol_info` field to `DerivEnv`, which ultimately gets used to initialize the `ds_skol_info` in a `DerivSpec`. Fixes #20719. - - - - - 21680fb0 by Sebastian Graf at 2022-03-24T06:11:19-04:00 WorkWrap: Handle partial FUN apps in `isRecDataCon` (#21265) Partial FUN apps like `(->) Bool` aren't detected by `splitFunTy_maybe`. A silly oversight that is easily fixed by replacing `splitFunTy_maybe` with a guard in the `splitTyConApp_maybe` case. But fortunately, Simon nudged me into rewriting the whole `isRecDataCon` function in a way that makes it much shorter and hence clearer which DataCons are actually considered as recursive. Fixes #21265. - - - - - a2937e2b by Matthew Pickering at 2022-03-24T17:13:22-04:00 Add test for T21035 This test checks that you are allowed to explicitly supply object files for dependencies even if you haven't got the shared object for that library yet. Fixes #21035 - - - - - 1756d547 by Matthew Pickering at 2022-03-24T17:13:58-04:00 Add check to ensure we are not building validate jobs for releases - - - - - 99623358 by Matthew Pickering at 2022-03-24T17:13:58-04:00 hadrian: Correct generation of hsc2hs wrapper If you inspect the inside of a wrapper script for hsc2hs you will see that the cflag and lflag values are concatenated incorrectly. ``` HSC2HS_EXTRA="--cflag=-U__i686--lflag=-fuse-ld=gold" ``` It should instead be ``` HSC2HS_EXTRA="--cflag=-U__i686 --lflag=-fuse-ld=gold" ``` Fixes #21221 - - - - - fefd4e31 by Matthew Pickering at 2022-03-24T17:13:59-04:00 testsuite: Remove library dependenices from T21119 These dependencies would affect the demand signature depending on various rules and so on. Fixes #21271 - - - - - 5ff690b8 by Matthew Pickering at 2022-03-24T17:13:59-04:00 ci: Generate jobs for all normal builds and use hadrian for all builds This commit introduces a new script (.gitlab/gen_ci.hs) which generates a yaml file (.gitlab/jobs.yaml) which contains explicit descriptions for all the jobs we want to run. The jobs are separated into three categories: * validate - jobs run on every MR * nightly - jobs run once per day on the master branch * release - jobs for producing release artifacts The generation script is a Haskell program which includes a DSL for specifying the different jobs. The hope is that it's easier to reason about the different jobs and how the variables are merged together rather than the unclear and opaque yaml syntax. The goal is to fix issues like #21190 once and for all.. The `.gitlab/jobs.yaml` can be generated by running the `.gitlab/generate_jobs` script. You have to do this manually. Another consequence of this patch is that we use hadrian for all the validate, nightly and release builds on all platforms. - - - - - 1d673aa2 by Christiaan Baaij at 2022-03-25T11:35:49-04:00 Add the OPAQUE pragma A new pragma, `OPAQUE`, that ensures that every call of a named function annotated with an `OPAQUE` pragma remains a call of that named function, not some name-mangled variant. Implements GHC proposal 0415: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0415-opaque-pragma.rst This commit also updates the haddock submodule to handle the newly introduced lexer tokens corresponding to the OPAQUE pragma. - - - - - 83f5841b by Bodigrim at 2022-03-25T11:36:31-04:00 Add instance Lift ByteArray - - - - - 7cc1184a by Matthew Pickering at 2022-03-25T11:37:07-04:00 Make -ddump-rn-ast and -ddump-tc-ast work in GHCi Fixes #17830 - - - - - 940feaf3 by Sylvain Henry at 2022-03-25T11:37:47-04:00 Modularize Tidy (#17957) - Factorize Tidy options into TidyOpts datatype. Initialize it in GHC.Driver.Config.Tidy - Same thing for StaticPtrOpts - Perform lookups of unpackCString[Utf8]# once in initStaticPtrOpts instead of for every use of mkStringExprWithFS - - - - - 25101813 by Takenobu Tani at 2022-03-28T01:16:02-04:00 users-guide: Correct markdown for profiling This patch corrects some markdown. [skip ci] - - - - - c832ae93 by Matthew Pickering at 2022-03-28T01:16:38-04:00 hadrian: Flag cabal flag handling This patch basically deletes some ad-hoc handling of Cabal Flags and replaces it with a correct query of the LocalBuildInfo. The flags in the local build info can be modified by users by passing hadrian options For example (!4331) ``` *.genapply.cabal.configure.opts += --flags=unregisterised ``` And all the flags specified by the `Cabal Flags` builder were already passed to configure properly using `--flags`. - - - - - a9f3a5c6 by Ben Gamari at 2022-03-28T01:16:38-04:00 Disable text's dependency on simdutf by default Unfortunately we are simply not currently in a good position to robustly ship binary distributions which link against C++ code like simdutf. Fixes #20724. - - - - - eff86e8a by Richard Eisenberg at 2022-03-28T01:17:14-04:00 Add Red Herring to Note [What might equal later?] Close #21208. - - - - - 12653be9 by jberryman at 2022-03-28T01:17:55-04:00 Document typed splices inhibiting unused bind detection (#16524) - - - - - 4aeade15 by Adam Sandberg Ericsson at 2022-03-28T01:18:31-04:00 users-guide: group ticky-ticky profiling under one heading - - - - - cc59648a by Sylvain Henry at 2022-03-28T01:19:12-04:00 Hadrian: allow testsuite to run with cross-compilers (#21292) - - - - - 89cb1315 by Matthew Pickering at 2022-03-28T01:19:48-04:00 hadrian: Add show target to bindist makefile Some build systems use "make show" to query facts about the bindist, for example: ``` make show VALUE=ProjectVersion > version ``` to determine the ProjectVersion - - - - - 8229885c by Alan Zimmerman at 2022-03-28T19:23:28-04:00 EPA: let stmt with semicolon has wrong anchor The code let ;x =1 Captures the semicolon annotation, but did not widen the anchor in the ValBinds. Fix that. Closes #20247 - - - - - 2c12627c by Ryan Scott at 2022-03-28T19:24:04-04:00 Consistently attach SrcSpans to sub-expressions in TH splices Before, `GHC.ThToHs` was very inconsistent about where various sub-expressions would get the same `SrcSpan` from the original TH splice location or just a generic `noLoc` `SrcSpan`. I have ripped out all uses of `noLoc` in favor of the former instead, and I have added a `Note [Source locations within TH splices]` to officially enshrine this design choice. Fixes #21299. - - - - - 789add55 by Zubin Duggal at 2022-03-29T13:07:22-04:00 Fix all invalid haddock comments in the compiler Fixes #20935 and #20924 - - - - - 967dad03 by Zubin Duggal at 2022-03-29T13:07:22-04:00 hadrian: Build lib:GHC with -haddock and -Winvalid-haddock (#21273) - - - - - ad09a5f7 by sheaf at 2022-03-29T13:08:05-04:00 Hadrian: make DDEBUG separate from debugged RTS This patchs separates whether -DDEBUG is enabled (i.e. whether debug assertions are enabled) from whether we are using the debugged RTS (i.e. GhcDebugged = YES). This means that we properly skip tests which have been marked with `when(compiler_debugged(), skip)`. Fixes #21113, #21153 and #21234 - - - - - 840a6811 by Matthew Pickering at 2022-03-29T13:08:42-04:00 RTS: Zero gc_cpu_start and gc_cpu_end after accounting When passed a combination of `-N` and `-qn` options the cpu time for garbage collection was being vastly overcounted because the counters were not being zeroed appropiately. When -qn1 is passed, only 1 of the N avaiable GC threads is chosen to perform work, the rest are idle. At the end of the GC period, stat_endGC traverses all the GC threads and adds up the elapsed time from each of them. For threads which didn't participate in this GC, the value of the cpu time should be zero, but before this patch, the counters were not zeroed and hence we would count the same elapsed time on many subsequent iterations (until the thread participated in a GC again). The most direct way to zero these fields is to do so immediately after the value is added into the global counter, after which point they are never used again. We also tried another approach where we would zero the counter in yieldCapability but there are some (undiagnosed) siations where a capbility would not pass through yieldCapability before the GC ended and the same double counting problem would occur. Fixes #21082 - - - - - dda46e2d by Matthew Pickering at 2022-03-29T13:09:18-04:00 Add test for T21306 Fixes #21306 - - - - - f07c7766 by Jakob Brünker at 2022-03-30T03:10:33-04:00 Give parsing plugins access to errors Previously, when the parser produced non-fatal errors (i.e. it produced errors but the 'PState' is 'POk'), compilation would be aborted before the 'parsedResultAction' of any plugin was invoked. This commit changes that, so that such that 'parsedResultAction' gets collections of warnings and errors as argument, and must return them after potentially modifying them. Closes #20803 - - - - - e5dfde75 by Ben Gamari at 2022-03-30T03:11:10-04:00 Fix reference to Note [FunBind vs PatBind] This Note was renamed in 2535a6716202253df74d8190b028f85cc6d21b72 yet this occurrence was not updated. - - - - - 21894a63 by Krzysztof Gogolewski at 2022-03-30T03:11:45-04:00 Refactor: make primtypes independent of PrimReps Previously, 'pcPrimTyCon', the function used to define a primitive type, was taking a PrimRep, only to convert it to a RuntimeRep. Now it takes a RuntimeRep directly. Moved primRepToRuntimeRep to GHC.Types.RepType. It is now located next to its inverse function runtimeRepPrimRep. Now GHC.Builtin.Types.Prim no longer mentions PrimRep, and GHC.Types.RepType no longer imports GHC.Builtin.Types.Prim. Removed unused functions `primRepsToRuntimeRep` and `mkTupleRep`. Removed Note [PrimRep and kindPrimRep] - it was never referenced, didn't belong to Types.Prim, and Note [Getting from RuntimeRep to PrimRep] is more comprehensive. - - - - - 43da2963 by Matthew Pickering at 2022-03-30T09:55:49+01:00 Fix mention of non-existent "rehydrateIface" function [skip ci] Fixes #21303 - - - - - 6793a20f by gershomb at 2022-04-01T10:33:46+01:00 Remove wrong claim about naturality law. This docs change removes a longstanding confusion in the Traversable docs. The docs say "(The naturality law is implied by parametricity and thus so is the purity law [1, p15].)". However if one reads the reference a different "natural" law is implied by parametricity. The naturality law given as a law here is imposed. Further, the reference gives examples which violate both laws -- so they cannot be implied by parametricity. This PR just removes the wrong claim. - - - - - 5beeff46 by Ben Gamari at 2022-04-01T10:34:39+01:00 Refactor handling of global initializers GHC uses global initializers for a number of things including cost-center registration, info-table provenance registration, and setup of foreign exports. Previously, the global initializer arrays which referenced these initializers would live in the object file of the C stub, which would then be merged into the main object file of the module. Unfortunately, this approach is no longer tenable with the move to Clang/LLVM on Windows (see #21019). Specifically, lld's PE backend does not support object merging (that is, the -r flag). Instead we are now rather packaging a module's object files into a static library. However, this is problematic in the case of initializers as there are no references to the C stub object in the archive, meaning that the linker may drop the object from the final link. This patch refactors our handling of global initializers to instead place initializer arrays within the object file of the module to which they belong. We do this by introducing a Cmm data declaration containing the initializer array in the module's Cmm stream. While the initializer functions themselves remain in separate C stub objects, the reference from the module's object ensures that they are not dropped from the final link. In service of #21068. - - - - - 3e6fe71b by Matthew Pickering at 2022-04-01T10:35:41+01:00 Fix remaining issues in eventlog types (gen_event_types.py) * The size of End concurrent mark phase looks wrong and, it used to be 4 and now it's 0. * The size of Task create is wrong, used to be 18 and now 14. * The event ticky-ticky entry counter begin sample has the wrong name * The event ticky-ticky entry counter being sample has the wrong size, was 0 now 32. Closes #21070 - - - - - 7847f47a by Ben Gamari at 2022-04-01T10:35:41+01:00 users-guide: Fix a few small issues in eventlog format descriptions The CONC_MARK_END event description didn't mention its payload. Clarify the meaning of the CREATE_TASK's payload. - - - - - acfd5a4c by Matthew Pickering at 2022-04-01T10:35:53+01:00 ci: Regenerate jobs.yaml It seems I forgot to update this to reflect the current state of gen_ci.hs - - - - - a952dd80 by Matthew Pickering at 2022-04-01T10:35:59+01:00 ci: Attempt to fix windows cache issues It appears that running the script directly does nothing (no info is printed about saving the cache). - - - - - fb65e6e3 by Adrian Ratiu at 2022-04-01T10:49:52+01:00 fp_prog_ar.m4: take AR var into consideration In ChromeOS and Gentoo we want the ability to use LLVM ar instead of GNU ar even though both are installed, thus we pass (for eg) AR=llvm-ar to configure. Unfortunately GNU ar always gets picked regardless of the AR setting because the check does not consider the AR var when setting fp_prog_ar, hence this fix. - - - - - 1daaefdf by Greg Steuck at 2022-04-01T10:50:16+01:00 T13366 requires c++ & c++abi libraries on OpenBSD Fixes this failure: =====> 1 of 1 [0, 0, 0] T13366(normal) 1 of 1 [0, 0, 0] Compile failed (exit code 1) errors were: <no location info>: error: user specified .o/.so/.DLL could not be loaded (File not found) Whilst trying to load: (dynamic) stdc++ Additional directories searched: (none) *** unexpected failure for T13366(normal) - - - - - 18e6c85b by Jakob Bruenker at 2022-04-01T10:54:28+01:00 new datatypes for parsedResultAction Previously, the warnings and errors were given and returned as a tuple (Messages PsWarnings, Messages PsErrors). Now, it's just PsMessages. This, together with the HsParsedModule the parser plugin gets and returns, has been wrapped up as ParsedResult. - - - - - 9727e592 by Morrow at 2022-04-01T10:55:12+01:00 Clarify that runghc interprets the input program - - - - - f589dea3 by sheaf at 2022-04-01T10:59:58+01:00 Unify RuntimeRep arguments in ty_co_match The `ty_co_match` function ignored the implicit RuntimeRep coercions that occur in a `FunCo`. Even though a comment explained that this should be fine, #21205 showed that it could result in discarding a RuntimeRep coercion, and thus discarding an important cast entirely. With this patch, we first match the kinds in `ty_co_match`. Fixes #21205 ------------------------- Metric Increase: T12227 T18223 ------------------------- - - - - - 6f4dc372 by Andreas Klebinger at 2022-04-01T11:01:35+01:00 Export MutableByteArray from Data.Array.Byte This implements CLC proposal #49 - - - - - 5df9f5e7 by ARATA Mizuki at 2022-04-01T11:02:35+01:00 Add test cases for #20640 Closes #20640 - - - - - 8334ff9e by Krzysztof Gogolewski at 2022-04-01T11:03:16+01:00 Minor cleanup - Remove unused functions exprToCoercion_maybe, applyTypeToArg, typeMonoPrimRep_maybe, runtimeRepMonoPrimRep_maybe. - Replace orValid with a simpler check - Use splitAtList in applyTysX - Remove calls to extra_clean in the testsuite; it does not do anything. Metric Decrease: T18223 - - - - - b2785cfc by Eric Lindblad at 2022-04-01T11:04:07+01:00 hadrian typos - - - - - 418e6fab by Eric Lindblad at 2022-04-01T11:04:12+01:00 two typos - - - - - dd7c7c99 by Phil de Joux at 2022-04-01T11:04:56+01:00 Add tests and docs on plugin args and order. - - - - - 3e209a62 by MaxHearnden at 2022-04-01T11:05:19+01:00 Change may not to might not - - - - - b84380d3 by Matthew Pickering at 2022-04-01T11:07:27+01:00 hadrian: Remove linters-common from bindist Zubin observed that the bindists contains the utility library linters-common. There are two options: 1. Make sure only the right files are added into the bindist.. a bit tricky due to the non-trivial structure of the lib directory. 2. Remove the bad files once they get copied in.. a bit easier So I went for option 2 but we perhaps should go for option 1 in the future. Fixes #21203 - - - - - ba9904c1 by Zubin Duggal at 2022-04-01T11:07:31+01:00 hadrian: allow testing linters with out of tree compilers - - - - - 26547759 by Matthew Pickering at 2022-04-01T11:07:35+01:00 hadrian: Introduce CheckProgram datatype to replace a 7-tuple - - - - - df65d732 by Jakob Bruenker at 2022-04-01T11:08:28+01:00 Fix panic when pretty printing HsCmdLam When pretty printing a HsCmdLam with more than one argument, GHC panicked because of a missing case. This fixes that. Closes #21300 - - - - - ad6cd165 by John Ericson at 2022-04-01T11:10:06+01:00 hadrian: Remove vestigial -this-unit-id support check This has been dead code since 400ead81e80f66ad7b1260b11b2a92f25ccc3e5a. - - - - - 8ca7ab81 by Matthew Pickering at 2022-04-01T11:10:23+01:00 hadrian: Fix race involving empty package databases There was a small chance of a race occuring between the small window of 1. The first package (.conf) file get written into the database 2. hadrian calling "ghc-pkg recache" to refresh the package.conf file In this window the package database would contain rts.conf but not a package.cache file, and therefore if ghc was invoked it would error because it was missing. To solve this we call "ghc-pkg recache" at when the database is created by shake by writing the stamp file into the database folder. This also creates the package.cache file and so avoids the possibility of this race. - - - - - cc4ec64b by Matthew Pickering at 2022-04-01T11:11:05+01:00 hadrian: Add assertion that in/out tree args are the same There have been a few instances where this calculation was incorrect, so we add a non-terminal assertion when now checks they the two computations indeed compute the same thing. Fixes #21285 - - - - - 691508d8 by Matthew Pickering at 2022-04-01T11:13:10+01:00 hlint: Ignore suggestions in generated HaddockLex file With the make build system this file ends up in the compiler/ subdirectory so is linted. With hadrian, the file ends up in _build so it's not linted. Fixes #21313 - - - - - f8f152e7 by Krzysztof Gogolewski at 2022-04-01T11:14:08+01:00 Change GHC.Prim to GHC.Exts in docs and tests Users are supposed to import GHC.Exts rather than GHC.Prim. Part of #18749. - - - - - f8fc6d2e by Matthew Pickering at 2022-04-01T11:15:24+01:00 driver: Improve -Wunused-packages error message (and simplify implementation) In the past I improved the part of -Wunused-packages which found which packages were used. Now I improve the part which detects which ones were specified. The key innovation is to use the explicitUnits field from UnitState which has the result of resolving the package flags, so we don't need to mess about with the flag arguments from DynFlags anymore. The output now always includes the package name and version (and the flag which exposed it). ``` The following packages were specified via -package or -package-id flags, but were not needed for compilation: - bytestring-0.11.2.0 (exposed by flag -package bytestring) - ghc-9.3 (exposed by flag -package ghc) - process-1.6.13.2 (exposed by flag -package process) ``` Fixes #21307 - - - - - 5e5a12d9 by Matthew Pickering at 2022-04-01T11:15:32+01:00 driver: In oneshot mode, look for interface files in hidir How things should work: * -i is the search path for source files * -hidir explicitly sets the search path for interface files and the output location for interface files. * -odir sets the search path and output location for object files. Before in one shot mode we would look for the interface file in the search locations given by `-i`, but then set the path to be in the `hidir`, so in unusual situations the finder could find an interface file in the `-i` dir but later fail because it tried to read the interface file from the `-hidir`. A bug identified by #20569 - - - - - 950f58e7 by Matthew Pickering at 2022-04-01T11:15:36+01:00 docs: Update documentation interaction of search path, -hidir and -c mode. As noted in #20569 the documentation for search path was wrong because it seemed to indicate that `-i` dirs were important when looking for interface files in `-c` mode, but they are not important if `-hidir` is set. Fixes #20569 - - - - - d85c7dcb by sheaf at 2022-04-01T11:17:56+01:00 Keep track of promotion ticks in HsOpTy This patch adds a PromotionFlag field to HsOpTy, which is used in pretty-printing and when determining whether to emit warnings with -fwarn-unticked-promoted-constructors. This allows us to correctly report tick-related warnings for things like: type A = Int : '[] type B = [Int, Bool] Updates haddock submodule Fixes #19984 - - - - - 32070e6c by Jakob Bruenker at 2022-04-01T20:31:08+02:00 Implement \cases (Proposal 302) This commit implements proposal 302: \cases - Multi-way lambda expressions. This adds a new expression heralded by \cases, which works exactly like \case, but can match multiple apats instead of a single pat. Updates submodule haddock to support the ITlcases token. Closes #20768 - - - - - c6f77f39 by sheaf at 2022-04-01T20:33:05+02:00 Add a regression test for #21323 This bug was fixed at some point between GHC 9.0 and GHC 9.2; this patch simply adds a regression test. - - - - - 3596684e by Jakob Bruenker at 2022-04-01T20:33:05+02:00 Fix error when using empty case in arrow notation It was previously not possible to use -XEmptyCase in Arrow notation, since GHC would print "Exception: foldb of empty list". This is now fixed. Closes #21301 - - - - - 9a325b59 by Ben Gamari at 2022-04-01T20:33:05+02:00 users-guide: Fix various markup issues - - - - - aefb1e6d by sheaf at 2022-04-01T20:36:01+02:00 Ensure implicit parameters are lifted `tcExpr` typechecked implicit parameters by introducing a metavariable of kind `TYPE kappa`, without enforcing that `kappa ~ LiftedRep`. This patch instead creates a metavariable of kind `Type`. Fixes #21327 - - - - - ed62dc66 by Ben Gamari at 2022-04-05T11:44:51-04:00 gitlab-ci: Disable cabal-install store caching on Windows For reasons that remain a mystery, cabal-install seems to consistently corrupt its cache on Windows. Disable caching for now. Works around #21347. - - - - - 5ece5c5a by Ryan Scott at 2022-04-06T13:00:51-04:00 Add /linters/*/dist-install/ to .gitignore Fixes #21335. [ci skip] - - - - - 410c76ee by Ben Gamari at 2022-04-06T13:01:28-04:00 Use static archives as an alternative to object merging Unfortunately, `lld`'s COFF backend does not currently support object merging. With ld.bfd having broken support for high image-load base addresses, it's necessary to find an alternative. Here I introduce support in the driver for generating static archives, which we use on Windows instead of object merging. Closes #21068. - - - - - 400666c8 by Ben Gamari at 2022-04-06T13:01:28-04:00 rts/linker: Catch archives masquerading as object files Check the file's header to catch static archive bearing the `.o` extension, as may happen on Windows after the Clang refactoring. See #21068 - - - - - 694d39f0 by Ben Gamari at 2022-04-06T13:01:28-04:00 driver: Make object merging optional On Windows we don't have a linker which supports object joining (i.e. the `-r` flag). Consequently, `-pgmlm` is now a `Maybe`. See #21068. - - - - - 41fcb5cd by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Refactor handling of ar flags Previously the setup was quite fragile as it had to assume which arguments were file arguments and which were flags. - - - - - 3ac80a86 by Ben Gamari at 2022-04-06T13:01:28-04:00 hadrian: Produce ar archives with L modifier on Windows Since object files may in fact be archive files, we must ensure that their contents are merged rather than constructing an archive-of-an-archive. See #21068. - - - - - 295c35c5 by Ben Gamari at 2022-04-06T13:01:28-04:00 Add a Note describing lack of object merging on Windows See #21068. - - - - - d2ae0a3a by Ben Gamari at 2022-04-06T13:01:28-04:00 Build ar archives with -L when "joining" objects Since there may be .o files which are in fact archives. - - - - - babb47d2 by Zubin Duggal at 2022-04-06T13:02:04-04:00 Add warnings for file header pragmas that appear in the body of a module (#20385) Once we are done parsing the header of a module to obtain the options, we look through the rest of the tokens in order to determine if they contain any misplaced file header pragmas that would usually be ignored, potentially resulting in bad error messages. The warnings are reported immediately so that later errors don't shadow over potentially helpful warnings. Metric Increase: T13719 - - - - - 3f31825b by Ben Gamari at 2022-04-06T13:02:40-04:00 rts/AdjustorPool: Generalize to allow arbitrary contexts Unfortunately the i386 adjustor logic needs this. - - - - - 9b645ee1 by Ben Gamari at 2022-04-06T13:02:40-04:00 adjustors/i386: Use AdjustorPool In !7511 (closed) I introduced a new allocator for adjustors, AdjustorPool, which eliminates the address space fragmentation issues which adjustors can introduce. In that work I focused on amd64 since that was the platform where I observed issues. However, in #21132 we noted that the size of adjustors is also a cause of CI fragility on i386. In this MR I port i386 to use AdjustorPool. Sadly the complexity of the i386 adjustor code does cause require a bit of generalization which makes the code a bit more opaque but such is the world. Closes #21132. - - - - - c657a616 by Ben Gamari at 2022-04-06T13:03:16-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 9ce273b9 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Drop dead HACKAGE_INDEX_STATE variable - - - - - 01845375 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab/darwin: Factor out bindists This makes it a bit easier to bump them. - - - - - c41c478e by Ben Gamari at 2022-04-06T13:03:16-04:00 Fix a few new warnings when booting with GHC 9.2.2 -Wuni-incomplete-patterns and apparent improvements in the pattern match checker surfaced these. - - - - - 6563cd24 by Ben Gamari at 2022-04-06T13:03:16-04:00 gitlab-ci: Bump bootstrap compiler to 9.2.2 This is necessary to build recent `text` commits. Bumps Hackage index state for a hashable which builds with GHC 9.2. - - - - - a62e983e by Ben Gamari at 2022-04-06T13:03:16-04:00 Bump text submodule to current `master` Addresses #21295. - - - - - 88d61031 by Vladislav Zavialov at 2022-04-06T13:03:53-04:00 Refactor OutputableBndrFlag instances The matching on GhcPass introduced by 95275a5f25a is not necessary. This patch reverts it to make the code simpler. - - - - - f601f002 by GHC GitLab CI at 2022-04-06T15:18:26-04:00 rts: Eliminate use of nested functions This is a gcc-specific extension. - - - - - d4c5f29c by Ben Gamari at 2022-04-06T15:18:26-04:00 driver: Drop hacks surrounding windres invocation Drop hack for #1828, among others as they appear to be unnecessary when using `llvm-windres`. - - - - - 6be2c5a7 by Ben Gamari at 2022-04-06T15:18:26-04:00 Windows/Clang: Build system adaptation * Bump win32-tarballs to 0.7 * Move Windows toolchain autoconf logic into separate file * Use clang and LLVM utilities as described in #21019 * Disable object merging as lld doesn't support -r * Drop --oformat=pe-bigobj-x86-64 arguments from ld flags as LLD detects that the output is large on its own. * Drop gcc wrapper since Clang finds its root fine on its own. - - - - - c6fb7aff by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Test that we can build bigobj PE objects - - - - - 79851c07 by Ben Gamari at 2022-04-06T15:18:26-04:00 Drop -static-libgcc This flag is not applicable when Clang is used. - - - - - 1f8a8264 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Port T16514 to C Previously this test was C++ which made it a bit of a portability problem. - - - - - d7e650d1 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark Windows as a libc++ platform - - - - - d7886c46 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark T9405 as fixed on Windows I have not seen it fail since moving to clang. Closes #12714. - - - - - 4c3fbb4e by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark FloatFnInverses as fixed The new toolchain has fixed it. Closes #15670. - - - - - 402c36ba by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Rework T13606 to avoid gcc dependence Previously we used libgcc_s's import library in T13606. However, now that we ship with clang we no longer have this library. Instead we now use gdi32. - - - - - 9934ad54 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Clean up tests depending on C++ std lib - - - - - 12fcdef2 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Split T13366 into two tests Split up the C and C++ uses since the latter is significantly more platform-dependent. - - - - - 3c08a198 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Fix mk-big-obj I'm a bit unclear on how this previously worked as it attempted to build an executable without defining `main`. - - - - - 7e97cc23 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Provide module definitions in T10955dyn Otherwise the linker will export all symbols, including those provided by the RTS, from the produced shared object. Consequently, attempting to link against multiple objects simultaneously will cause the linker to complain that RTS symbols are multiply defined. Avoid this by limiting the DLL exports with a module definition file. - - - - - 9a248afa by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite: Mark test-defaulting-plugin as fragile on Windows Currently llvm-ar does not handle long file paths, resulting in occassional failures of these tests and #21293. - - - - - 39371aa4 by Ben Gamari at 2022-04-06T15:18:26-04:00 testsuite/driver: Treat framework failures of fragile tests as non-fatal Previously we would report framework failures of tests marked as fragile as failures. Now we rather treat them as fragile test failures, which are not fatal to the testsuite run. Noticed while investigating #21293. - - - - - a1e6661d by Ben Gamari at 2022-04-06T15:18:32-04:00 Bump Cabal submodule - Disable support for library-for-ghci on Windows as described in #21068. - Teach Cabal to use `ar -L` when available - - - - - f7b0f63c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump process submodule Fixes missing TEST_CC_OPTS in testsuite tests. - - - - - 109cee19 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Disable ghci libraries when object merging is not available - - - - - c22fba5c by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump bytestring submodule - - - - - 6e2744cc by Ben Gamari at 2022-04-06T15:18:37-04:00 Bump text submodule - - - - - 32333747 by Ben Gamari at 2022-04-06T15:18:37-04:00 hadrian: Build wrappers using ghc rather than cc - - - - - 59787ba5 by Ben Gamari at 2022-04-06T15:18:37-04:00 linker/PEi386: More descriptive error message - - - - - 5e3c3c4f by Ben Gamari at 2022-04-06T15:18:37-04:00 testsuite: Mark TH_spliceE5_prof as unbroken on Windows It was previously failing due to #18721 and now passes with the new toolchain. Closes #18721. - - - - - 9eb0a9d9 by GHC GitLab CI at 2022-04-06T15:23:48-04:00 rts/PEi386: Move some debugging output to -DL - - - - - ce874595 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen/x86: Use %rip-relative addressing On Windows with high-entropy ASLR we must use %rip-relative addressing to avoid overflowing the signed 32-bit immediate size of x86-64. Since %rip-relative addressing comes essentially for free and can make linking significantly easier, we use it on all platforms. - - - - - 52deee64 by Ben Gamari at 2022-04-06T15:24:01-04:00 Generate LEA for label expressions - - - - - 105a0056 by Ben Gamari at 2022-04-06T15:24:01-04:00 Refactor is32BitLit to take Platform rather than Bool - - - - - ec4526b5 by Ben Gamari at 2022-04-06T15:24:01-04:00 Don't assume that labels are 32-bit on Windows - - - - - ffdbe457 by Ben Gamari at 2022-04-06T15:24:01-04:00 nativeGen: Note signed-extended nature of MOV - - - - - bfb79697 by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 5ad143fd by Ben Gamari at 2022-04-06T15:30:56-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - a59a66a8 by Ben Gamari at 2022-04-06T15:30:56-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - 42bf7528 by GHC GitLab CI at 2022-04-06T16:25:04-04:00 rts/PEi386: Fix memory leak Previously we would leak the section information of the `.bss` section. - - - - - d286a55c by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Preserve information about symbol types As noted in #20978, the linker would previously handle overflowed relocations by creating a jump island. While this is fine in the case of code symbols, it's very much not okay in the case of data symbols. To fix this we must keep track of whether each symbol is code or data and relocate them appropriately. This patch takes the first step in this direction, adding a symbol type field to the linker's symbol table. It doesn't yet change relocation behavior to take advantage of this knowledge. Fixes #20978. - - - - - e689e9d5 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Fix relocation overflow behavior This fixes handling of overflowed relocations on PEi386 targets: * Refuse to create jump islands for relocations of data symbols * Correctly handle the `__imp___acrt_iob_func` symbol, which is an new type of symbol: `SYM_TYPE_INDIRECT_DATA` - - - - - 655e7d8f by GHC GitLab CI at 2022-04-06T16:25:25-04:00 rts: Mark anything that might have an info table as data Tables-next-to-code mandates that we treat symbols with info tables like data since we cannot relocate them using a jump island. See #20983. - - - - - 7e8cc293 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Rework linker This is a significant rework of the PEi386 linker, making the linker compatible with high image base addresses. Specifically, we now use the m32 allocator instead of `HeapAllocate`. In addition I found a number of latent bugs in our handling of import libraries and relocations. I've added quite a few comments describing what I've learned about Windows import libraries while fixing these. Thanks to Tamar Christina (@Phyx) for providing the address space search logic, countless hours of help while debugging, and his boundless Windows knowledge. Co-Authored-By: Tamar Christina <tamar at zhox.com> - - - - - ff625218 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Move allocateBytes to MMap.c - - - - - f562b5ca by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PEi386: Avoid accidentally-quadratic allocation cost We now preserve the address that we last mapped, allowing us to resume our search and avoiding quadratic allocation costs. This fixes the runtime of T10296a, which allocates many adjustors. - - - - - 3247b7db by Ben Gamari at 2022-04-06T16:25:25-04:00 Move msvcrt dep out of base - - - - - fa404335 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: More descriptive debug output - - - - - 140f338f by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/PathUtils: Define pathprintf in terms of snwprintf on Windows swprintf deviates from usual `snprintf` semantics in that it does not guarantee reasonable behavior when the buffer is NULL (that is, returning the number of bytes that would have been emitted). - - - - - eb60565b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Report archive member index - - - - - 209fd61b by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker: Split up object resolution and initialization Previously the RTS linker would call initializers during the "resolve" phase of linking. However, this is problematic in the case of cyclic dependencies between objects. In particular, consider the case where we have a situation where a static library contains a set of recursive objects: * object A has depends upon symbols in object B * object B has an initializer that depends upon object A * we try to load object A The linker would previously: 1. start resolving object A 2. encounter the reference to object B, loading it resolve object B 3. run object B's initializer 4. the initializer will attempt to call into object A, which hasn't been fully resolved (and therefore protected) Fix this by moving constructor execution to a new linking phase, which follows resolution. Fix #21253. - - - - - 8e8a1021 by Ben Gamari at 2022-04-06T16:25:25-04:00 rts/linker/LoadArchive: Fix leaking file handle Previously `isArchive` could leak a `FILE` handle if the `fread` returned a short read. - - - - - 429ea5d9 by sheaf at 2022-04-07T07:55:52-04:00 Remove Fun pattern from Typeable COMPLETE set GHC merge request !963 improved warnings in the presence of COMPLETE annotations. This allows the removal of the Fun pattern from the complete set. Doing so expectedly causes some redundant pattern match warnings, in particular in GHC.Utils.Binary.Typeable and Data.Binary.Class from the binary library; this commit addresses that. Updates binary submodule Fixes #20230 - - - - - 54b18824 by Alan Zimmerman at 2022-04-07T07:56:28-04:00 EPA: handling of con_bndrs in mkGadtDecl Get rid of unnnecessary case clause that always matched. Closes #20558 - - - - - 9c838429 by Ben Gamari at 2022-04-07T09:38:53-04:00 testsuite: Mark T10420 as broken on Windows Due to #21322. - - - - - 50739d2b by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Refactor and fix printf attributes on clang Clang on Windows does not understand the `gnu_printf` attribute; use `printf` instead. - - - - - 9eeaeca4 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Add missing newline in error message - - - - - fcef9a17 by Ben Gamari at 2022-04-07T09:42:42-04:00 configure: Make environ decl check more robust Some platforms (e.g. Windows/clang64) declare `environ` in `<stdlib.h>`, not `<unistd.h>` - - - - - 8162b4f3 by Ben Gamari at 2022-04-07T09:42:42-04:00 rts: Adjust RTS symbol table on Windows for ucrt - - - - - 633280d7 by Ben Gamari at 2022-04-07T09:43:21-04:00 testsuite: Fix exit code of bounds checking tests on Windows `abort` exits with 255, not 134, on Windows. - - - - - cab4dc01 by Ben Gamari at 2022-04-07T09:43:31-04:00 testsuite: Update expected output from T5435 tests on Windows I'll admit, I don't currently see *why* this output is reordered but it is a fairly benign difference and I'm out of time to investigate. - - - - - edf5134e by Ben Gamari at 2022-04-07T09:43:35-04:00 testsuite: Mark T20918 as broken on Windows Our toolchain on Windows doesn't currently have Windows support. - - - - - d0ddeff3 by Ben Gamari at 2022-04-07T09:43:39-04:00 testsuite: Mark linker unloading tests as broken on Windows Due to #20354. We will need to investigate this prior the release. - - - - - 5a86da2b by Ben Gamari at 2022-04-07T09:43:43-04:00 testsuite: Mark T9405 as broken on Windows Due to #21361. - - - - - 4aa86dcf by Ben Gamari at 2022-04-07T09:44:18-04:00 Merge branches 'wip/windows-high-codegen', 'wip/windows-high-linker', 'wip/windows-clang-2' and 'wip/lint-rts-includes' into wip/windows-clang-join - - - - - 7206f055 by Ben Gamari at 2022-04-07T09:45:07-04:00 rts/CloneStack: Ensure that Rts.h is #included first As is necessary on Windows. - - - - - 9cfcb27b by Ben Gamari at 2022-04-07T09:45:07-04:00 rts: Fallback to ucrtbase not msvcrt Since we have switched to Clang the toolchain now links against ucrt rather than msvcrt. - - - - - d6665d85 by Ben Gamari at 2022-04-07T09:46:25-04:00 Accept spurious perf test shifts on Windows Metric Decrease: T16875 Metric Increase: T12707 T13379 T3294 T4801 T5321FD T5321Fun T783 - - - - - 83363c8b by Simon Peyton Jones at 2022-04-07T12:57:21-04:00 Use prepareBinding in tryCastWorkerWrapper As #21144 showed, tryCastWorkerWrapper was calling prepareRhs, and then unconditionally floating the bindings, without the checks of doFloatFromRhs. That led to floating an unlifted binding into a Rec group. This patch refactors prepareBinding to make these checks, and do them uniformly across all calls. A nice improvement. Other changes * Instead of passing around a RecFlag and a TopLevelFlag; and sometimes a (Maybe SimplCont) for join points, define a new Simplifier-specific data type BindContext: data BindContext = BC_Let TopLevelFlag RecFlag | BC_Join SimplCont and use it consistently. * Kill off completeNonRecX by inlining it. It was only called in one place. * Add a wrapper simplImpRules for simplRules. Compile time on T9630 drops by 4.7%; little else changes. Metric Decrease: T9630 - - - - - 02279a9c by Vladislav Zavialov at 2022-04-07T12:57:59-04:00 Rename [] to List (#21294) This patch implements a small part of GHC Proposal #475. The key change is in GHC.Types: - data [] a = [] | a : [a] + data List a = [] | a : List a And the rest of the patch makes sure that List is pretty-printed as [] in various contexts. Updates the haddock submodule. - - - - - 08480d2a by Simon Peyton Jones at 2022-04-07T12:58:36-04:00 Fix the free-var test in validDerivPred The free-var test (now documented as (VD3)) was too narrow, affecting only class predicates. #21302 demonstrated that this wasn't enough! Fixes #21302. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - b3d6d23d by Andreas Klebinger at 2022-04-07T12:59:12-04:00 Properly explain where INLINE pragmas can appear. Fixes #20676 - - - - - 23ef62b3 by Ben Gamari at 2022-04-07T14:28:28-04:00 rts: Fix off-by-one in snwprintf usage - - - - - b2dbcc7d by Simon Jakobi at 2022-04-08T03:00:38-04:00 Improve seq[D]VarSet Previously, the use of size[D]VarSet would involve a traversal of the entire underlying IntMap. Since IntMaps are already spine-strict, this is unnecessary. - - - - - 64ac20a7 by sheaf at 2022-04-08T03:01:16-04:00 Add test for #21338 This no-skolem-info bug was fixed by the no-skolem-info patch that will be part of GHC 9.4. This patch adds a regression test for the issue reported in issue #21338. Fixes #21338. - - - - - c32c4db6 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Move __USE_MINGW_ANSI_STDIO definition to PosixSource.h It's easier to ensure that this is included first than Rts.h - - - - - 56f85d62 by Ben Gamari at 2022-04-08T03:01:53-04:00 rts: Fix various #include issues This fixes various violations of the newly-added RTS includes linter. - - - - - cb1f31f5 by Ben Gamari at 2022-04-08T03:01:53-04:00 testsuite: Lint RTS #includes Verifies two important properties of #includes in the RTS: * That system headers don't appear inside of a `<BeginPrivate.h>` block as this can hide system library symbols, resulting in very hard-to-diagnose linker errors * That no headers precede `Rts.h`, ensuring that __USE_MINGW_ANSI_STDIO is set correctly before system headers are included. - - - - - c44432db by Krzysztof Gogolewski at 2022-04-08T03:02:29-04:00 Fixes to 9.4 release notes - Mention -Wforall-identifier - Improve description of withDict - Fix formatting - - - - - 777365f1 by sheaf at 2022-04-08T09:43:35-04:00 Correctly report SrcLoc of redundant constraints We were accidentally dropping the source location information in certain circumstances when reporting redundant constraints. This patch makes sure that we set the TcLclEnv correctly before reporting the warning. Fixes #21315 - - - - - af300a43 by Vladislav Zavialov at 2022-04-08T09:44:11-04:00 Reject illegal quote mark in data con declarations (#17865) * Non-fatal (i.e. recoverable) parse error * Checking infix constructors * Extended the regression test - - - - - 56254e6b by Ben Gamari at 2022-04-08T09:59:46-04:00 Merge remote-tracking branch 'origin/master' - - - - - 6e2c3b7c by Matthew Pickering at 2022-04-08T13:55:15-04:00 driver: Introduce HomeModInfoCache abstraction The HomeModInfoCache is a mutable cache which is updated incrementally as the driver completes, this makes it robust to exceptions including (SIGINT) The interface for the cache is described by the `HomeMOdInfoCache` data type: ``` data HomeModInfoCache = HomeModInfoCache { hmi_clearCache :: IO [HomeModInfo] , hmi_addToCache :: HomeModInfo -> IO () } ``` The first operation clears the cache and returns its contents. This is designed so it's harder to end up in situations where the cache is retained throughout the execution of upsweep. The second operation allows a module to be added to the cache. The one slightly nasty part is in `interpretBuildPlan` where we have to be careful to ensure that the cache writes happen: 1. In parralel 2. Before the executation continues after upsweep. This requires some simple, localised MVar wrangling. Fixes #20780 - - - - - 85f4a3c9 by Andreas Klebinger at 2022-04-08T13:55:50-04:00 Add flag -fprof-manual which controls if GHC should honour manual cost centres. This allows disabling of manual control centres in code a user doesn't control like libraries. Fixes #18867 - - - - - 3415981c by Vladislav Zavialov at 2022-04-08T13:56:27-04:00 HsUniToken for :: in GADT constructors (#19623) One more step towards the new design of EPA. Updates the haddock submodule. - - - - - 23f95735 by sheaf at 2022-04-08T13:57:07-04:00 Docs: datacon eta-expansion, rep-poly checks The existing notes weren't very clear on how the eta-expansion of data constructors that occurs in tcInferDataCon/dsConLike interacts with the representation polymorphism invariants. So we explain with a few more details how we ensure that the representation-polymorphic lambdas introduced by tcInferDataCon/dsConLike don't end up causing problems, by checking they are properly instantiated and then relying on the simple optimiser to perform beta reduction. A few additional changes: - ConLikeTc just take type variables instead of binders, as we never actually used the binders. - Removed the FRRApp constructor of FRROrigin; it was no longer used now that we use ExpectedFunTyOrigin. - Adds a bit of documentation to the constructors of ExpectedFunTyOrigin. - - - - - d4480490 by Matthew Pickering at 2022-04-08T13:57:43-04:00 ci: Replace "always" with "on_success" to stop build jobs running before hadrian-ghci has finished See https://docs.gitlab.com/ee/ci/yaml/#when * always means, always run not matter what * on_success means, run if the dependencies have built successfully - - - - - 0736e949 by Vladislav Zavialov at 2022-04-08T13:58:19-04:00 Disallow (->) as a data constructor name (#16999) The code was misusing isLexCon, which was never meant for validation. In fact, its documentation states the following: Use these functions to figure what kind of name a 'FastString' represents; these functions do /not/ check that the identifier is valid. Ha! This sign can't stop me because I can't read. The fix is to use okConOcc instead. The other checks (isTcOcc or isDataOcc) seem superfluous, so I also removed those. - - - - - e58d5eeb by Simon Peyton Jones at 2022-04-08T13:58:55-04:00 Tiny documentation wibble This commit commit 83363c8b04837ee871a304cf85207cf79b299fb0 Author: Simon Peyton Jones <simon.peytonjones at gmail.com> Date: Fri Mar 11 16:55:38 2022 +0000 Use prepareBinding in tryCastWorkerWrapper refactored completeNonRecX away, but left a Note referring to it. This MR fixes that Note. - - - - - 4bb00839 by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Fix nightly head.hackage pipelines This also needs a corresponding commit to head.hackage, I also made the job explicitly depend on the fedora33 job so that it isn't blocked by a failing windows job, which causes docs-tarball to fail. - - - - - 3c48e12a by Matthew Pickering at 2022-04-09T07:40:28-04:00 ci: Remove doc-tarball dependency from perf and perf-nofib jobs These don't depend on the contents of the tarball so we can run them straight after the fedora33 job finishes. - - - - - 27362265 by Matthew Pickering at 2022-04-09T07:41:04-04:00 Bump deepseq to 1.4.7.0 Updates deepseq submodule Fixes #20653 - - - - - dcf30da8 by Joachim Breitner at 2022-04-09T13:02:19-04:00 Drop the app invariant previously, GHC had the "let/app-invariant" which said that the RHS of a let or the argument of an application must be of lifted type or ok for speculation. We want this on let to freely float them around, and we wanted that on app to freely convert between the two (e.g. in beta-reduction or inlining). However, the app invariant meant that simple code didn't stay simple and this got in the way of rules matching. By removing the app invariant, this thus fixes #20554. The new invariant is now called "let-can-float invariant", which is hopefully easier to guess its meaning correctly. Dropping the app invariant means that everywhere where we effectively do beta-reduction (in the two simplifiers, but also in `exprIsConApp_maybe` and other innocent looking places) we now have to check if the argument must be evaluated (unlifted and side-effecting), and analyses have to be adjusted to the new semantics of `App`. Also, `LetFloats` in the simplifier can now also carry such non-floating bindings. The fix for DmdAnal, refine by Sebastian, makes functions with unlifted arguments strict in these arguments, which changes some signatures. This causes some extra calls to `exprType` and `exprOkForSpeculation`, so some perf benchmarks regress a bit (while others improve). Metric Decrease: T9020 Metric Increase: LargeRecord T12545 T15164 T16577 T18223 T5642 T9961 Co-authored-by: Sebastian Graf <sebastian.graf at kit.edu> - - - - - 6c6c5379 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add functions traceWith, traceShowWith, traceEventWith. As discussed at https://github.com/haskell/core-libraries-committee/issues/36 - - - - - 8fafacf7 by Philip Hazelden at 2022-04-09T13:02:59-04:00 Add tests for several trace functions. - - - - - 20bbf3ac by Philip Hazelden at 2022-04-09T13:02:59-04:00 Update changelog. - - - - - 47d18b0b by Andreas Klebinger at 2022-04-09T13:03:35-04:00 Add regression test for #19569 - - - - - 5f8d6e65 by sheaf at 2022-04-09T13:04:14-04:00 Fix missing SymCo in pushCoercionIntoLambda There was a missing SymCo in pushCoercionIntoLambda. Currently this codepath is only used with rewrite rules, so this bug managed to slip by, but trying to use pushCoercionIntoLambda in other contexts revealed the bug. - - - - - 20eca489 by Vladislav Zavialov at 2022-04-09T13:04:50-04:00 Refactor: simplify lexing of the dot Before this patch, the lexer did a truly roundabout thing with the dot: 1. look up the varsym in reservedSymsFM and turn it into ITdot 2. under OverloadedRecordDot, turn it into ITvarsym 3. in varsym_(prefix|suffix|...) turn it into ITvarsym, ITdot, or ITproj, depending on extensions and whitespace Turns out, the last step is sufficient to handle the dot correctly. This patch removes the first two steps. - - - - - 5440f63e by Hécate Moonlight at 2022-04-12T11:11:06-04:00 Document that DuplicateRecordFields doesn't tolerates ambiguous fields Fix #19891 - - - - - 0090ad7b by Sebastian Graf at 2022-04-12T11:11:42-04:00 Eta reduction based on evaluation context (#21261) I completely rewrote our Notes surrounding eta-reduction. The new entry point is `Note [Eta reduction makes sense]`. Then I went on to extend the Simplifier to maintain an evaluation context in the form of a `SubDemand` inside a `SimplCont`. That `SubDemand` is useful for doing eta reduction according to `Note [Eta reduction based on evaluation context]`, which describes how Demand analysis, Simplifier and `tryEtaReduce` interact to facilitate eta reduction in more scenarios. Thus we fix #21261. ghc/alloc perf marginally improves (-0.0%). A medium-sized win is when compiling T3064 (-3%). It seems that haddock improves by 0.6% to 1.0%, too. Metric Decrease: T3064 - - - - - 4d2ee313 by Sebastian Graf at 2022-04-12T17:54:57+02:00 Specialising through specialised method calls (#19644) In #19644, we discovered that the ClassOp/DFun rules from Note [ClassOp/DFun selection] inhibit transitive specialisation in a scenario like ``` class C a where m :: Show b => a -> b -> ...; n :: ... instance C Int where m = ... -- $cm :: Show b => Int -> b -> ... f :: forall a b. (C a, Show b) => ... f $dC $dShow = ... m @a $dC @b $dShow ... main = ... f @Int @Bool ... ``` After we specialise `f` for `Int`, we'll see `m @a $dC @b $dShow` in the body of `$sf`. But before this patch, Specialise doesn't apply the ClassOp/DFun rule to rewrite to a call of the instance method for `C Int`, e.g., `$cm @Bool $dShow`. As a result, Specialise couldn't further specialise `$cm` for `Bool`. There's a better example in `Note [Specialisation modulo dictionary selectors]`. This patch enables proper Specialisation, as follows: 1. In the App case of `specExpr`, try to apply the CalssOp/DictSel rule on the head of the application 2. Attach an unfolding to freshly-bound dictionary ids such as `$dC` and `$dShow` in `bindAuxiliaryDict` NB: Without (2), (1) would be pointless, because `lookupRule` wouldn't be able to look into the RHS of `$dC` to see the DFun. (2) triggered #21332, because the Specialiser floats around dictionaries without accounting for them in the `SpecEnv`'s `InScopeSet`, triggering a panic when rewriting dictionary unfoldings. Fixes #19644 and #21332. - - - - - b06f4f47 by Sebastian Graf at 2022-04-12T17:54:58+02:00 Specialise: Check `typeDeterminesValue` before specialising on an interesting dictionary I extracted the checks from `Note [Type determines value]` into its own function, so that we share the logic properly. Then I made sure that we actually call `typeDeterminesValue` everywhere we check for `interestingDict`. - - - - - a42dbc55 by Matthew Pickering at 2022-04-13T06:24:52-04:00 Refine warning about defining rules in SAFE modules This change makes it clear that it's the definition rather than any usage which is a problem, and that rules defined in other modules will still be used to do rewrites. Fixes #20923 - - - - - df893f66 by Andreas Klebinger at 2022-04-14T08:18:37-04:00 StgLint: Lint constructor applications and strict workers for arity. This will mean T9208 when run with lint will return a lint error instead of resulting in a panic. Fixes #21117 - - - - - 426ec446 by sheaf at 2022-04-14T08:19:16-04:00 Hadrian: use a set to keep track of ways The order in which ways are provided doesn't matter, so we use a data structure with the appropriate semantics to represent ways. Fixes #21378 - - - - - 7c639b9a by Dylan Yudaken at 2022-04-15T13:55:59-04:00 Only enable PROF_SPIN in DEBUG - - - - - 96b9e5ea by Ben Gamari at 2022-04-15T13:56:34-04:00 testsuite: Add test for #21390 - - - - - d8392f6a by Ben Gamari at 2022-04-15T13:56:34-04:00 rts: Ensure that the interpreter doesn't disregard tags Previously the interpreter's handling of `RET_BCO` stack frames would throw away the tag of the returned closure. This resulted in #21390. - - - - - 83c67f76 by Alan Zimmerman at 2022-04-20T11:49:28-04:00 Add -dkeep-comments flag to keep comments in the parser This provides a way to set the Opt_KeepRawTokenStream from the command line, allowing exact print annotation users to see exactly what is produced for a given parsed file, when used in conjunction with -ddump-parsed-ast Discussed in #19706, but this commit does not close the issue. - - - - - a5ea65c9 by Krzysztof Gogolewski at 2022-04-20T11:50:04-04:00 Remove LevityInfo Every Id was storing a boolean whether it could be levity-polymorphic. This information is no longer needed since representation-checking has been moved to the typechecker. - - - - - 49bd7584 by Andreas Klebinger at 2022-04-20T11:50:39-04:00 Fix a shadowing issue in StgUnarise. For I assume performance reasons we don't record no-op replacements during unarise. This lead to problems with code like this: f = \(Eta_B0 :: VoidType) x1 x2 -> ... let foo = \(Eta_B0 :: LiftedType) -> g x y Eta_B0 in ... Here we would record the outer Eta_B0 as void rep, but would not shadow Eta_B0 inside `foo` because this arg is single-rep and so doesn't need to replaced. But this means when looking at occurence sites we would check the env and assume it's void rep based on the entry we made for the (no longer in scope) outer `Eta_B0`. Fixes #21396 and the ticket has a few more details. - - - - - 0c02c919 by Simon Peyton Jones at 2022-04-20T11:51:15-04:00 Fix substitution in bindAuxiliaryDict In GHC.Core.Opt.Specialise.bindAuxiliaryDict we were unnecessarily calling `extendInScope` to bring into scope variables that were /already/ in scope. Worse, GHC.Core.Subst.extendInScope strangely deleted the newly-in-scope variables from the substitution -- and that was fatal in #21391. I removed the redundant calls to extendInScope. More ambitiously, I changed GHC.Core.Subst.extendInScope (and cousins) to stop deleting variables from the substitution. I even changed the names of the function to extendSubstInScope (and cousins) and audited all the calls to check that deleting from the substitution was wrong. In fact there are very few such calls, and they are all about introducing a fresh non-in-scope variable. These are "OutIds"; it is utterly wrong to mess with the "InId" substitution. I have not added a Note, because I'm deleting wrong code, and it'd be distracting to document a bug. - - - - - 0481a6af by Cheng Shao at 2022-04-21T11:06:06+00:00 [ci skip] Drop outdated TODO in RtsAPI.c - - - - - 1e062a8a by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Introduce ip_STACK_FRAME While debugging it is very useful to be able to determine whether a given info table is a stack frame or not. We have spare bits in the closure flags array anyways, use one for this information. - - - - - 08a6a2ee by Ben Gamari at 2022-04-22T02:12:59-04:00 rts: Mark closureFlags array as const - - - - - 8f9b8282 by Krzysztof Gogolewski at 2022-04-22T02:13:35-04:00 Check for zero-bit types in sizeExpr Fixes #20940 Metric Decrease: T18698a - - - - - fcf22883 by Andreas Klebinger at 2022-04-22T02:14:10-04:00 Include the way string in the file name for dump files. This can be disabled by `-fno-dump-with-ways` if not desired. Finally we will be able to look at both profiled and non-profiled dumps when compiling with dump flags and we compile in both ways. - - - - - 252394ce by Bodigrim at 2022-04-22T02:14:48-04:00 Improve error messages from GHC.IO.Encoding.Failure - - - - - 250f57c1 by Bodigrim at 2022-04-22T02:14:48-04:00 Update test baselines to match new error messages from GHC.IO.Encoding.Failure - - - - - 5ac9b321 by Ben Gamari at 2022-04-22T02:15:25-04:00 get-win32-tarballs: Drop i686 architecture As of #18487 we no longer support 32-bit Windows. Fixes #21372. - - - - - dd5fecb0 by Ben Gamari at 2022-04-22T02:16:00-04:00 hadrian: Don't rely on xxx not being present in installation path Previously Hadrian's installation makefile would assume that the string `xxx` did not appear in the installation path. This would of course break for some users. Fixes #21402. - - - - - 09e98859 by Ben Gamari at 2022-04-22T02:16:35-04:00 testsuite: Ensure that GHC doesn't pick up environment files Here we set GHC_ENVIRONMENT="-" to ensure that GHC invocations of tests don't pick up a user's local package environment. Fixes #21365. Metric Decrease: T10421 T12234 T12425 T13035 T16875 T9198 - - - - - 76bb8cb3 by Ben Gamari at 2022-04-22T02:17:11-04:00 hadrian: Enable -dlint in devel2 flavour Previously only -dcore-lint was enabled. - - - - - f435d55f by Krzysztof Gogolewski at 2022-04-22T08:00:18-04:00 Fixes to rubbish literals * In CoreToStg, the application 'RUBBISH[rep] x' was simplified to 'RUBBISH[rep]'. But it is possible that the result of the function is represented differently than the function. * In Unarise, 'LitRubbish (primRepToType prep)' is incorrect: LitRubbish takes a RuntimeRep such as IntRep, while primRepToType returns a type such as Any @(TYPE IntRep). Use primRepToRuntimeRep instead. This code is never run in the testsuite. * In StgToByteCode, all rubbish literals were assumed to be boxed. This code predates representation-polymorphic RubbishLit and I think it was not updated. I don't have a testcase for any of those issues, but the code looks wrong. - - - - - 93c16b94 by sheaf at 2022-04-22T08:00:57-04:00 Relax "suppressing errors" assert in reportWanteds The assertion in reportWanteds that we aren't suppressing all the Wanted constraints was too strong: it might be the case that we are inside an implication, and have already reported an unsolved Wanted from outside the implication. It is possible that all Wanteds inside the implication have been rewritten by the outer Wanted, so we shouldn't throw an assertion failure in that case. Fixes #21405 - - - - - 78ec692d by Andreas Klebinger at 2022-04-22T08:01:33-04:00 Mention new MutableByteArray# wrapper in base changelog. - - - - - 56d7cb53 by Eric Lindblad at 2022-04-22T14:13:32-04:00 unlist announce - - - - - 1e4dcf23 by sheaf at 2022-04-22T14:14:12-04:00 decideMonoTyVars: account for CoVars in candidates The "candidates" passed to decideMonoTyVars can contain coercion holes. This is because we might well decide to quantify over some unsolved equality constraints, as long as they are not definitely insoluble. In that situation, decideMonoTyVars was passing a set of type variables that was not closed over kinds to closeWrtFunDeps, which was tripping up an assertion failure. Fixes #21404 - - - - - 2c541f99 by Simon Peyton Jones at 2022-04-22T14:14:47-04:00 Improve floated dicts in Specialise Second fix to #21391. It turned out that we missed calling bringFloatedDictsIntoScope when specialising imports, which led to the same bug as before. I refactored to move that call to a single place, in specCalls, so we can't forget it. This meant making `FloatedDictBinds` into its own type, pairing the dictionary bindings themselves with the set of their binders. Nicer this way. - - - - - 0950e2c4 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Ensure that --extra-lib-dirs are used Previously we only took `extraLibDirs` and friends from the package description, ignoring any contribution from the `LocalBuildInfo`. Fix this. Fixes #20566. - - - - - 53cc93ae by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Drop redundant include directories The package-specific include directories in Settings.Builders.Common.cIncludeDirs are now redundant since they now come from Cabal. Closes #20566. - - - - - b2721819 by Ben Gamari at 2022-04-25T10:18:17-04:00 hadrian: Clean up handling of libffi dependencies - - - - - 18e5103f by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: More robust library way detection Previously `test.mk` would try to determine whether the dynamic, profiling, and vanilla library ways are available by searching for `PrimOpWrappers.{,dyn_,p_}hi` in directory reported by `ghc-pkg field ghc-prim library-dirs`. However, this is extremely fragile as there is no guarantee that there is only one library directory. To handle the case of multiple `library-dirs` correct we would have to carry out the delicate task of tokenising the directory list (in shell, no less). Since this isn't a task that I am eager to solve, I have rather moved the detection logic into the testsuite driver and instead perform a test compilation in each of the ways. This should be more robust than the previous approach. I stumbled upon this while fixing #20579. - - - - - 6c7a4913 by Ben Gamari at 2022-04-25T10:18:17-04:00 testsuite: Cabalify ghc-config To ensure that the build benefits from Hadrian's usual logic for building packages, avoiding #21409. Closes #21409. - - - - - 9af091f7 by Ben Gamari at 2022-04-25T10:18:53-04:00 rts: Factor out built-in GC roots - - - - - e7c4719d by Ben Gamari at 2022-04-25T10:18:54-04:00 Ensure that wired-in exception closures aren't GC'd As described in Note [Wired-in exceptions are not CAFfy], a small set of built-in exception closures get special treatment in the code generator, being declared as non-CAFfy despite potentially containing CAF references. The original intent of this treatment for the RTS to then add StablePtrs for each of the closures, ensuring that they are not GC'd. However, this logic was not applied consistently and eventually removed entirely in 951c1fb0. This lead to #21141. Here we fix this bug by reintroducing the StablePtrs and document the status quo. Closes #21141. - - - - - 9587726f by Ben Gamari at 2022-04-25T10:18:54-04:00 testsuite: Add testcase for #21141 - - - - - cb71226f by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop dead code in GHC.Linker.Static.linkBinary' Previously we supported building statically-linked executables using libtool. However, this was dropped in 91262e75dd1d80f8f28a3922934ec7e59290e28c in favor of using ar/ranlib directly. Consequently we can drop this logic. Fixes #18826. - - - - - 9420d26b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop libtool path from settings file GHC no longers uses libtool for linking and therefore this is no longer necessary. - - - - - 41cf758b by Ben Gamari at 2022-04-25T10:19:29-04:00 Drop remaining vestiges of libtool Drop libtool logic from gen-dll, allowing us to drop the remaining logic from the `configure` script. Strangely, this appears to reliably reduce compiler allocations of T16875 on Windows. Closes #18826. Metric Decrease: T16875 - - - - - e09afbf2 by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - e76705cf by Ben Gamari at 2022-04-25T10:20:05-04:00 rts: Improve documentation of closure types Also drops the unused TREC_COMMITTED transaction state. - - - - - f2c08124 by Bodigrim at 2022-04-25T10:20:44-04:00 Document behaviour of RULES with KnownNat - - - - - 360dc2bc by Li-yao Xia at 2022-04-25T19:13:06+00:00 Fix rendering of liftA haddock - - - - - 16df6058 by Ben Gamari at 2022-04-27T10:02:25-04:00 testsuite: Report minimum and maximum stat changes As suggested in #20733. - - - - - e39cab62 by Fabian Thorand at 2022-04-27T10:03:03-04:00 Defer freeing of mega block groups Solves the quadratic worst case performance of freeing megablocks that was described in issue #19897. During GC runs, we now keep a secondary free list for megablocks that is neither sorted, nor coalesced. That way, free becomes an O(1) operation at the expense of not being able to reuse memory for larger allocations. At the end of a GC run, the secondary free list is sorted and then merged into the actual free list in a single pass. That way, our worst case performance is O(n log(n)) rather than O(n^2). We postulate that temporarily losing coalescense during a single GC run won't have any adverse effects in practice because: - We would need to release enough memory during the GC, and then after that (but within the same GC run) allocate a megablock group of more than one megablock. This seems unlikely, as large objects are not copied during GC, and so we shouldn't need such large allocations during a GC run. - Allocations of megablock groups of more than one megablock are rare. They only happen when a single heap object is large enough to require that amount of space. Any allocation areas that are supposed to hold more than one heap object cannot use megablock groups, because only the first megablock of a megablock group has valid `bdescr`s. Thus, heap object can only start in the first megablock of a group, not in later ones. - - - - - 5de6be0c by Fabian Thorand at 2022-04-27T10:03:03-04:00 Add note about inefficiency in returnMemoryToOS - - - - - 8bef471a by sheaf at 2022-04-27T10:03:43-04:00 Ensure that Any is Boxed in FFI imports/exports We should only accept the type `Any` in foreign import/export declarations when it has type `Type` or `UnliftedType`. This patch adds a kind check, and a special error message triggered by occurrences of `Any` in foreign import/export declarations at other kinds. Fixes #21305 - - - - - ba3d4e1c by Ben Gamari at 2022-04-27T10:04:19-04:00 Basic response file support Here we introduce support into our command-line parsing infrastructure and driver for handling gnu-style response file arguments, typically used to work around platform command-line length limitations. Fixes #16476. - - - - - 3b6061be by Ben Gamari at 2022-04-27T10:04:19-04:00 testsuite: Add test for #16476 - - - - - 75bf1337 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix cabal-reinstall job It's quite nice we can do this by mostly deleting code Fixes #21373 - - - - - 2c00d904 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add test to check that release jobs have profiled libs - - - - - 50d78d3b by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Explicitly handle failures in test_hadrian We also disable the stage1 testing which is broken. Related to #21072 - - - - - 2dcdf091 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Fix shell command - - - - - 55c84123 by Matthew Pickering at 2022-04-27T10:04:55-04:00 bootstrap: Add bootstrapping files for ghc-9_2_2 Fixes #21373 - - - - - c7ee0be6 by Matthew Pickering at 2022-04-27T10:04:55-04:00 ci: Add linting job which checks authors are not GHC CI - - - - - 23aad124 by Adam Sandberg Ericsson at 2022-04-27T10:05:31-04:00 rts: state explicitly what evacuate and scavange mean in the copying gc - - - - - 318e0005 by Ben Gamari at 2022-04-27T10:06:07-04:00 rts/eventlog: Don't attempt to flush if there is no writer If the user has not configured a writer then there is nothing to flush. - - - - - ee11d043 by Ben Gamari at 2022-04-27T10:06:07-04:00 Enable eventlog support in all ways by default Here we deprecate the eventlogging RTS ways and instead enable eventlog support in the remaining ways. This simplifies packaging and reduces GHC compilation times (as we can eliminate two whole compilations of the RTS) while simplifying the end-user story. The trade-off is a small increase in binary sizes in the case that the user does not want eventlogging support, but we think that this is a fine trade-off. This also revealed a latent RTS bug: some files which included `Cmm.h` also assumed that it defined various macros which were in fact defined by `Config.h`, which `Cmm.h` did not include. Fixing this in turn revealed that `StgMiscClosures.cmm` failed to import various spinlock statistics counters, as evidenced by the failed unregisterised build. Closes #18948. - - - - - a2e5ab70 by Andreas Klebinger at 2022-04-27T10:06:43-04:00 Change `-dsuppress-ticks` to only suppress non-code ticks. This means cost centres and coverage ticks will still be present in output. Makes using -dsuppress-all more convenient when looking at profiled builds. - - - - - ec9d7e04 by Ben Gamari at 2022-04-27T10:07:21-04:00 Bump text submodule. This should fix #21352 - - - - - c3105be4 by Bodigrim at 2022-04-27T10:08:01-04:00 Documentation for setLocaleEncoding - - - - - 7f618fd3 by sheaf at 2022-04-27T10:08:40-04:00 Update docs for change to type-checking plugins There was no mention of the changes to type-checking plugins in the 9.4.1 notes, and the extending_ghc documentation contained a reference to an outdated type. - - - - - 4419dd3a by Adam Sandberg Ericsson at 2022-04-27T10:09:18-04:00 rts: add some more documentation to StgWeak closure type - - - - - 5a7f0dee by Matthew Pickering at 2022-04-27T10:09:54-04:00 Give Cmm files fake ModuleNames which include full filepath This fixes the initialisation functions when using -prof or -finfo-table-map. Fixes #21370 - - - - - 81cf52bb by sheaf at 2022-04-27T10:10:33-04:00 Mark GHC.Prim.PtrEq as Unsafe This module exports unsafe pointer equality operations, so we accordingly mark it as Unsafe. Fixes #21433 - - - - - f6a8185d by Ben Gamari at 2022-04-28T09:10:31+00:00 testsuite: Add performance test for #14766 This distills the essence of the Sigs.hs program found in the ticket. - - - - - c7a3dc29 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Add Monoid instance to Way - - - - - 654bafea by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Enrich flavours to build profiled/debugged/threaded ghcs per stage - - - - - 4ad559c8 by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: add debug_ghc and debug_stage1_ghc flavour transformers - - - - - f9728fdb by Douglas Wilson at 2022-04-28T18:54:44-04:00 hadrian: Don't pass -rtsopts when building libraries - - - - - 769279e6 by Matthew Pickering at 2022-04-28T18:54:44-04:00 testsuite: Fix calculation about whether to pass -dynamic to compiler - - - - - da8ae7f2 by Ben Gamari at 2022-04-28T18:55:20-04:00 hadrian: Clean up flavour transformer definitions Previously the `ipe` and `omit_pragmas` transformers were hackily defined using the textual key-value syntax. Fix this. - - - - - 61305184 by Ben Gamari at 2022-04-28T18:55:56-04:00 Bump process submodule - - - - - a8c99391 by sheaf at 2022-04-28T18:56:37-04:00 Fix unification of ConcreteTvs, removing IsRefl# This patch fixes the unification of concrete type variables. The subtlety was that unifying concrete metavariables is more subtle than other metavariables, as decomposition is possible. See the Note [Unifying concrete metavariables], which explains how we unify a concrete type variable with a type 'ty' by concretising 'ty', using the function 'GHC.Tc.Utils.Concrete.concretise'. This can be used to perform an eager syntactic check for concreteness, allowing us to remove the IsRefl# special predicate. Instead of emitting two constraints `rr ~# concrete_tv` and `IsRefl# rr concrete_tv`, we instead concretise 'rr'. If this succeeds we can fill 'concrete_tv', and otherwise we directly emit an error message to the typechecker environment instead of deferring. We still need the error message to be passed on (instead of directly thrown), as we might benefit from further unification in which case we will need to zonk the stored types. To achieve this, we change the 'wc_holes' field of 'WantedConstraints' to 'wc_errors', which stores general delayed errors. For the moement, a delayed error is either a hole, or a syntactic equality error. hasFixedRuntimeRep_MustBeRefl is now hasFixedRuntimeRep_syntactic, and hasFixedRuntimeRep has been refactored to directly return the most useful coercion for PHASE 2 of FixedRuntimeRep. This patch also adds a field ir_frr to the InferResult datatype, holding a value of type Maybe FRROrigin. When this value is not Nothing, this means that we must fill the ir_ref field with a type which has a fixed RuntimeRep. When it comes time to fill such an ExpType, we ensure that the type has a fixed RuntimeRep by performing a representation-polymorphism check with the given FRROrigin This is similar to what we already do to ensure we fill an Infer ExpType with a type of the correct TcLevel. This allows us to properly perform representation-polymorphism checks on 'Infer' 'ExpTypes'. The fillInferResult function had to be moved to GHC.Tc.Utils.Unify to avoid a cyclic import now that it calls hasFixedRuntimeRep. This patch also changes the code in matchExpectedFunTys to make use of the coercions, which is now possible thanks to the previous change. This implements PHASE 2 of FixedRuntimeRep in some situations. For example, the test cases T13105 and T17536b are now both accepted. Fixes #21239 and #21325 ------------------------- Metric Decrease: T18223 T5631 ------------------------- - - - - - 43bd897d by Simon Peyton Jones at 2022-04-28T18:57:13-04:00 Add INLINE pragmas for Enum helper methods As #21343 showed, we need to be super-certain that the "helper methods" for Enum instances are actually inlined or specialised. I also tripped over this when I discovered that numericEnumFromTo and friends had no pragmas at all, so their performance was very fragile. If they weren't inlined, all bets were off. So I've added INLINE pragmas for them too. See new Note [Inline Enum method helpers] in GHC.Enum. I also expanded Note [Checking for INLINE loop breakers] in GHC.Core.Lint to explain why an INLINE function might temporarily be a loop breaker -- this was the initial bug report in #21343. Strangely we get a 16% runtime allocation decrease in perf/should_run/T15185, but only on i386. Since it moves in the right direction I'm disinclined to investigate, so I'll accept it. Metric Decrease: T15185 - - - - - ca1434e3 by Ben Gamari at 2022-04-28T18:57:49-04:00 configure: Bump GHC version to 9.5 Bumps haddock submodule. - - - - - 292e3971 by Teo Camarasu at 2022-04-28T18:58:28-04:00 add since annotation for GHC.Stack.CCS.whereFrom - - - - - 905206d6 by Tamar Christina at 2022-04-28T22:19:34-04:00 winio: add support to iserv. - - - - - d182897e by Tamar Christina at 2022-04-28T22:19:34-04:00 Remove unused line - - - - - 22cf4698 by Matthew Pickering at 2022-04-28T22:20:10-04:00 Revert "rts: Refactor handling of dead threads' stacks" This reverts commit e09afbf2a998beea7783e3de5dce5dd3c6ff23db. - - - - - 8ed57135 by Matthew Pickering at 2022-04-29T04:11:29-04:00 Provide efficient unionMG function for combining two module graphs. This function is used by API clients (hls). This supercedes !6922 - - - - - 0235ff02 by Ben Gamari at 2022-04-29T04:12:05-04:00 Bump bytestring submodule Update to current `master`. - - - - - 01988418 by Matthew Pickering at 2022-04-29T04:12:05-04:00 testsuite: Normalise package versions in UnusedPackages test - - - - - 724d0dc0 by Matthew Pickering at 2022-04-29T08:59:42+00:00 testsuite: Deduplicate ways correctly This was leading to a bug where we would run a profasm test twice which led to invalid junit.xml which meant the test results database was not being populated for the fedora33-perf job. - - - - - 5630dde6 by Ben Gamari at 2022-04-29T13:06:20-04:00 rts: Refactor handling of dead threads' stacks This fixes a bug that @JunmingZhao42 and I noticed while working on her MMTK port. Specifically, in stg_stop_thread we used stg_enter_info as a sentinel at the tail of a stack after a thread has completed. However, stg_enter_info expects to have a two-field payload, which we do not push. Consequently, if the GC ends up somehow the stack it will attempt to interpret data past the end of the stack as the frame's fields, resulting in unsound behavior. To fix this I eliminate this hacky use of `stg_stop_thread` and instead introduce a new stack frame type, `stg_dead_thread_info`. Not only does this eliminate the potential for the previously mentioned memory unsoundness but it also more clearly captures the intended structure of the dead threads' stacks. - - - - - 0cdef807 by parsonsmatt at 2022-04-30T16:51:12-04:00 Add a note about instance visibility across component boundaries In principle, the *visible* instances are * all instances defined in a prior top-level declaration group (see docs on `newDeclarationGroup`), or * all instances defined in any module transitively imported by the module being compiled However, actually searching all modules transitively below the one being compiled is unreasonably expensive, so `reifyInstances` will report only the instance for modules that GHC has had some cause to visit during this compilation. This is a shortcoming: `reifyInstances` might fail to report instances for a type that is otherwise unusued, or instances defined in a different component. You can work around this shortcoming by explicitly importing the modules whose instances you want to be visible. GHC issue #20529 has some discussion around this. Fixes #20529 - - - - - e2dd884a by Ryan Scott at 2022-04-30T16:51:47-04:00 Make mkFunCo take AnonArgFlags into account Previously, whenever `mkFunCo` would produce reflexive coercions, it would use `mkVisFunTy` to produce the kind of the coercion. However, `mkFunCo` is also used to produce coercions between types of the form `ty1 => ty2` in certain places. This has the unfortunate side effect of causing the type of the coercion to appear as `ty1 -> ty2` in certain error messages, as spotted in #21328. This patch address this by changing replacing the use of `mkVisFunTy` with `mkFunctionType` in `mkFunCo`. `mkFunctionType` checks the kind of `ty1` and makes the function arrow `=>` instead of `->` if `ty1` has kind `Constraint`, so this should always produce the correct `AnonArgFlag`. As a result, this patch fixes part (2) of #21328. This is not the only possible way to fix #21328, as the discussion on that issue lists some possible alternatives. Ultimately, it was concluded that the alternatives would be difficult to maintain, and since we already use `mkFunctionType` in `coercionLKind` and `coercionRKind`, using `mkFunctionType` in `mkFunCo` is consistent with this choice. Moreover, using `mkFunctionType` does not regress the performance of any test case we have in GHC's test suite. - - - - - 170da54f by Ben Gamari at 2022-04-30T16:52:27-04:00 Convert More Diagnostics (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors. - - - - - 39edc7b4 by Marius Ghita at 2022-04-30T16:53:06-04:00 Update user guide example rewrite rules formatting Change the rewrite rule examples to include a space between the composition of `f` and `g` in the map rewrite rule examples. Without this change, if the user has locally enabled the extension OverloadedRecordDot the copied example will result in a compile time error that `g` is not a field of `f`. ``` • Could not deduce (GHC.Records.HasField "g" (a -> b) (a1 -> b)) arising from selecting the field ‘g’ ``` - - - - - 2e951e48 by Adam Sandberg Ericsson at 2022-04-30T16:53:42-04:00 ghc-boot: export typesynonyms from GHC.Utils.Encoding This makes the Haddocks easier to understand. - - - - - d8cbc77e by Adam Sandberg Ericsson at 2022-04-30T16:54:18-04:00 users guide: add categories to some flags - - - - - d0f14fad by Chris Martin at 2022-04-30T16:54:57-04:00 hacking guide: mention the core libraries committee - - - - - 34b28200 by Matthew Pickering at 2022-04-30T16:55:32-04:00 Revert "Make the specialiser handle polymorphic specialisation" This reverts commit ef0135934fe32da5b5bb730dbce74262e23e72e8. See ticket #21229 ------------------------- Metric Decrease: T15164 Metric Increase: T13056 ------------------------- - - - - - ee891c1e by Matthew Pickering at 2022-04-30T16:55:32-04:00 Add test for T21229 - - - - - ab677cc8 by Matthew Pickering at 2022-04-30T16:56:08-04:00 Hadrian: Update README about the flavour/testsuite contract There have been a number of tickets about non-tested flavours not passing the testsuite.. this is expected and now noted in the documentation. You use other flavours to run the testsuite at your own risk. Fixes #21418 - - - - - b57b5b92 by Ben Gamari at 2022-04-30T16:56:44-04:00 rts/m32: Fix assertion failure This fixes an assertion failure in the m32 allocator due to the imprecisely specified preconditions of `m32_allocator_push_filled_list`. Specifically, the caller must ensure that the page type is set to filled prior to calling `m32_allocator_push_filled_list`. While this issue did result in an assertion failure in the debug RTS, the issue is in fact benign. - - - - - a7053a6c by sheaf at 2022-04-30T16:57:23-04:00 Testsuite driver: don't crash on empty metrics The testsuite driver crashed when trying to display minimum/maximum performance changes when there are no metrics (i.e. there is no baseline available). This patch fixes that. - - - - - 636f7c62 by Andreas Klebinger at 2022-05-01T22:21:17-04:00 StgLint: Check that functions are applied to compatible runtime reps We use compatibleRep to compare reps, and avoid checking functions with levity polymorphic types because of #21399. - - - - - 60071076 by Hécate Moonlight at 2022-05-01T22:21:55-04:00 Add documentation to the ByteArray# primetype. close #21417 - - - - - 2b2e3020 by Andreas Klebinger at 2022-05-01T22:22:31-04:00 exprIsDeadEnd: Use isDeadEndAppSig to check if a function appliction is bottoming. We used to check the divergence and that the number of arguments > arity. But arity zero represents unknown arity so this was subtly broken for a long time! We would check if the saturated function diverges, and if we applied >=arity arguments. But for unknown arity functions any number of arguments is >=idArity. This fixes #21440. - - - - - 4eaf0f33 by Eric Lindblad at 2022-05-01T22:23:11-04:00 typos - - - - - fc58df90 by Niklas Hambüchen at 2022-05-02T08:59:27+00:00 libraries/base: docs: Explain relationshipt between `finalizeForeignPtr` and `*Conc*` creation Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/21420 - - - - - 3e400f20 by Krzysztof Gogolewski at 2022-05-02T18:29:23-04:00 Remove obsolete code in CoreToStg Note [Nullary unboxed tuple] was removed in e9e61f18a548b70693f4. This codepath is tested by T15696_3. - - - - - 4a780928 by Krzysztof Gogolewski at 2022-05-02T18:29:24-04:00 Fix several note references - - - - - 15ffe2b0 by Sebastian Graf at 2022-05-03T20:11:51+02:00 Assume at least one evaluation for nested SubDemands (#21081, #21133) See the new `Note [SubDemand denotes at least one evaluation]`. A demand `n :* sd` on a let binder `x=e` now means > "`x` was evaluated `n` times and in any program trace it is evaluated, `e` is > evaluated deeply in sub-demand `sd`." The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081) ```hs f :: (Bool, Bool) -> (Bool, Bool) f pr = (case pr of (a,b) -> a /= b, True) -- before: <MP(L,L)> -- after: <MP(SL,SL)> g :: Int -> (Bool, Bool) g x = let y = let z = odd x in (z,z) in f y ``` The change in demand signature "before" to "after" allows us to case-bind `z` here. Similarly good things happen for the `sd` in call sub-demands `Cn(sd)`, which allows for more eta-reduction (which is only sound with `-fno-pedantic-bottoms`, albeit). We also fix #21085, a surprising inconsistency with `Poly` to `Call` sub-demand expansion. In an attempt to fix a regression caused by less inlining due to eta-reduction in T15426, I eta-expanded the definition of `elemIndex` and `elemIndices`, thus fixing #21345 on the go. The main point of this patch is that it fixes #21081 and #21133. Annoyingly, I discovered that more precise demand signatures for join points can transform a program into a lazier program if that join point gets floated to the top-level, see #21392. There is no simple fix at the moment, but !5349 might. Thus, we accept a ~5% regression in `MultiLayerModulesTH_OneShot`, where #21392 bites us in `addListToUniqDSet`. T21392 reliably reproduces the issue. Surprisingly, ghc/alloc perf on Windows improves much more than on other jobs, by 0.4% in the geometric mean and by 2% in T16875. Metric Increase: MultiLayerModulesTH_OneShot Metric Decrease: T16875 - - - - - 948c7e40 by Andreas Klebinger at 2022-05-04T09:57:34-04:00 CoreLint - When checking for levity polymorphism look through more ticks. For expressions like `(scc<cc_name> primOp#) arg1` we should also look at arg1 to determine if we call primOp# at a fixed runtime rep. This is what corePrep already does but CoreLint didn't yet. This patch will bring them in sync in this regard. It also uses tickishFloatable in CorePrep instead of CorePrep having it's own slightly differing definition of when a tick is floatable. - - - - - 85bc73bd by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Support Unicode properly - - - - - 063d485e by Alexis King at 2022-05-04T09:58:14-04:00 genprimopcode: Replace LaTeX documentation syntax with Haddock The LaTeX documentation generator does not seem to have been used for quite some time, so the LaTeX-to-Haddock preprocessing step has become a pointless complication that makes documenting the contents of GHC.Prim needlessly difficult. This commit replaces the LaTeX syntax with the Haddock it would have been converted into, anyway, though with an additional distinction: it uses single quotes in places to instruct Haddock to generate hyperlinks to bindings. This improves the quality of the generated output. - - - - - d61f7428 by Ben Gamari at 2022-05-04T09:58:50-04:00 rts/ghc.mk: Only build StgCRunAsm.S when it is needed Previously the make build system unconditionally included StgCRunAsm.S in the link, meaning that the RTS would require an execstack unnecessarily. Fixes #21478. - - - - - 934a90dd by Simon Peyton Jones at 2022-05-04T16:15:34-04:00 Improve error reporting in generated code Our error reporting in generated code (via desugaring before typechecking) only worked when the generated code was just a simple call. This commit makes it work in nested cases. - - - - - 445d3657 by sheaf at 2022-05-04T16:16:12-04:00 Ensure Any is not levity-polymorphic in FFI The previous patch forgot to account for a type such as Any @(TYPE (BoxedRep l)) for a quantified levity variable l. - - - - - ddd2591c by Ben Gamari at 2022-05-04T16:16:48-04:00 Update supported LLVM versions Pull forward minimum version to match 9.2. (cherry picked from commit c26faa54c5fbe902ccb74e79d87e3fa705e270d1) - - - - - f9698d79 by Ben Gamari at 2022-05-04T16:16:48-04:00 testsuite/T7275: Use sed -r Darwin requires the `-r` flag to be compatible with GNU sed. (cherry picked from commit 512338c8feec96c38ef0cf799f3a01b77c967c56) - - - - - 8635323b by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Use ld.lld on ARMv7/Linux Due to #16177. Also cleanup some code style issues. (cherry picked from commit cc1c3861e2372f464bf9e3c9c4d4bd83f275a1a6) - - - - - 4f6370c7 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Always preserve artifacts, even in failed jobs (cherry picked from commit fd08b0c91ea3cab39184f1b1b1aafcd63ce6973f) - - - - - 6f662754 by Ben Gamari at 2022-05-04T16:16:48-04:00 configure: Make sphinx version check more robust It appears that the version of sphinx shipped on CentOS 7 reports a version string of `Sphinx v1...`. Accept the `v`. (cherry picked from commit a9197a292fd4b13308dc6664c01351c7239357ed) - - - - - 0032dc38 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab-ci: Don't run make job in release pipelines (cherry picked from commit 16d6a8ff011f2194485387dcca1c00f8ddcdbdeb) - - - - - 27f9aab3 by Ben Gamari at 2022-05-04T16:16:48-04:00 gitlab/ci: Fix name of bootstrap compiler directory Windows binary distributions built with Hadrian have a target platform suffix in the name of their root directory. Teach `ci.sh` about this fact. (cherry picked from commit df5752f39671f6d04d8cd743003469ae5eb67235) - - - - - b528f0f6 by Krzysztof Gogolewski at 2022-05-05T09:05:43-04:00 Fix several note references, part 2 - - - - - 691aacf6 by Adam Sandberg Ericsson at 2022-05-05T09:06:19-04:00 adjustors: align comment about number of integer like arguments with implementation for Amd4+MinGW implementation - - - - - f050557e by Simon Jakobi at 2022-05-05T12:47:32-04:00 Remove two uses of IntMap.size IntMap.size is O(n). The new code should be slightly more efficient. The transformation of GHC.CmmToAsm.CFG.calcFreqs.nodeCount can be described formally as the transformation: (\sum_{0}^{n-1} \sum_{0}^{k-1} i_nk) + n ==> (\sum_{0}^{n-1} 1 + \sum_{0}^{k-1} i_nk) - - - - - 7da90ae3 by Tom Ellis at 2022-05-05T12:48:09-04:00 Explain that 'fail s' should run in the monad itself - - - - - 610d0283 by Matthew Craven at 2022-05-05T12:48:47-04:00 Add a test for the bracketing in rules for (^) - - - - - 016f9ca6 by Matthew Craven at 2022-05-05T12:48:47-04:00 Fix broken rules for (^) with known small powers - - - - - 9372aaab by Matthew Craven at 2022-05-05T12:48:47-04:00 Give the two T19569 tests different names - - - - - 61901b32 by Andreas Klebinger at 2022-05-05T12:49:23-04:00 SpecConstr: Properly create rules for call patterns representing partial applications The main fix is that in addVoidWorkerArg we now add the argument to the front. This fixes #21448. ------------------------- Metric Decrease: T16875 ------------------------- - - - - - 71278dc7 by Teo Camarasu at 2022-05-05T12:50:03-04:00 add since annotations for instances of ByteArray - - - - - 962ff90b by sheaf at 2022-05-05T12:50:42-04:00 Start 9.6.1-notes Updates the documentation notes to start tracking changes for the 9.6.1 release (instead of 9.4). - - - - - aacb15a3 by Matthew Pickering at 2022-05-05T20:24:01-04:00 ci: Add job to check that jobs.yaml is up-to-date There have been quite a few situations where jobs.yaml has been out of date. It's better to add a CI job which checks that it's right. We don't want to use a staged pipeline because it obfuscates the structure of the pipeline. - - - - - be7102e5 by Ben Gamari at 2022-05-05T20:24:37-04:00 rts: Ensure that XMM registers are preserved on Win64 Previously we only preserved the bottom 64-bits of the callee-saved 128-bit XMM registers, in violation of the Win64 calling convention. Fix this. Fixes #21465. - - - - - 73b22ff1 by Ben Gamari at 2022-05-05T20:24:37-04:00 testsuite: Add test for #21465 - - - - - e2ae9518 by Ziyang Liu at 2022-05-06T19:22:22-04:00 Allow `let` just before pure/return in ApplicativeDo The following is currently rejected: ```haskell -- F is an Applicative but not a Monad x :: F (Int, Int) x = do a <- pure 0 let b = 1 pure (a, b) ``` This has bitten me multiple times. This MR contains a simple fix: only allow a "let only" segment to be merged with the next (and not the previous) segment. As a result, when the last one or more statements before pure/return are `LetStmt`s, there will be one more segment containing only those `LetStmt`s. Note that if the `let` statement mentions a name bound previously, then the program is still rejected, for example ```haskell x = do a <- pure 0 let b = a + 1 pure (a, b) ``` or the example in #18559. To support this would require a more complex approach, but this is IME much less common than the previous case. - - - - - 0415449a by Matthew Pickering at 2022-05-06T19:22:58-04:00 template-haskell: Fix representation of OPAQUE pragmas There is a mis-match between the TH representation of OPAQUE pragmas and GHC's internal representation due to how OPAQUE pragmas disallow phase annotations. It seemed most in keeping to just fix the wired in name issue by adding a special case to the desugaring of INLINE pragmas rather than making TH/GHC agree with how the representation should look. Fixes #21463 - - - - - 4de887e2 by Simon Peyton Jones at 2022-05-06T19:23:34-04:00 Comments only: Note [AppCtxt] - - - - - 6e69964d by Matthew Pickering at 2022-05-06T19:24:10-04:00 Fix name of windows release bindist in doc-tarball job - - - - - ced4689e by Matthew Pickering at 2022-05-06T19:24:46-04:00 ci: Generate source-tarball in release jobs We need to distribute the source tarball so we should generate it in the CI pipeline. - - - - - 3c91de21 by Rob at 2022-05-08T13:40:53+02:00 Change Specialise to use OrdList. Fixes #21362 Metric Decrease: T16875 - - - - - 67072c31 by Simon Jakobi at 2022-05-08T12:23:43-04:00 Tweak GHC.CmmToAsm.CFG.delEdge mapAdjust is more efficient than mapAlter. - - - - - 374554bb by Teo Camarasu at 2022-05-09T16:24:37-04:00 Respect -po when heap profiling (#21446) - - - - - 1ea414b6 by Teo Camarasu at 2022-05-09T16:24:37-04:00 add test case for #21446 - - - - - c7902078 by Jens Petersen at 2022-05-09T16:25:17-04:00 avoid hadrian/bindist/Makefile install_docs error when --docs=none When docs are disabled the bindist does not have docs/ and hence docs-utils/ is not generated. Here we just test that docs-utils exists before attempting to install prologue.txt and gen_contents_index to avoid the error: /usr/bin/install: cannot stat 'docs-utils/prologue.txt': No such file or directory make: *** [Makefile:195: install_docs] Error 1 - - - - - 158bd659 by Hécate Moonlight at 2022-05-09T16:25:56-04:00 Correct base's changelog for 4.16.1.0 This commit reaffects the new Ix instances of the foreign integral types from base 4.17 to 4.16.1.0 closes #21529 - - - - - a4fbb589 by Sylvain Henry at 2022-05-09T16:26:36-04:00 STG: only print cost-center if asked to - - - - - 50347ded by Gergo ERDI at 2022-05-10T11:43:33+00:00 Improve "Glomming" note Add a paragraph that clarifies that `occurAnalysePgm` finding out-of-order references, and thus needing to glom, is not a cause for concern when its root cause is rewrite rules. - - - - - df2e3373 by Eric Lindblad at 2022-05-10T20:45:41-04:00 update INSTALL - - - - - dcac3833 by Matthew Pickering at 2022-05-10T20:46:16-04:00 driver: Make -no-keep-o-files -no-keep-hi-files work in --make mode It seems like it was just an oversight to use the incorrect DynFlags (global rather than local) when implementing these two options. Using the local flags allows users to request these intermediate files get cleaned up, which works fine in --make mode because 1. Interface files are stored in memory 2. Object files are only cleaned at the end of session (after link) Fixes #21349 - - - - - 35da81f8 by Ben Gamari at 2022-05-10T20:46:52-04:00 configure: Check for ffi.h As noted in #21485, we checked for ffi.h yet then failed to throw an error if it is missing. Fixes #21485. - - - - - bdc99cc2 by Simon Peyton Jones at 2022-05-10T20:47:28-04:00 Check for uninferrable variables in tcInferPatSynDecl This fixes #21479 See Note [Unquantified tyvars in a pattern synonym] While doing this, I found that some error messages pointed at the pattern synonym /name/, rather than the /declaration/ so I widened the SrcSpan to encompass the declaration. - - - - - 142a73d9 by Matthew Pickering at 2022-05-10T20:48:04-04:00 hadrian: Fix split-sections transformer The splitSections transformer has been broken since -dynamic-too support was implemented in hadrian. This is because we actually build the dynamic way when building the dynamic way, so the predicate would always fail. The fix is to just always pass `split-sections` even if it doesn't do anything for a particular way. Fixes #21138 - - - - - 699f5935 by Matthew Pickering at 2022-05-10T20:48:04-04:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. Closes #21135 - - - - - 21feece2 by Simon Peyton Jones at 2022-05-10T20:48:39-04:00 Use the wrapper for an unlifted binding We assumed the wrapper for an unlifted binding is the identity, but as #21516 showed, that is no always true. Solution is simple: use it. - - - - - 68d1ea5f by Matthew Pickering at 2022-05-10T20:49:15-04:00 docs: Fix path to GHC API docs in index.html In the make bindists we generate documentation in docs/ghc-<VER> but the hadrian bindists generate docs/ghc/ so the path to the GHC API docs was wrong in the index.html file. Rather than make the hadrian and make bindists the same it was easier to assume that if you're using the mkDocs script that you're using hadrian bindists. Fixes #21509 - - - - - 9d8f44a9 by Matthew Pickering at 2022-05-10T20:49:51-04:00 hadrian: Don't pass -j to haddock This has high potential for oversubcribing as many haddock jobs can be spawned in parralel which will each request the given number of capabilities. Once -jsem is implemented (#19416, !5176) we can expose that haddock via haddock and use that to pass a semaphore. Ticket #21136 - - - - - fec3e7aa by Matthew Pickering at 2022-05-10T20:50:27-04:00 hadrian: Only copy and install libffi headers when using in-tree libffi When passed `--use-system-libffi` then we shouldn't copy and install the headers from the system package. Instead the headers are expected to be available as a runtime dependency on the users system. Fixes #21485 #21487 - - - - - 5b791ed3 by mikael at 2022-05-11T08:22:13-04:00 FIND_LLVM_PROG: Recognize llvm suffix used by FreeBSD, ie llc10. - - - - - 8500206e by ARATA Mizuki at 2022-05-11T08:22:57-04:00 Make floating-point abs IEEE 754 compliant The old code used by via-C backend didn't handle the sign bit of NaN. See #21043. - - - - - 4a4c77ed by Alan Zimmerman at 2022-05-11T08:23:33-04:00 EPA: do statement with leading semicolon has wrong anchor The code do; a <- doAsync; b Generated an incorrect Anchor for the statement list that starts after the first semicolon. This commit fixes it. Closes #20256 - - - - - e3ca8dac by Simon Peyton Jones at 2022-05-11T08:24:08-04:00 Specialiser: saturate DFuns correctly Ticket #21489 showed that the saturation mechanism for DFuns (see Note Specialising DFuns) should use both UnspecType and UnspecArg. We weren't doing that; but this MR fixes that problem. No test case because it's hard to tickle, but it showed up in Gergo's work with GHC-as-a-library. - - - - - fcc7dc4c by Ben Gamari at 2022-05-11T20:05:41-04:00 gitlab-ci: Check for dynamic msys2 dependencies Both #20878 and #21196 were caused by unwanted dynamic dependencies being introduced by boot libraries. Ensure that we catch this in CI by attempting to run GHC in an environment with a minimal PATH. - - - - - 3c998f0d by Matthew Pickering at 2022-05-11T20:06:16-04:00 Add back Debian9 CI jobs We still build Deb9 bindists for now due to Ubuntu 18 and Linux Mint 19 not being at EOL until April 2023 and they still need tinfo5. Fixes #21469 - - - - - dea9a3d9 by Ben Gamari at 2022-05-11T20:06:51-04:00 rts: Drop setExecutable Since f6e366c058b136f0789a42222b8189510a3693d1 setExecutable has been dead code. Drop it. - - - - - 32cdf62d by Simon Peyton Jones at 2022-05-11T20:07:27-04:00 Add a missing guard in GHC.HsToCore.Utils.is_flat_prod_pat This missing guard gave rise to #21519. - - - - - 2c00a8d0 by Matthew Pickering at 2022-05-11T20:08:02-04:00 Add mention of -hi to RTS --help Fixes #21546 - - - - - a2dcad4e by Andre Marianiello at 2022-05-12T02:15:48+00:00 Decouple dynflags in Cmm parser (related to #17957) - - - - - 3a022baa by Andre Marianiello at 2022-05-12T02:15:48+00:00 Remove Module argument from initCmmParserConfig - - - - - 2fc8d76b by Andre Marianiello at 2022-05-12T02:15:48+00:00 Move CmmParserConfig and PDConfig into GHC.Cmm.Parser.Config - - - - - b8c5ffab by Andre Marianiello at 2022-05-12T18:13:55-04:00 Decouple dynflags in GHC.Core.Opt.Arity (related to #17957) Metric Decrease: T16875 - - - - - 3bf938b6 by sheaf at 2022-05-12T18:14:34-04:00 Update extending_ghc for TcPlugin changes The documentation still mentioned Derived constraints and an outdated datatype TcPluginResult. - - - - - 668a9ef4 by jackohughes at 2022-05-13T12:10:34-04:00 Fix printing of brackets in multiplicities (#20315) Change mulArrow to allow for printing of correct application precedence where necessary and update callers of mulArrow to reflect this. As part of this, move mulArrow from GHC/Utils/Outputtable to GHC/Iface/Type. Fixes #20315 - - - - - 30b8b7f1 by Ben Gamari at 2022-05-13T12:11:09-04:00 rts: Add debug output on ocResolve failure This makes it easier to see how resolution failures nest. - - - - - 53b3fa1c by Ben Gamari at 2022-05-13T12:11:09-04:00 rts/PEi386: Fix handling of weak symbols Previously we would flag the symbol as weak but failed to set its address, which must be computed from an "auxiliary" symbol entry the follows the weak symbol. Fixes #21556. - - - - - 5678f017 by Ben Gamari at 2022-05-13T12:11:09-04:00 testsuite: Add tests for #21556 - - - - - 49af0e52 by Ben Gamari at 2022-05-13T22:23:26-04:00 Re-export augment and build from GHC.List Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/19127 - - - - - aed356e1 by Simon Peyton Jones at 2022-05-13T22:24:02-04:00 Comments only around HsWrapper - - - - - 27b90409 by Ben Gamari at 2022-05-16T08:30:44-04:00 hadrian: Introduce linting flavour transformer (+lint) The linting flavour enables -dlint uniformly across anything build by the stage1 compiler. -dcmm-lint is not currently enabled because it fails on i386 (see #21563) - - - - - 3f316776 by Matthew Pickering at 2022-05-16T08:30:44-04:00 hadrian: Uniformly enable -dlint with enableLinting transformer This fixes some bugs where * -dcore-lint was being passed when building stage1 libraries with the boot compiler * -dcore-lint was not being passed when building executables. Fixes #20135 - - - - - 3d74cfca by Andreas Klebinger at 2022-05-16T08:31:20-04:00 Make closure macros EXTERN_INLINE to make debugging easier Implements #21424. The RTS macros get_itbl and friends are extremely helpful during debugging. However only a select few of those were available in the compiled RTS as actual symbols as the rest were INLINE macros. This commit marks all of them as EXTERN_INLINE. This will still inline them at use sites but allow us to use their compiled counterparts during debugging. This allows us to use things like `p get_fun_itbl(ptr)` in the gdb shell since `get_fun_itbl` will now be available as symbol! - - - - - 93153aab by Matthew Pickering at 2022-05-16T08:31:55-04:00 packaging: Introduce CI job for generating hackage documentation This adds a CI job (hackage-doc-tarball) which generates the necessary tarballs for uploading libraries and documentation to hackage. The release script knows to download this folder and the upload script will also upload the release to hackage as part of the release. The `ghc_upload_libs` script is moved from ghc-utils into .gitlab/ghc_upload_libs There are two modes, preparation and upload. * The `prepare` mode takes a link to a bindist and creates a folder containing the source and doc tarballs ready to upload to hackage. * The `upload` mode takes the folder created by prepare and performs the upload to hackage. Fixes #21493 Related to #21512 - - - - - 65d31d05 by Simon Peyton Jones at 2022-05-16T15:32:50-04:00 Add arity to the INLINE pragmas for pattern synonyms The lack of INLNE arity was exposed by #21531. The fix is simple enough, if a bit clumsy. - - - - - 43c018aa by Krzysztof Gogolewski at 2022-05-16T15:33:25-04:00 Misc cleanup - Remove groupWithName (unused) - Use the RuntimeRepType synonym where possible - Replace getUniqueM + mkSysLocalOrCoVar with mkSysLocalOrCoVarM No functional changes. - - - - - 8dfea078 by Pavol Vargovcik at 2022-05-16T15:34:04-04:00 TcPlugin: access to irreducible givens + fix passed ev_binds_var - - - - - fb579e15 by Ben Gamari at 2022-05-17T00:25:02-04:00 driver: Introduce pgmcxx Here we introduce proper support for compilation of C++ objects. This includes: * logic in `configure` to detect the C++ toolchain and propagating this information into the `settings` file * logic in the driver to use the C++ toolchain when compiling C++ sources - - - - - 43628ed4 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Build T20918 with HC, not CXX - - - - - 0ef249aa by Ben Gamari at 2022-05-17T00:25:02-04:00 Introduce package to capture dependency on C++ stdlib Here we introduce a new "virtual" package into the initial package database, `system-cxx-std-lib`. This gives users a convenient, platform agnostic way to link against C++ libraries, addressing #20010. Fixes #20010. - - - - - 03efe283 by Ben Gamari at 2022-05-17T00:25:02-04:00 testsuite: Add tests for system-cxx-std-lib package Test that we can successfully link against C++ code both in GHCi and batch compilation. See #20010 - - - - - 5f6527e0 by nineonine at 2022-05-17T00:25:38-04:00 OverloadedRecordFields: mention parent name in 'ambiguous occurrence' error for better disambiguation (#17420) - - - - - eccdb208 by Simon Peyton Jones at 2022-05-17T07:16:39-04:00 Adjust flags for pprTrace We were using defaultSDocContext for pprTrace, which suppresses lots of useful infomation. This small MR adds GHC.Utils.Outputable.traceSDocContext and uses it for pprTrace and pprTraceUserWarning. traceSDocContext is a global, and hence not influenced by flags, but that seems unavoidable. But I made the sdocPprDebug bit controlled by unsafeHasPprDebug, since we have the latter for exactly this purpose. Fixes #21569 - - - - - d2284c4c by Simon Peyton Jones at 2022-05-17T07:17:15-04:00 Fix bad interaction between withDict and the Specialiser This MR fixes a bad bug, where the withDict was inlined too vigorously, which in turn made the type-class Specialiser generate a bogus specialisation, because it saw the same overloaded function applied to two /different/ dictionaries. Solution: inline `withDict` later. See (WD8) of Note [withDict] in GHC.HsToCore.Expr See #21575, which is fixed by this change. - - - - - 70f52443 by Matthew Pickering at 2022-05-17T07:17:50-04:00 Bump time submodule to 1.12.2 This bumps the time submodule to the 1.12.2 release. Fixes #21571 - - - - - 2343457d by Vladislav Zavialov at 2022-05-17T07:18:26-04:00 Remove unused test files (#21582) Those files were moved to the perf/ subtree in 11c9a469, and then accidentally reintroduced in 680ef2c8. - - - - - cb52b4ae by Ben Gamari at 2022-05-17T16:00:14-04:00 CafAnal: Improve code clarity Here we implement a few measures to improve the clarity of the CAF analysis implementation. Specifically: * Use CafInfo instead of Bool since the former is more descriptive * Rename CAFLabel to CAFfyLabel, since not all CAFfyLabels are in fact CAFs * Add numerous comments - - - - - b048a9f4 by Ben Gamari at 2022-05-17T16:00:14-04:00 codeGen: Ensure that static datacon apps are included in SRTs When generating an SRT for a recursive group, GHC.Cmm.Info.Build.oneSRT filters out recursive references, as described in Note [recursive SRTs]. However, doing so for static functions would be unsound, for the reason described in Note [Invalid optimisation: shortcutting]. However, the same argument applies to static data constructor applications, as we discovered in #20959. Fix this by ensuring that static data constructor applications are included in recursive SRTs. The approach here is not entirely satisfactory, but it is a starting point. Fixes #20959. - - - - - 0e2d16eb by Matthew Pickering at 2022-05-17T16:00:50-04:00 Add test for #21558 This is now fixed on master and 9.2 branch. Closes #21558 - - - - - ef3c8d9e by Sylvain Henry at 2022-05-17T20:22:02-04:00 Don't store LlvmConfig into DynFlags LlvmConfig contains information read from llvm-passes and llvm-targets files in GHC's top directory. Reading these files is done only when needed (i.e. when the LLVM backend is used) and cached for the whole compiler session. This patch changes the way this is done: - Split LlvmConfig into LlvmConfig and LlvmConfigCache - Store LlvmConfigCache in HscEnv instead of DynFlags: there is no good reason to store it in DynFlags. As it is fixed per session, we store it in the session state instead (HscEnv). - Initializing LlvmConfigCache required some changes to driver functions such as newHscEnv. I've used the opportunity to untangle initHscEnv from initGhcMonad (in top-level GHC module) and to move it to GHC.Driver.Main, close to newHscEnv. - I've also made `cmmPipeline` independent of HscEnv in order to remove the call to newHscEnv in regalloc_unit_tests. - - - - - 828fbd8a by Andreas Klebinger at 2022-05-17T20:22:38-04:00 Give all EXTERN_INLINE closure macros prototypes - - - - - cfc8e2e2 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Introduce [sg]etFinalizerExceptionHandler This introduces a global hook which is called when an exception is thrown during finalization. - - - - - 372cf730 by Ben Gamari at 2022-05-19T04:57:51-04:00 base: Throw exceptions raised while closing finalized Handles Fixes #21336. - - - - - 3dd2f944 by Ben Gamari at 2022-05-19T04:57:51-04:00 testsuite: Add tests for #21336 - - - - - 297156e0 by Matthew Pickering at 2022-05-19T04:58:27-04:00 Add release flavour and use it for the release jobs The release flavour is essentially the same as the perf flavour currently but also enables `-haddock`. I have hopefully updated all the relevant places where the `-perf` flavour was hardcoded. Fixes #21486 - - - - - a05b6293 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Don't build sphinx documentation on centos The centos docker image lacks the sphinx builder so we disable building sphinx docs for these jobs. Fixes #21580 - - - - - 209d7c69 by Matthew Pickering at 2022-05-19T04:58:27-04:00 ci: Use correct syntax when args list is empty This seems to fail on the ancient version of bash present on CentOS - - - - - 02d16334 by Matthew Pickering at 2022-05-19T04:59:03-04:00 hadrian: Don't attempt to build dynamic profiling libraries We only support building static profiling libraries, the transformer was requesting things like a dynamic, threaded, debug, profiling RTS, which we have never produced nor distributed. Fixes #21567 - - - - - 35bdab1c by Ben Gamari at 2022-05-19T04:59:39-04:00 configure: Check CC_STAGE0 for --target support We previously only checked the stage 1/2 compiler for --target support. We got away with this for quite a while but it eventually caught up with us in #21579, where `bytestring`'s new NEON implementation was unbuildable on Darwin due to Rosetta's seemingly random logic for determining which executable image to execute. This lead to a confusing failure to build `bytestring`'s cbits, when `clang` tried to compile NEON builtins while targetting x86-64. Fix this by checking CC_STAGE0 for --target support. Fixes #21579. - - - - - 0ccca94b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator analysis of `CmmGraph` This commit adds module `GHC.Cmm.Dominators`, which provides a wrapper around two existing algorithms in GHC: the Lengauer-Tarjan dominator analysis from the X86 back end and the reverse postorder ordering from the Cmm Dataflow framework. Issue #20726 proposes that we evaluate some alternatives for dominator analysis, but for the time being, the best path forward is simply to use the existing analysis on `CmmGraph`s. This commit addresses a bullet in #21200. - - - - - 54f0b578 by Norman Ramsey at 2022-05-20T05:32:32-04:00 add dominator-tree function - - - - - 05ed917b by Norman Ramsey at 2022-05-20T05:32:32-04:00 add HasDebugCallStack; remove unneeded extensions - - - - - 0b848136 by Andreas Klebinger at 2022-05-20T05:32:32-04:00 document fields of `DominatorSet` - - - - - 8a26e8d6 by Ben Gamari at 2022-05-20T05:33:08-04:00 nonmoving: Fix documentation of GC statistics fields These were previously incorrect. Fixes #21553. - - - - - c1e24e61 by Matthew Pickering at 2022-05-20T05:33:44-04:00 Remove pprTrace from pushCoercionIntoLambda (#21555) This firstly caused spurious output to be emitted (as evidenced by #21555) but even worse caused a massive coercion to be attempted to be printed (> 200k terms) which would invariably eats up all the memory of your computer. The good news is that removing this trace allows the program to compile to completion, the bad news is that the program exhibits a core lint error (on 9.0.2) but not any other releases it seems. Fixes #21577 and #21555 - - - - - a36d12ee by Zubin Duggal at 2022-05-20T10:44:35-04:00 docs: Fix LlvmVersion in manpage (#21280) - - - - - 36b8a57c by Matthew Pickering at 2022-05-20T10:45:10-04:00 validate: Use $make rather than make In the validate script we are careful to use the $make variable as this stores whether we are using gmake, make, quiet mode etc. There was just this one place where we failed to use it. Fixes #21598 - - - - - 4aa3c5bd by Norman Ramsey at 2022-05-21T03:11:04+00:00 Change `Backend` type and remove direct dependencies With this change, `Backend` becomes an abstract type (there are no more exposed value constructors). Decisions that were formerly made by asking "is the current back end equal to (or different from) this named value constructor?" are now made by interrogating the back end about its properties, which are functions exported by `GHC.Driver.Backend`. There is a description of how to migrate code using `Backend` in the user guide. Clients using the GHC API can find a backdoor to access the Backend datatype in GHC.Driver.Backend.Internal. Bumps haddock submodule. Fixes #20927 - - - - - ecf5f363 by Julian Ospald at 2022-05-21T12:51:16-04:00 Respect DESTDIR in hadrian bindist Makefile, fixes #19646 - - - - - 7edd991e by Julian Ospald at 2022-05-21T12:51:16-04:00 Test DESTDIR in test_hadrian() - - - - - ea895b94 by Matthew Pickering at 2022-05-22T21:57:47-04:00 Consider the stage of typeable evidence when checking stage restriction We were considering all Typeable evidence to be "BuiltinInstance"s which meant the stage restriction was going unchecked. In-fact, typeable has evidence and so we need to apply the stage restriction. This is complicated by the fact we don't generate typeable evidence and the corresponding DFunIds until after typechecking is concluded so we introcue a new `InstanceWhat` constructor, BuiltinTypeableInstance which records whether the evidence is going to be local or not. Fixes #21547 - - - - - ffbe28e5 by Dominik Peteler at 2022-05-22T21:58:23-04:00 Modularize GHC.Core.Opt.LiberateCase Progress towards #17957 - - - - - bc723ac2 by Simon Peyton Jones at 2022-05-23T17:09:34+01:00 Improve FloatOut and SpecConstr This patch addresses a relatively obscure situation that arose when chasing perf regressions in !7847, which itself is fixing It does two things: * SpecConstr can specialise on ($df d1 d2) dictionary arguments * FloatOut no longer checks argument strictness See Note [Specialising on dictionaries] in GHC.Core.Opt.SpecConstr. A test case is difficult to construct, but it makes a big difference in nofib/real/eff/VSM, at least when we have the patch for #21286 installed. (The latter stops worker/wrapper for dictionary arguments). There is a spectacular, but slightly illusory, improvement in runtime perf on T15426. I have documented the specifics in T15426 itself. Metric Decrease: T15426 - - - - - 1a4195b0 by John Ericson at 2022-05-23T17:33:59-04:00 Make debug a `Bool` not an `Int` in `StgToCmmConfig` We don't need any more resolution than this. Rename the field to `stgToCmmEmitDebugInfo` to indicate it is no longer conveying any "level" information. - - - - - e9fff12b by Alan Zimmerman at 2022-05-23T21:04:49-04:00 EPA : Remove duplicate comments in DataFamInstD The code data instance Method PGMigration = MigrationQuery Query -- ^ Run a query against the database | MigrationCode (Connection -> IO (Either String ())) -- ^ Run any arbitrary IO code Resulted in two instances of the "-- ^ Run a query against the database" comment appearing in the Exact Print Annotations when it was parsed. Ensure only one is kept. Closes #20239 - - - - - e2520df3 by Alan Zimmerman at 2022-05-23T21:05:27-04:00 EPA: Comment Order Reversed Make sure comments captured in the exact print annotations are in order of increasing location Closes #20718 - - - - - 4b45fd72 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Add test for T21455 - - - - - e2cd1d43 by Teo Camarasu at 2022-05-24T10:49:13-04:00 Allow passing -po outside profiling way Resolves #21455 - - - - - 3b8c413a by Greg Steuck at 2022-05-24T10:49:52-04:00 Fix haddock_*_perf tests on non-GNU-grep systems Using regexp pattern requires `egrep` and straight up `+`. The haddock_parser_perf and haddock_renamer_perf tests now pass on OpenBSD. They previously incorrectly parsed the files and awk complained about invalid syntax. - - - - - 1db877a3 by Ben Gamari at 2022-05-24T10:50:28-04:00 hadrian/bindist: Drop redundant include of install.mk `install.mk` is already included by `config.mk`. Moreover, `install.mk` depends upon `config.mk` to set `RelocatableBuild`, making this first include incorrect. - - - - - f485d267 by Greg Steuck at 2022-05-24T10:51:08-04:00 Remove -z wxneeded for OpenBSD With all the recent W^X fixes in the loader this workaround is not necessary any longer. I verified that the only tests failing for me on OpenBSD 7.1-current are the same (libc++ related) before and after this commit (with --fast). - - - - - 7c51177d by Andreas Klebinger at 2022-05-24T22:13:19-04:00 Use UnionListsOrd instead of UnionLists in most places. This should get rid of most, if not all "Overlong lists" errors and fix #20016 - - - - - 81b3741f by Andreas Klebinger at 2022-05-24T22:13:55-04:00 Fix #21563 by using Word64 for 64bit shift code. We use the 64bit shifts only on 64bit platforms. But we compile the code always so compiling it on 32bit caused a lint error. So use Word64 instead. - - - - - 2c25fff6 by Zubin Duggal at 2022-05-24T22:14:30-04:00 Fix compilation with -haddock on GHC <= 8.10 -haddock on GHC < 9.0 is quite fragile and can result in obtuse parse errors when it encounters invalid haddock syntax. This has started to affect users since 297156e0b8053a28a860e7a18e1816207a59547b enabled -haddock by default on many flavours. Furthermore, since we don't test bootstrapping with 8.10 on CI, this problem managed to slip throught the cracks. - - - - - cfb9faff by sheaf at 2022-05-24T22:15:12-04:00 Hadrian: don't add "lib" for relocatable builds The conditional in hadrian/bindist/Makefile depended on the target OS, but it makes more sense to use whether we are using a relocatable build. (Currently this only gets set to true on Windows, but this ensures that the logic stays correctly coupled.) - - - - - 9973c016 by Andre Marianiello at 2022-05-25T01:36:09-04:00 Remove HscEnv from GHC.HsToCore.Usage (related to #17957) Metric Decrease: T16875 - - - - - 2ff18e39 by sheaf at 2022-05-25T01:36:48-04:00 SimpleOpt: beta-reduce through casts The simple optimiser would sometimes fail to beta-reduce a lambda when there were casts in between the lambda and its arguments. This can cause problems because we rely on representation-polymorphic lambdas getting beta-reduced away (for example, those that arise from newtype constructors with representation-polymorphic arguments, with UnliftedNewtypes). - - - - - e74fc066 by CarrieMY at 2022-05-25T16:43:03+02:00 Desugar RecordUpd in `tcExpr` This patch typechecks record updates by desugaring them inside the typechecker using the HsExpansion mechanism, and then typechecking this desugared result. Example: data T p q = T1 { x :: Int, y :: Bool, z :: Char } | T2 { v :: Char } | T3 { x :: Int } | T4 { p :: Float, y :: Bool, x :: Int } | T5 The record update `e { x=e1, y=e2 }` desugars as follows e { x=e1, y=e2 } ===> let { x' = e1; y' = e2 } in case e of T1 _ _ z -> T1 x' y' z T4 p _ _ -> T4 p y' x' The desugared expression is put into an HsExpansion, and we typecheck that. The full details are given in Note [Record Updates] in GHC.Tc.Gen.Expr. Fixes #2595 #3632 #10808 #10856 #16501 #18311 #18802 #21158 #21289 Updates haddock submodule - - - - - 2b8bdab8 by Eric Lindblad at 2022-05-26T03:21:58-04:00 update README - - - - - 3d7e7e84 by BinderDavid at 2022-05-26T03:22:38-04:00 Replace dead link in Haddock documentation of Control.Monad.Fail (fixes #21602) - - - - - ee61c7f9 by John Ericson at 2022-05-26T03:23:13-04:00 Add Haddocks for `WwOpts` - - - - - da5ccf0e by Dominik Peteler at 2022-05-26T03:23:13-04:00 Avoid global compiler state for `GHC.Core.Opt.WorkWrap` Progress towards #17957 - - - - - 3bd975b4 by sheaf at 2022-05-26T03:23:52-04:00 Optimiser: avoid introducing bad rep-poly The functions `pushCoValArg` and `pushCoercionIntoLambda` could introduce bad representation-polymorphism. Example: type RR :: RuntimeRep type family RR where { RR = IntRep } type F :: TYPE RR type family F where { F = Int# } co = GRefl F (TYPE RR[0]) :: (F :: TYPE RR) ~# (F |> TYPE RR[0] :: TYPE IntRep) f :: F -> () `pushCoValArg` would transform the unproblematic application (f |> (co -> <()>)) (arg :: F |> TYPE RR[0]) into an application in which the argument does not have a fixed `RuntimeRep`: f ((arg |> sym co) :: (F :: TYPE RR)) - - - - - b22979fb by Fraser Tweedale at 2022-05-26T06:14:51-04:00 executablePath test: fix file extension treatment The executablePath test strips the file extension (if any) when comparing the query result with the expected value. This is to handle platforms where GHC adds a file extension to the output program file (e.g. .exe on Windows). After the initial check, the file gets deleted (if supported). However, it tries to delete the *stripped* filename, which is incorrect. The test currently passes only because Windows does not allow deleting the program while any process created from it is alive. Make the test program correct in general by deleting the *non-stripped* executable filename. - - - - - afde4276 by Fraser Tweedale at 2022-05-26T06:14:51-04:00 fix executablePath test for NetBSD executablePath support for NetBSD was added in a172be07e3dce758a2325104a3a37fc8b1d20c9c, but the test was not updated. Update the test so that it works for NetBSD. This requires handling some quirks: - The result of getExecutablePath could include "./" segments. Therefore use System.FilePath.equalFilePath to compare paths. - The sysctl(2) call returns the original executable name even after it was deleted. Add `canQueryAfterDelete :: [FilePath]` and adjust expectations for the post-delete query accordingly. Also add a note to the `executablePath` haddock to advise that NetBSD behaves differently from other OSes when the file has been deleted. Also accept a decrease in memory usage for T16875. On Windows, the metric is -2.2% of baseline, just outside the allowed ±2%. I don't see how this commit could have influenced this metric, so I suppose it's something in the CI environment. Metric Decrease: T16875 - - - - - d0e4355a by John Ericson at 2022-05-26T06:15:30-04:00 Factor out `initArityOps` to `GHC.Driver.Config.*` module We want `DynFlags` only mentioned in `GHC.Driver`. - - - - - 44bb7111 by romes at 2022-05-26T16:27:57+00:00 TTG: Move MatchGroup Origin field and MatchGroupTc to GHC.Hs - - - - - 88e58600 by sheaf at 2022-05-26T17:38:43-04:00 Add tests for eta-expansion of data constructors This patch adds several tests relating to the eta-expansion of data constructors, including UnliftedNewtypes and DataTypeContexts. - - - - - d87530bb by Richard Eisenberg at 2022-05-26T23:20:14-04:00 Generalize breakTyVarCycle to work with TyFamLHS The function breakTyVarCycle_maybe has been installed in a dark corner of GHC to catch some gremlins (a.k.a. occurs-check failures) who lurk there. But it previously only caught gremlins of the form (a ~ ... F a ...), where some of our intrepid users have spawned gremlins of the form (G a ~ ... F (G a) ...). This commit improves breakTyVarCycle_maybe (and renames it to breakTyEqCycle_maybe) to catch the new gremlins. Happily, the change is remarkably small. The gory details are in Note [Type equality cycles]. Test cases: typecheck/should_compile/{T21515,T21473}. - - - - - ed37027f by Hécate Moonlight at 2022-05-26T23:20:52-04:00 [base] Fix the links in the Data.Data module fix #21658 fix #21657 fix #21657 - - - - - 3bd7d5d6 by Krzysztof Gogolewski at 2022-05-27T16:44:48+02:00 Use a class to check validity of withDict This moves handling of the magic 'withDict' function from the desugarer to the typechecker. Details in Note [withDict]. I've extracted a part of T16646Fail to a separate file T16646Fail2, because the new error in 'reify' hides the errors from 'f' and 'g'. WithDict now works with casts, this fixes #21328. Part of #19915 - - - - - b54f6c4f by sheaf at 2022-05-28T21:00:09-04:00 Fix FreeVars computation for mdo Commit acb188e0 introduced a regression in the computation of free variables in mdo statements, as the logic in GHC.Rename.Expr.segmentRecStmts was slightly different depending on whether the recursive do block corresponded to an mdo statement or a rec statment. This patch restores the previous computation for mdo blocks. Fixes #21654 - - - - - 0704295c by Matthew Pickering at 2022-05-28T21:00:45-04:00 T16875: Stabilise (temporarily) by increasing acceptance threshold The theory is that on windows there is some difference in the environment between pipelines on master and merge requests which affects all tests equally but because T16875 barely allocates anything it is the test which is affected the most. See #21557 - - - - - 6341c8ed by Matthew Pickering at 2022-05-28T21:01:20-04:00 make: Fix make maintainer-clean deleting a file tracked by source control Fixes #21659 - - - - - fbf2f254 by Bodigrim at 2022-05-28T21:01:58-04:00 Expand documentation of hIsTerminalDevice - - - - - 0092c67c by Teo Camarasu at 2022-05-29T12:25:39+00:00 export IsList from GHC.IsList it is still re-exported from GHC.Exts - - - - - 91396327 by Sylvain Henry at 2022-05-30T09:40:55-04:00 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR ARM64_RELOC_SUBTRACTOR relocations are paired with an AMR64_RELOC_UNSIGNED relocation to implement: addend + sym1 - sym2 The linker was doing it in two steps, basically: *addend <- *addend - sym2 *addend <- *addend + sym1 The first operation was likely to overflow. For example when the relocation target was 32-bit and both sym1/sym2 were 64-bit addresses. With the small memory model, (sym1-sym2) would fit in 32 bits but (*addend-sym2) may not. Now the linker does it in one step: *addend <- *addend + sym1 - sym2 - - - - - acc26806 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Some fixes to SRT documentation - reordered the 3 SRT implementation cases from the most general to the most specific one: USE_SRT_POINTER -> USE_SRT_OFFSET -> USE_INLINE_SRT_FIELD - added requirements for each - found and documented a confusion about "SRT inlining" not supported with MachO. (It is fixed in the following commit) - - - - - 5878f439 by Sylvain Henry at 2022-05-30T09:40:55-04:00 Enable USE_INLINE_SRT_FIELD on ARM64 It was previously disabled because of: - a confusion about "SRT inlining" (see removed comment in this commit) - a linker bug (overflow) in the handling of ARM64_RELOC_SUBTRACTOR relocation: fixed by a previous commit. - - - - - 59bd6159 by Matthew Pickering at 2022-05-30T09:41:39-04:00 ci: Make sure to exit promptly if `make install` fails. Due to the vageries of bash, you have to explicitly handle the failure and exit when in a function. This failed to exit promptly when !8247 was failing. See #21358 for the general issue - - - - - 5a5a28da by Sylvain Henry at 2022-05-30T09:42:23-04:00 Split GHC.HsToCore.Foreign.Decl This is preliminary work for JavaScript support. It's better to put the code handling the desugaring of Prim, C and JavaScript declarations into separate modules. - - - - - 6f5ff4fa by Sylvain Henry at 2022-05-30T09:43:05-04:00 Bump hadrian to LTS-19.8 (GHC 9.0.2) - - - - - f2e70707 by Sylvain Henry at 2022-05-30T09:43:05-04:00 Hadrian: remove unused code - - - - - 2f215b9f by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Eta reduction with casted function We want to be able to eta-reduce \x y. ((f x) |> co) y by pushing 'co' inwards. A very small change accommodates this See Note [Eta reduction with casted function] - - - - - f4f6a87a by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Do arity trimming at bindings, rather than in exprArity Sometimes there are very large casts, and coercionRKind can be slow. - - - - - 610a2b83 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make findRhsArity take RecFlag This avoids a fixpoint iteration for the common case of non-recursive bindings. - - - - - 80ba50c7 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Comments and white space - - - - - 0079171b by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 Make PrimOpId record levity This patch concerns #20155, part (1) The general idea is that since primops have curried bindings (currently in PrimOpWrappers.hs) we don't need to eta-expand them. But we /do/ need to eta-expand the levity-polymorphic ones, because they /don't/ have bindings. This patch makes a start in that direction, by identifying the levity-polymophic primops in the PrimOpId IdDetails constructor. For the moment, I'm still eta-expanding all primops (by saying that hasNoBinding returns True for all primops), because of the bug reported in #20155. But I hope that before long we can tidy that up too, and remove the TEMPORARILY stuff in hasNoBinding. - - - - - 6656f016 by Simon Peyton Jones at 2022-05-30T13:44:14-04:00 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: * Move state-hack stuff from GHC.Types.Id (where it never belonged) to GHC.Core.Opt.Arity (which seems much more appropriate). * Add a crucial mkCast in the Cast case of GHC.Core.Opt.Arity.eta_expand; helps with T18223 * Add clarifying notes about eta-reducing to PAPs. See Note [Do not eta reduce PAPs] * I moved tryEtaReduce from GHC.Core.Utils to GHC.Core.Opt.Arity, where it properly belongs. See Note [Eta reduce PAPs] * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, pull out the code for when eta-expansion is wanted, to make wantEtaExpansion, and all that same function in GHC.Core.Opt.Simplify.simplStableUnfolding. It was previously inconsistent, but it's doing the same thing. * I did a substantial refactor of ArityType; see Note [ArityType]. This allowed me to do away with the somewhat mysterious takeOneShots; more generally it allows arityType to describe the function, leaving its clients to decide how to use that information. I made ArityType abstract, so that clients have to use functions to access it. * Make GHC.Core.Opt.Simplify.Utils.rebuildLam (was stupidly called mkLam before) aware of the floats that the simplifier builds up, so that it can still do eta-reduction even if there are some floats. (Previously that would not happen.) That means passing the floats to rebuildLam, and an extra check when eta-reducting (etaFloatOk). * In GHC.Core.Opt.Simplify.Utils.tryEtaExpandRhs, make use of call-info in the idDemandInfo of the binder, as well as the CallArity info. The occurrence analyser did this but we were failing to take advantage here. In the end I moved the heavy lifting to GHC.Core.Opt.Arity.findRhsArity; see Note [Combining arityType with demand info], and functions idDemandOneShots and combineWithDemandOneShots. (These changes partly drove my refactoring of ArityType.) * In GHC.Core.Opt.Arity.findRhsArity * I'm now taking account of the demand on the binder to give extra one-shot info. E.g. if the fn is always called with two args, we can give better one-shot info on the binders than if we just look at the RHS. * Don't do any fixpointing in the non-recursive case -- simple short cut. * Trim arity inside the loop. See Note [Trim arity inside the loop] * Make SimpleOpt respect the eta-reduction flag (Some associated refactoring here.) * I made the CallCtxt which the Simplifier uses distinguish between recursive and non-recursive right-hand sides. data CallCtxt = ... | RhsCtxt RecFlag | ... It affects only one thing: - We call an RHS context interesting only if it is non-recursive see Note [RHS of lets] in GHC.Core.Unfold * Remove eta-reduction in GHC.CoreToStg.Prep, a welcome simplification. See Note [No eta reduction needed in rhsToBody] in GHC.CoreToStg.Prep. Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. * Delete dead function GHC.Core.Opt.Simplify.Utils.contIsRhsOrArg Metrics: compile_time/bytes allocated Test Metric Baseline New value Change --------------------------------------------------------------------------------------- MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,743,297,692 2,619,762,992 -4.5% GOOD T18223(normal) ghc/alloc 1,103,161,360 972,415,992 -11.9% GOOD T3064(normal) ghc/alloc 201,222,500 184,085,360 -8.5% GOOD T8095(normal) ghc/alloc 3,216,292,528 3,254,416,960 +1.2% T9630(normal) ghc/alloc 1,514,131,032 1,557,719,312 +2.9% BAD parsing001(normal) ghc/alloc 530,409,812 525,077,696 -1.0% geo. mean -0.1% Nofib: Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- banner +0.0% +0.4% -8.9% -8.7% 0.0% exact-reals +0.0% -7.4% -36.3% -37.4% 0.0% fannkuch-redux +0.0% -0.1% -1.0% -1.0% 0.0% fft2 -0.1% -0.2% -17.8% -19.2% 0.0% fluid +0.0% -1.3% -2.1% -2.1% 0.0% gg -0.0% +2.2% -0.2% -0.1% 0.0% spectral-norm +0.1% -0.2% 0.0% 0.0% 0.0% tak +0.0% -0.3% -9.8% -9.8% 0.0% x2n1 +0.0% -0.2% -3.2% -3.2% 0.0% -------------------------------------------------------------------------------- Min -3.5% -7.4% -58.7% -59.9% 0.0% Max +0.1% +2.2% +32.9% +32.9% 0.0% Geometric Mean -0.0% -0.1% -14.2% -14.8% -0.0% Metric Decrease: MultiLayerModulesTH_OneShot T18223 T3064 T15185 T14766 Metric Increase: T9630 - - - - - cac8c7bb by Matthew Pickering at 2022-05-30T13:44:50-04:00 hadrian: Fix building from source-dist without alex/happy This fixes two bugs which were adding dependencies on alex/happy when building from a source dist. * When we try to pass `--with-alex` and `--with-happy` to cabal when configuring but the builders are not set. This is fixed by making them optional. * When we configure, cabal requires alex/happy because of the build-tool-depends fields. These are now made optional with a cabal flag (build-tool-depends) for compiler/hpc-bin/genprimopcode. Fixes #21627 - - - - - a96dccfe by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test the bootstrap without ALEX/HAPPY on path - - - - - 0e5bb3a8 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Test bootstrapping in release jobs - - - - - d8901469 by Matthew Pickering at 2022-05-30T13:44:50-04:00 ci: Allow testing bootstrapping on MRs using the "test-bootstrap" label - - - - - 18326ad2 by Matthew Pickering at 2022-05-30T13:45:25-04:00 rts: Remove explicit timescale for deprecating -h flag We originally planned to remove the flag in 9.4 but there's actually no great rush to do so and it's probably less confusing (forever) to keep the message around suggesting an explicit profiling option. Fixes #21545 - - - - - eaaa1389 by Matthew Pickering at 2022-05-30T13:46:01-04:00 Enable -dlint in hadrian lint transformer Now #21563 is fixed we can properly enable `-dlint` in CI rather than a subset of the flags. - - - - - 0544f114 by Ben Gamari at 2022-05-30T19:16:55-04:00 upload-ghc-libs: Allow candidate-only upload - - - - - 83467435 by Sylvain Henry at 2022-05-30T19:17:35-04:00 Avoid using DynFlags in GHC.Linker.Unit (#17957) - - - - - 5c4421b1 by Matthew Pickering at 2022-05-31T08:35:17-04:00 hadrian: Introduce new package database for executables needed to build stage0 These executables (such as hsc2hs) are built using the boot compiler and crucially, most libraries from the global package database. We also move other build-time executables to be built in this stage such as linters which also cleans up which libraries end up in the global package database. This allows us to remove hacks where linters-common is removed from the package database when a bindist is created. This fixes issues caused by infinite recursion due to bytestring adding a dependency on template-haskell. Fixes #21634 - - - - - 0dafd3e7 by Matthew Pickering at 2022-05-31T08:35:17-04:00 Build stage1 with -V as well This helps tracing errors which happen when building stage1 - - - - - 15d42a7a by Matthew Pickering at 2022-05-31T08:35:52-04:00 Revert "packaging: Build perf builds with -split-sections" This reverts commit 699f593532a3cd5ca1c2fab6e6e4ce9d53be2c1f. Split sections causes segfaults in profiling way with old toolchains (deb9) and on windows (#21670) Fixes #21670 - - - - - d4c71f09 by John Ericson at 2022-05-31T16:26:28+00:00 Purge `DynFlags` and `HscEnv` from some `GHC.Core` modules where it's not too hard Progress towards #17957 Because of `CoreM`, I did not move the `DynFlags` and `HscEnv` to other modules as thoroughly as I usually do. This does mean that risk of `DynFlags` "creeping back in" is higher than it usually is. After we do the same process to the other Core passes, and then figure out what we want to do about `CoreM`, we can finish the job started here. That is a good deal more work, however, so it certainly makes sense to land this now. - - - - - a720322f by romes at 2022-06-01T07:44:44-04:00 Restore Note [Quasi-quote overview] - - - - - 392ce3fc by romes at 2022-06-01T07:44:44-04:00 Move UntypedSpliceFlavour from L.H.S to GHC.Hs UntypedSpliceFlavour was only used in the client-specific `GHC.Hs.Expr` but was defined in the client-independent L.H.S.Expr. - - - - - 7975202b by romes at 2022-06-01T07:44:44-04:00 TTG: Rework and improve splices This commit redefines the structure of Splices in the AST. We get rid of `HsSplice` which used to represent typed and untyped splices, quasi quotes, and the result of splicing either an expression, a type or a pattern. Instead we have `HsUntypedSplice` which models an untyped splice or a quasi quoter, which works in practice just like untyped splices. The `HsExpr` constructor `HsSpliceE` which used to be constructed with an `HsSplice` is split into `HsTypedSplice` and `HsUntypedSplice`. The former is directly constructed with an `HsExpr` and the latter now takes an `HsUntypedSplice`. Both `HsType` and `Pat` constructors `HsSpliceTy` and `SplicePat` now take an `HsUntypedSplice` instead of a `HsSplice` (remember only /untyped splices/ can be spliced as types or patterns). The result of splicing an expression, type, or pattern is now comfortably stored in the extension fields `XSpliceTy`, `XSplicePat`, `XUntypedSplice` as, respectively, `HsUntypedSpliceResult (HsType GhcRn)`, `HsUntypedSpliceResult (Pat GhcRn)`, and `HsUntypedSpliceResult (HsExpr GhcRn)` Overall the TTG extension points are now better used to make invalid states unrepresentable and model the progression between stages better. See Note [Lifecycle of an untyped splice, and PendingRnSplice] and Note [Lifecycle of an typed splice, and PendingTcSplice] for more details. Updates haddock submodule Fixes #21263 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - 320270c2 by Matthew Pickering at 2022-06-01T07:44:44-04:00 Add test for #21619 Fixes #21619 - - - - - ef7ddd73 by Pierre Le Marre at 2022-06-01T07:44:47-04:00 Pure Haskell implementation of GHC.Unicode Switch to a pure Haskell implementation of base:GHC.Unicode, based on the implementation of the package unicode-data (https://github.com/composewell/unicode-data/). Approved by CLC as per https://github.com/haskell/core-libraries-committee/issues/59#issuecomment-1132106691. - Remove current Unicode cbits. - Add generator for Unicode property files from Unicode Character Database. - Generate internal modules. - Update GHC.Unicode. - Add unicode003 test for general categories and case mappings. - Add Python scripts to check 'base' Unicode tests outputs and characters properties. Fixes #21375 ------------------------- Metric Decrease: T16875 Metric Increase: T4029 T18304 haddock.base ------------------------- - - - - - 514a6a28 by Eric Lindblad at 2022-06-01T07:44:51-04:00 typos - - - - - 9004be3c by Matthew Pickering at 2022-06-01T07:44:52-04:00 source-dist: Copy in files created by ./boot Since we started producing source dists with hadrian we stopped copying in the files created by ./boot which adds a dependency on python3 and autoreconf. This adds back in the files which were created by running configure. Fixes #21673 #21672 and #21626 - - - - - a12a3cab by Matthew Pickering at 2022-06-01T07:44:52-04:00 ci: Don't try to run ./boot when testing bootstrap of source dist - - - - - e07f9059 by Shlomo Shuck at 2022-06-01T07:44:55-04:00 Language.Haskell.Syntax: Fix docs for PromotedConsT etc. Fixes ghc/ghc#21675. - - - - - 87295e6d by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump bytestring, process, and text submodules Metric Decrease: T5631 Metric Increase: T18223 (cherry picked from commit 55fcee30cb3281a66f792e8673967d64619643af) - - - - - 24b5bb61 by Ben Gamari at 2022-06-01T07:44:56-04:00 Bump Cabal submodule To current `master`. (cherry picked from commit fbb59c212415188486aafd970eafef170516356a) - - - - - 5433a35e by Matthew Pickering at 2022-06-01T22:26:30-04:00 hadrian/tool-args: Write output to intermediate file rather than via stdout This allows us to see the output of hadrian while it is doing the setup. - - - - - 468f919b by Matthew Pickering at 2022-06-01T22:27:10-04:00 Make -fcompact-unwind the default This is a follow-up to !7247 (closed) making the inclusion of compact unwinding sections the default. Also a slight refactoring/simplification of the flag handling to add -fno-compact-unwind. - - - - - 819fdc61 by Zubin Duggal at 2022-06-01T22:27:47-04:00 hadrian bootstrap: add plans for 9.0.2 and 9.2.3 - - - - - 9fa790b4 by Zubin Duggal at 2022-06-01T22:27:47-04:00 ci: Add matrix for bootstrap sources - - - - - ce9f986b by John Ericson at 2022-06-02T15:42:59+00:00 HsToCore.Coverage: Improve haddocks - - - - - f065804e by John Ericson at 2022-06-02T15:42:59+00:00 Hoist auto `mkModBreaks` and `writeMixEntries` conditions to caller No need to inline traversing a maybe for `mkModBreaks`. And better to make each function do one thing and let the caller deside when than scatter the decision making and make the caller seem more imperative. - - - - - d550d907 by John Ericson at 2022-06-02T15:42:59+00:00 Rename `HsToCore.{Coverage -> Ticks}` The old name made it confusing why disabling HPC didn't disable the entire pass. The name makes it clear --- there are other reasons to add ticks in addition. - - - - - 6520da95 by John Ericson at 2022-06-02T15:42:59+00:00 Split out `GHC.HsToCore.{Breakpoints,Coverage}` and use `SizedSeq` As proposed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_432877 and https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7508#note_434676, `GHC.HsToCore.Ticks` is about ticks, breakpoints are separate and backend-specific (only for the bytecode interpreter), and mix entry writing is just for HPC. With this split we separate out those interpreter- and HPC-specific its, and keep the main `GHC.HsToCore.Ticks` agnostic. Also, instead of passing the reversed list and count around, we use `SizedSeq` which abstracts over the algorithm. This is much nicer to avoid noise and prevents bugs. (The bugs are not just hypothetical! I missed up the reverses on an earlier draft of this commit.) - - - - - 1838c3d8 by Sylvain Henry at 2022-06-02T15:43:14+00:00 GHC.HsToCore.Breakpoints: Slightly improve perf We have the length already, so we might as well use that rather than O(n) recomputing it. - - - - - 5a3fdcfd by John Ericson at 2022-06-02T15:43:59+00:00 HsToCore.Coverage: Purge DynFlags Finishes what !7467 (closed) started. Progress towards #17957 - - - - - 9ce9ea50 by HaskellMouse at 2022-06-06T09:50:00-04:00 Deprecate TypeInType extension This commit fixes #20312 It deprecates "TypeInType" extension according to the following proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0083-no-type-in-type.rst It has been already implemented. The migration strategy: 1. Disable TypeInType 2. Enable both DataKinds and PolyKinds extensions Metric Decrease: T16875 - - - - - f2e037fd by Aaron Allen at 2022-06-06T09:50:39-04:00 Diagnostics conversions, part 6 (#20116) Replaces uses of `TcRnUnknownMessage` with proper diagnostics constructors in `GHC.Tc.Gen.Match`, `GHC.Tc.Gen.Pat`, and `GHC.Tc.Gen.Sig`. - - - - - 04209f2a by Simon Peyton Jones at 2022-06-06T09:51:15-04:00 Ensure floated dictionaries are in scope (again) In the Specialiser, we missed one more call to bringFloatedDictsIntoScope (see #21391). This omission led to #21689. The problem is that the call to `rewriteClassOps` needs to have in scope any dictionaries floated out of the arguments we have just specialised. Easy fix. - - - - - a7fece19 by John Ericson at 2022-06-07T05:04:22+00:00 Don't print the number of deps in count-deps tests It is redundant information and a source of needless version control conflicts when multiple MRs are changing the deps list. Just printing the list and not also its length is fine. - - - - - a1651a3a by John Ericson at 2022-06-07T05:06:38+00:00 Core.Lint: Reduce `DynFlags` and `HscEnv` Co-Authored-By: Andre Marianiello <andremarianiello at users.noreply.github.com> - - - - - 56ebf9a5 by Andreas Klebinger at 2022-06-09T09:11:43-04:00 Fix a CSE shadowing bug. We used to process the rhs of non-recursive bindings and their body using the same env. If we had something like let x = ... x ... this caused trouble because the two xs refer to different binders but we would substitute both for a new binder x2 causing out of scope errors. We now simply use two different envs for the rhs and body in cse_bind. It's all explained in the Note [Separate envs for let rhs and body] Fixes #21685 - - - - - 28880828 by sheaf at 2022-06-09T09:12:19-04:00 Typecheck remaining ValArgs in rebuildHsApps This patch refactors hasFixedRuntimeRep_remainingValArgs, renaming it to tcRemainingValArgs. The logic is moved to rebuildHsApps, which ensures consistent behaviour across tcApp and quickLookArg1/tcEValArg. This patch also refactors the treatment of stupid theta for data constructors, changing the place we drop stupid theta arguments from dsConLike to mkDataConRep (now the datacon wrapper drops these arguments). We decided not to implement PHASE 2 of the FixedRuntimeRep plan for these remaining ValArgs. Future directions are outlined on the wiki: https://gitlab.haskell.org/ghc/ghc/-/wikis/Remaining-ValArgs Fixes #21544 and #21650 - - - - - 1fbba97b by Matthew Pickering at 2022-06-09T09:12:54-04:00 Add test for T21682 Fixes #21682 - - - - - 8727be73 by Andreas Klebinger at 2022-06-09T09:13:29-04:00 Document dataToTag# primop - - - - - 7eab75bb by uhbif19 at 2022-06-09T20:22:47+03:00 Remove TcRnUnknownMessage usage from GHC.Rename.Env #20115 - - - - - 46d2fc65 by uhbif19 at 2022-06-09T20:24:40+03:00 Fix TcRnPragmaWarning meaning - - - - - 69e72ecd by Matthew Pickering at 2022-06-09T19:07:01-04:00 getProcessCPUTime: Fix the getrusage fallback to account for system CPU time clock_gettime reports the combined total or user AND system time so in order to replicate it with getrusage we need to add both system and user time together. See https://stackoverflow.com/questions/7622371/getrusage-vs-clock-gettime Some sample measurements when building Cabal with this patch t1: rusage t2: clock_gettime t1: 62347518000; t2: 62347520873 t1: 62395687000; t2: 62395690171 t1: 62432435000; t2: 62432437313 t1: 62478489000; t2: 62478492465 t1: 62514990000; t2: 62514992534 t1: 62515479000; t2: 62515480327 t1: 62515485000; t2: 62515486344 Fixes #21656 - - - - - 722814ba by Yiyun Liu at 2022-06-10T21:23:03-04:00 Use <br> instead of newline character - - - - - dc202080 by Matthew Craven at 2022-06-13T14:07:12-04:00 Use (fixed_lev = True) in mkDataTyConRhs - - - - - ad70c621 by Matthew Pickering at 2022-06-14T08:40:53-04:00 hadrian: Fix testing stage1 compiler There were various issues with testing the stage1 compiler.. 1. The wrapper was not being built 2. The wrapper was picking up the stage0 package database and trying to load prelude from that. 3. The wrappers never worked on windows so just don't support that for now. Fixes #21072 - - - - - ac83899d by Ben Gamari at 2022-06-14T08:41:30-04:00 validate: Ensure that $make variable is set Currently the `$make` variable is used without being set in `validate`'s Hadrian path, which uses make to install the binary distribution. Fix this. Fixes #21687. - - - - - 59bc6008 by John Ericson at 2022-06-15T18:05:35+00:00 CoreToStg.Prep: Get rid of `DynFlags` and `HscEnv` The call sites in `Driver.Main` are duplicative, but this is good, because the next step is to remove `InteractiveContext` from `Core.Lint` into `Core.Lint.Interactive`. Also further clean up `Core.Lint` to use a better configuration record than the one we initially added. - - - - - aa9d9381 by Ben Gamari at 2022-06-15T20:33:04-04:00 hadrian: Run xattr -rc . on bindist tarball Fixes #21506. - - - - - cdc75a1f by Ben Gamari at 2022-06-15T20:33:04-04:00 configure: Hide spurious warning from ld Previously the check_for_gold_t22266 configure check could result in spurious warnings coming from the linker being blurted to stderr. Suppress these by piping stderr to /dev/null. - - - - - e128b7b8 by Ben Gamari at 2022-06-15T20:33:40-04:00 cmm: Add surface syntax for MO_MulMayOflo - - - - - bde65ea9 by Ben Gamari at 2022-06-15T20:34:16-04:00 configure: Don't attempt to override linker on Darwin Configure's --enable-ld-override functionality is intended to ensure that we don't rely on ld.bfd, which tends to be slow and buggy, on Linux and Windows. However, on Darwin the lack of sensible package management makes it extremely easy for users to have awkward mixtures of toolchain components from, e.g., XCode, the Apple Command-Line Tools package, and homebrew. This leads to extremely confusing problems like #21712. Here we avoid this by simply giving up on linker selection on Darwin altogether. This isn't so bad since the Apple ld64 linker has decent performance and AFAICT fairly reliable. Closes #21712. - - - - - 25b510c3 by Torsten Schmits at 2022-06-16T12:37:45-04:00 replace quadratic nub to fight byte code gen perf explosion Despite this code having been present in the core-to-bytecode implementation, I have observed it in the wild starting with 9.2, causing enormous slowdown in certain situations. My test case produces the following profiles: Before: ``` total time = 559.77 secs (559766 ticks @ 1000 us, 1 processor) total alloc = 513,985,665,640 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes elem_by Data.OldList libraries/base/Data/OldList.hs:429:1-7 67.6 92.9 378282 477447404296 eqInt GHC.Classes libraries/ghc-prim/GHC/Classes.hs:275:8-14 12.4 0.0 69333 32 $c>>= GHC.Data.IOEnv <no location info> 6.9 0.6 38475 3020371232 ``` After: ``` total time = 89.83 secs (89833 ticks @ 1000 us, 1 processor) total alloc = 39,365,306,360 bytes (excludes profiling overheads) COST CENTRE MODULE SRC %time %alloc ticks bytes $c>>= GHC.Data.IOEnv <no location info> 43.6 7.7 39156 3020403424 doCase GHC.StgToByteCode compiler/GHC/StgToByteCode.hs:(805,1)-(1054,53) 2.5 7.4 2246 2920777088 ``` - - - - - aa7e1f20 by Matthew Pickering at 2022-06-16T12:38:21-04:00 hadrian: Don't install `include/` directory in bindist. The install_includes for the RTS package used to be put in the top-level ./include folder but this would lead to confusing things happening if you installed multiple GHC versions side-by-side. We don't need this folder anymore because install-includes is honoured properly by cabal and the relevant header files already copied in by the cabal installation process. If you want to depend on the header files for the RTS in a Haskell project then you just have to depend on the `rts` package and the correct include directories will be provided for you. If you want to depend on the header files in a standard C project then you should query ghc-pkg to get the right paths. ``` ghc-pkg field rts include-dirs --simple-output ``` Fixes #21609 - - - - - 03172116 by Bryan Richter at 2022-06-16T12:38:57-04:00 Enable eventlogs on nightly perf job - - - - - ecbf8685 by Hécate Moonlight at 2022-06-16T16:30:00-04:00 Repair dead link in TH haddocks Closes #21724 - - - - - 99ff3818 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian: allow configuring Hsc2Hs This patch adds the ability to pass options to Hsc2Hs as Hadrian key/value settings, in the same way as cabal configure options, using the syntax: *.*.hsc2hs.run.opts += ... - - - - - 9c575f24 by sheaf at 2022-06-16T16:30:39-04:00 Hadrian bootstrap: look up hsc2hs Hadrian bootstrapping looks up where to find ghc_pkg, but the same logic was not in place for hsc2hs which meant we could fail to find the appropriate hsc2hs executabe when bootstrapping Hadrian. This patch adds that missing logic. - - - - - 229d741f by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Add (broken) test for #21622 - - - - - cadd7753 by Ben Gamari at 2022-06-18T10:42:54-04:00 ghc-heap: Don't Box NULL pointers Previously we could construct a `Box` of a NULL pointer from the `link` field of `StgWeak`. Now we take care to avoid ever introducing such pointers in `collect_pointers` and ensure that the `link` field is represented as a `Maybe` in the `Closure` type. Fixes #21622 - - - - - 31c214cc by Tamar Christina at 2022-06-18T10:43:34-04:00 winio: Add support to console handles to handleToHANDLE - - - - - 711cb417 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Add SMUL[LH] instructions These will be needed to fix #21624. - - - - - d05d90d2 by Ben Gamari at 2022-06-18T10:44:11-04:00 CmmToAsm/AArch64: Fix syntax of OpRegShift operands Previously this produced invalid assembly containing a redundant comma. - - - - - a1e1d8ee by Ben Gamari at 2022-06-18T10:44:11-04:00 ncg/aarch64: Fix implementation of IntMulMayOflo The code generated for IntMulMayOflo was previously wrong as it depended upon the overflow flag, which the AArch64 MUL instruction does not set. Fix this. Fixes #21624. - - - - - 26745006 by Ben Gamari at 2022-06-18T10:44:11-04:00 testsuite: Add test for #21624 Ensuring that mulIntMayOflo# behaves as expected. - - - - - 94f2e92a by Sebastian Graf at 2022-06-20T09:40:58+02:00 CprAnal: Set signatures of DFuns to top The recursive DFun in the reproducer for #20836 also triggered a bug in CprAnal that is observable in a debug build. The CPR signature of a recursive DFunId was never updated and hence the optimistic arity 0 bottom signature triggered a mismatch with the arity 1 of the binding in WorkWrap. We never miscompiled any code because WW doesn't exploit bottom CPR signatures. - - - - - b570da84 by Sebastian Graf at 2022-06-20T09:43:29+02:00 CorePrep: Don't speculatively evaluate recursive calls (#20836) In #20836 we have optimised a terminating program into an endless loop, because we speculated the self-recursive call of a recursive DFun. Now we track the set of enclosing recursive binders in CorePrep to prevent speculation of such self-recursive calls. See the updates to Note [Speculative evaluation] for details. Fixes #20836. - - - - - 49fb2f9b by Sebastian Graf at 2022-06-20T09:43:32+02:00 Simplify: Take care with eta reduction in recursive RHSs (#21652) Similar to the fix to #20836 in CorePrep, we now track the set of enclosing recursive binders in the SimplEnv and SimpleOptEnv. See Note [Eta reduction in recursive RHSs] for details. I also updated Note [Arity robustness] with the insights Simon and I had in a call discussing the issue. Fixes #21652. Unfortunately, we get a 5% ghc/alloc regression in T16577. That is due to additional eta reduction in GHC.Read.choose1 and the resulting ANF-isation of a large list literal at the top-level that didn't happen before (presumably because it was too interesting to float to the top-level). There's not much we can do about that. Metric Increase: T16577 - - - - - 2563b95c by Sebastian Graf at 2022-06-20T09:45:09+02:00 Ignore .hie-bios - - - - - e4e44d8d by Simon Peyton Jones at 2022-06-20T12:31:45-04:00 Instantiate top level foralls in partial type signatures The main fix for #21667 is the new call to tcInstTypeBnders in tcHsPartialSigType. It was really a simple omission before. I also moved the decision about whether we need to apply the Monomorphism Restriction, from `decideGeneralisationPlan` to `tcPolyInfer`. That removes a flag from the InferGen constructor, which is good. But more importantly, it allows the new function, checkMonomorphismRestriction called from `tcPolyInfer`, to "see" the `Types` involved rather than the `HsTypes`. And that in turn matters because we invoke the MR for partial signatures if none of the partial signatures in the group have any overloading context; and we can't answer that question for HsTypes. See Note [Partial type signatures and the monomorphism restriction] in GHC.Tc.Gen.Bind. This latter is really a pre-existing bug. - - - - - 262a9f93 by Winston Hartnett at 2022-06-20T12:32:23-04:00 Make Outputable instance for InlineSig print the InlineSpec Fix ghc/ghc#21739 Squash fix ghc/ghc#21739 - - - - - b5590fff by Matthew Pickering at 2022-06-20T12:32:59-04:00 Add NO_BOOT to hackage_doc_tarball job We were attempting to boot a src-tarball which doesn't work as ./boot is not included in the source tarball. This slipped through as the job is only run on nightly. - - - - - d24afd9d by Vladislav Zavialov at 2022-06-20T17:34:44-04:00 HsToken for @-patterns and TypeApplications (#19623) One more step towards the new design of EPA. - - - - - 159b7628 by Tamar Christina at 2022-06-20T17:35:23-04:00 linker: only keep rtl exception tables if they have been relocated - - - - - da5ff105 by Andreas Klebinger at 2022-06-21T17:04:12+02:00 Ticky:Make json info a separate field. - - - - - 1a4ce4b2 by Matthew Pickering at 2022-06-22T09:49:22+01:00 Revert "Ticky:Make json info a separate field." This reverts commit da5ff10503e683e2148c62e36f8fe2f819328862. This was pushed directly without review. - - - - - f89bf85f by Vanessa McHale at 2022-06-22T08:21:32-04:00 Flags to disable local let-floating; -flocal-float-out, -flocal-float-out-top-level CLI flags These flags affect the behaviour of local let floating. If `-flocal-float-out` is disabled (the default) then we disable all local floating. ``` …(let x = let y = e in (a,b) in body)... ===> …(let y = e; x = (a,b) in body)... ``` Further to this, top-level local floating can be disabled on it's own by passing -fno-local-float-out-top-level. ``` x = let y = e in (a,b) ===> y = e; x = (a,b) ``` Note that this is only about local floating, ie, floating two adjacent lets past each other and doesn't say anything about the global floating pass which is controlled by `-fno-float`. Fixes #13663 - - - - - 4ccefc6e by Matthew Craven at 2022-06-22T08:22:12-04:00 Check for Int overflows in Data.Array.Byte - - - - - 2004e3c8 by Matthew Craven at 2022-06-22T08:22:12-04:00 Add a basic test for ByteArray's Monoid instance - - - - - fb36770c by Matthew Craven at 2022-06-22T08:22:12-04:00 Rename `copyByteArray` to `unsafeCopyByteArray` - - - - - ecc9aedc by Ben Gamari at 2022-06-22T08:22:48-04:00 testsuite: Add test for #21719 Happily, this has been fixed since 9.2. - - - - - 19606c42 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Use lookupNameCache instead of lookupOrigIO - - - - - 4c9dfd69 by Brandon Chinn at 2022-06-22T08:23:28-04:00 Break out thNameToGhcNameIO (ref. #21730) - - - - - eb4fb849 by Michael Peyton Jones at 2022-06-22T08:24:07-04:00 Add laws for 'toInteger' and 'toRational' CLC discussion here: https://github.com/haskell/core-libraries-committee/issues/58 - - - - - c1a950c1 by Alexander Esgen at 2022-06-22T12:36:13+00:00 Correct documentation of defaults of the `-V` RTS option - - - - - b7b7d90d by Matthew Pickering at 2022-06-22T21:58:12-04:00 Transcribe discussion from #21483 into a Note In #21483 I had a discussion with Simon Marlow about the memory retention behaviour of -Fd. I have just transcribed that conversation here as it elucidates the potentially subtle assumptions which led to the design of the memory retention behaviours of -Fd. Fixes #21483 - - - - - 980d1954 by Ben Gamari at 2022-06-22T21:58:48-04:00 eventlog: Don't leave dangling pointers hanging around Previously we failed to reset pointers to various eventlog buffers to NULL after freeing them. In principle we shouldn't look at them after they are freed but nevertheless it is good practice to set them to a well-defined value. - - - - - 575ec846 by Eric Lindblad at 2022-06-22T21:59:28-04:00 runhaskell - - - - - e6a69337 by Artem Pelenitsyn at 2022-06-22T22:00:07-04:00 re-export GHC.Natural.minusNaturalMaybe from Numeric.Natural CLC proposal: https://github.com/haskell/core-libraries-committee/issues/45 - - - - - 5d45aa97 by Gergo ERDI at 2022-06-22T22:00:46-04:00 When specialising, look through floatable ticks. Fixes #21697. - - - - - 531205ac by Andreas Klebinger at 2022-06-22T22:01:22-04:00 TagCheck.hs: Properly check if arguments are boxed types. For one by mistake I had been checking against the kind of runtime rep instead of the boxity. This uncovered another bug, namely that we tried to generate the checking code before we had associated the function arguments with a register, so this could never have worked to begin with. This fixes #21729 and both of the above issues. - - - - - c7f9f6b5 by Gleb Popov at 2022-06-22T22:02:00-04:00 Use correct arch for the FreeBSD triple in gen-data-layout.sh Downstream bug for reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261798 Relevant upstream issue: #15718 - - - - - 75f0091b by Andreas Klebinger at 2022-06-22T22:02:35-04:00 Bump nofib submodule. Allows the shake runner to build with 9.2.3 among other things. Fixes #21772 - - - - - 0aa0ce69 by Ben Gamari at 2022-06-27T08:01:03-04:00 Bump ghc-prim and base versions To 0.9.0 and 4.17.0 respectively. Bumps array, deepseq, directory, filepath, haskeline, hpc, parsec, stm, terminfo, text, unix, haddock, and hsc2hs submodules. (cherry picked from commit ba47b95122b7b336ce1cc00896a47b584ad24095) - - - - - 4713abc2 by Ben Gamari at 2022-06-27T08:01:03-04:00 testsuite: Use normalise_version more consistently Previously several tests' output were unnecessarily dependent on version numbers, particularly of `base`. Fix this. - - - - - d7b0642b by Matthew Pickering at 2022-06-27T08:01:03-04:00 linters: Fix lint-submodule-refs when crashing trying to find plausible branches - - - - - 38378be3 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 hadrian: Improve haddocks for ghcDebugAssertions - - - - - ac7a7fc8 by Andreas Klebinger at 2022-06-27T08:01:39-04:00 Don't mark lambda binders as OtherCon We used to put OtherCon unfoldings on lambda binders of workers and sometimes also join points/specializations with with the assumption that since the wrapper would force these arguments once we execute the RHS they would indeed be in WHNF. This was wrong for reasons detailed in #21472. So now we purge evaluated unfoldings from *all* lambda binders. This fixes #21472, but at the cost of sometimes not using as efficient a calling convention. It can also change inlining behaviour as some occurances will no longer look like value arguments when they did before. As consequence we also change how we compute CBV information for arguments slightly. We now *always* determine the CBV convention for arguments during tidy. Earlier in the pipeline we merely mark functions as candidates for having their arguments treated as CBV. As before the process is described in the relevant notes: Note [CBV Function Ids] Note [Attaching CBV Marks to ids] Note [Never put `OtherCon` unfoldigns on lambda binders] ------------------------- Metric Decrease: T12425 T13035 T18223 T18223 T18923 MultiLayerModulesTH_OneShot Metric Increase: WWRec ------------------------- - - - - - 06cf6f4a by Tony Zorman at 2022-06-27T08:02:18-04:00 Add suggestions for unrecognised pragmas (#21589) In case of a misspelled pragma, offer possible corrections as to what the user could have meant. Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/21589 - - - - - 3fbab757 by Greg Steuck at 2022-06-27T08:02:56-04:00 Remove the traces of i386-*-openbsd, long live amd64 OpenBSD will not ship any ghc packages on i386 starting with 7.2 release. This means there will not be a bootstrap compiler easily available. The last available binaries are ghc-8.10.6 which is already not supported as bootstrap for HEAD. See here for more information: https://marc.info/?l=openbsd-ports&m=165060700222580&w=2 - - - - - 58530271 by Bodigrim at 2022-06-27T08:03:34-04:00 Add Foldable1 and Bifoldable1 type classes Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/9 Instances roughly follow https://hackage.haskell.org/package/semigroupoids-5.3.7/docs/Data-Semigroup-Foldable-Class.html#t:Foldable1 but the API of `Foldable1` was expanded in comparison to `semigroupoids`. Compatibility shim is available from https://github.com/phadej/foldable1 (to be released). Closes #13573. - - - - - a51f4ecc by Naomi Liu at 2022-06-27T08:04:13-04:00 add levity polymorphism to addrToAny# - - - - - f4edcdc4 by Naomi Liu at 2022-06-27T08:04:13-04:00 add tests for addrToAny# levity - - - - - 07016fc9 by Matthew Pickering at 2022-06-27T08:04:49-04:00 hadrian: Update main README page This README had some quite out-of-date content about the build system so I did a complete pass deleting old material. I also made the section about flavours more prominent and mentioned flavour transformers. - - - - - 79ae2d89 by Ben Gamari at 2022-06-27T08:05:24-04:00 testsuite: Hide output from test compilations with verbosity==2 Previously the output from test compilations used to determine whether, e.g., profiling libraries are available was shown with verbosity levels >= 2. However, the default level is 2, meaning that most users were often spammed with confusing errors. Fix this by bumping the verbosity threshold for this output to >=3. Fixes #21760. - - - - - 995ea44d by Ben Gamari at 2022-06-27T08:06:00-04:00 configure: Only probe for LD in FIND_LD Since 6be2c5a7e9187fc14d51e1ec32ca235143bb0d8b we would probe for LD rather early in `configure`. However, it turns out that this breaks `configure`'s `ld`-override logic, which assumes that `LD` was set by the user and aborts. Fixes #21778. - - - - - b43d140b by Sergei Trofimovich at 2022-06-27T08:06:39-04:00 `.hs-boot` make rules: add missing order-only dependency on target directory Noticed missing target directory dependency as a build failure in `make --shuffle` mode (added in https://savannah.gnu.org/bugs/index.php?62100): "cp" libraries/base/./GHC/Stack/CCS.hs-boot libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot cp: cannot create regular file 'libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot': No such file or directory libraries/haskeline/ghc.mk:4: libraries/haskeline/dist-install/build/.depend-v-p-dyn.haskell: No such file or directory make[1]: *** [libraries/base/ghc.mk:4: libraries/base/dist-install/build/GHC/Stack/CCS.hs-boot] Error 1 shuffle=1656129254 make: *** [Makefile:128: all] Error 2 shuffle=1656129254 Note that `cp` complains about inability to create target file. The change adds order-only dependency on a target directory (similar to the rest of rules in that file). The bug is lurking there since 2009 commit 34cc75e1a (`GHC new build system megapatch`.) where upfront directory creation was never added to `.hs-boot` files. - - - - - 57a5f88c by Ben Gamari at 2022-06-28T03:24:24-04:00 Mark AArch64/Darwin as requiring sign-extension Apple's AArch64 ABI requires that the caller sign-extend small integer arguments. Set platformCConvNeedsExtension to reflect this fact. Fixes #21773. - - - - - df762ae9 by Ben Gamari at 2022-06-28T03:24:24-04:00 -ddump-llvm shouldn't imply -fllvm Previously -ddump-llvm would change the backend used, which contrasts with all other dump flags. This is quite surprising and cost me quite a bit of time. Dump flags should not change compiler behavior. Fixes #21776. - - - - - 70f0c1f8 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Re-format argument handling logic Previously there were very long, hard to parse lines. Fix this. - - - - - 696d64c3 by Ben Gamari at 2022-06-28T03:24:24-04:00 CmmToAsm/AArch64: Sign-extend narrow C arguments The AArch64/Darwin ABI requires that function arguments narrower than 32-bits must be sign-extended by the caller. We neglected to do this, resulting in #20735. Fixes #20735. - - - - - c006ac0d by Ben Gamari at 2022-06-28T03:24:24-04:00 testsuite: Add test for #20735 - - - - - 16b9100c by Ben Gamari at 2022-06-28T03:24:59-04:00 integer-gmp: Fix cabal file Evidently fields may not come after sections in a cabal file. - - - - - 03cc5d02 by Sergei Trofimovich at 2022-06-28T15:20:45-04:00 ghc.mk: fix 'make install' (`mk/system-cxx-std-lib-1.0.conf.install` does not exist) before the change `make install` was failing as: ``` "mv" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc-stage2" "/<<NIX>>/ghc-9.3.20220406/lib/ghc-9.5.20220625/bin/ghc" make[1]: *** No rule to make target 'mk/system-cxx-std-lib-1.0.conf.install', needed by 'install_packages'. Stop. ``` I think it's a recent regression caused by 0ef249aa where `system-cxx-std-lib-1.0.conf` is created (somewhat manually), but not the .install varianlt of it. The fix is to consistently use `mk/system-cxx-std-lib-1.0.conf` everywhere. Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/21784 - - - - - eecab8f9 by Simon Peyton Jones at 2022-06-28T15:21:21-04:00 Comments only, about join points This MR just adds some documentation about why casts destroy join points, following #21716. - - - - - 251471e7 by Matthew Pickering at 2022-06-28T19:02:41-04:00 Cleanup BuiltInSyntax vs UserSyntax There was some confusion about whether FUN/TYPE/One/Many should be BuiltInSyntax or UserSyntax. The answer is certainly UserSyntax as BuiltInSyntax is for things which are directly constructed by the parser rather than going through normal renaming channels. I fixed all the obviously wrong places I could find and added a test for the original bug which was caused by this (#21752) Fixes #21752 #20695 #18302 - - - - - 0e22f16c by Ben Gamari at 2022-06-28T19:03:16-04:00 template-haskell: Bump version to 2.19.0.0 Bumps text and exceptions submodules due to bounds. - - - - - bbe6f10e by Emily Bourke at 2022-06-29T08:23:13+00:00 Tiny tweak to `IOPort#` documentation The exclamation mark and bracket don’t seem to make sense here. I’ve looked through the history, and I don’t think they’re deliberate – possibly a copy-and-paste error. - - - - - 70e47489 by Dominik Peteler at 2022-06-29T19:26:31-04:00 Remove `CoreOccurAnal` constructor of the `CoreToDo` type It was dead code since the last occurence in an expression context got removed in 71916e1c018dded2e68d6769a2dbb8777da12664. - - - - - d0722170 by nineonine at 2022-07-01T08:15:56-04:00 Fix panic with UnliftedFFITypes+CApiFFI (#14624) When declaring foreign import using CAPI calling convention, using unlifted unboxed types would result in compiler panic. There was an attempt to fix the situation in #9274, however it only addressed some of the ByteArray cases. This patch fixes other missed cases for all prims that may be used as basic foreign types. - - - - - eb043148 by Douglas Wilson at 2022-07-01T08:16:32-04:00 rts: gc stats: account properly for copied bytes in sequential collections We were not updating the [copied,any_work,scav_find_work, max_n_todo_overflow] counters during sequential collections. As well, we were double counting for parallel collections. To fix this we add an `else` clause to the `if (is_par_gc())`. The par_* counters do not need to be updated in the sequential case because they must be 0. - - - - - f95edea9 by Matthew Pickering at 2022-07-01T19:21:55-04:00 desugar: Look through ticks when warning about possible literal overflow Enabling `-fhpc` or `-finfo-table-map` would case a tick to end up between the appliation of `neg` to its argument. This defeated the special logic which looks for `NegApp ... (HsOverLit` to warn about possible overflow if a user writes a negative literal (without out NegativeLiterals) in their code. Fixes #21701 - - - - - f25c8d03 by Matthew Pickering at 2022-07-01T19:22:31-04:00 ci: Fix definition of slow-validate flavour (so that -dlint) is passed In this embarassing sequence of events we were running slow-validate without -dlint. - - - - - bf7991b0 by Mike Pilgrem at 2022-07-02T10:12:04-04:00 Identify the extistence of the `runhaskell` command and that it is equivalent to the `runghc` command. Add an entry to the index for `runhaskell`. See https://gitlab.haskell.org/ghc/ghc/-/issues/21411 - - - - - 9e79f6d0 by Simon Jakobi at 2022-07-02T10:12:39-04:00 Data.Foldable1: Remove references to Foldable-specific note ...as discussed in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495#note_439455. - - - - - 3a8970ac by romes at 2022-07-03T14:11:31-04:00 TTG: Move HsModule to L.H.S Move the definition of HsModule defined in GHC.Hs to Language.Haskell.Syntax with an added TTG parameter and corresponding extension fields. This is progress towards having the haskell-syntax package, as described in #21592 - - - - - f9f80995 by romes at 2022-07-03T14:11:31-04:00 TTG: Move ImpExp client-independent bits to L.H.S.ImpExp Move the GHC-independent definitions from GHC.Hs.ImpExp to Language.Haskell.Syntax.ImpExp with the required TTG extension fields such as to keep the AST independent from GHC. This is progress towards having the haskell-syntax package, as described in #21592 Bumps haddock submodule - - - - - c43dbac0 by romes at 2022-07-03T14:11:31-04:00 Refactor ModuleName to L.H.S.Module.Name ModuleName used to live in GHC.Unit.Module.Name. In this commit, the definition of ModuleName and its associated functions are moved to Language.Haskell.Syntax.Module.Name according to the current plan towards making the AST GHC-independent. The instances for ModuleName for Outputable, Uniquable and Binary were moved to the module in which the class is defined because these instances depend on GHC. The instance of Eq for ModuleName is slightly changed to no longer depend on unique explicitly and instead uses FastString's instance of Eq. - - - - - 2635c6f2 by konsumlamm at 2022-07-03T14:12:11-04:00 Expand `Ord` instance for `Down` Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/23#issuecomment-1172932610 - - - - - 36fba0df by Anselm Schüler at 2022-07-04T05:06:42+00:00 Add applyWhen to Data.Function per CLC prop Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/71#issuecomment-1165830233 - - - - - 3b13aab1 by Matthew Pickering at 2022-07-04T15:15:00-04:00 hadrian: Don't read package environments in ghc-stage1 wrapper The stage1 compiler may be on the brink of existence and not have even a working base library. You may have installed packages globally with a similar stage2 compiler which will then lead to arguments such as --show-iface not even working because you are passing too many package flags. The solution is simple, don't read these implicit files. Fixes #21803 - - - - - aba482ea by Andreas Klebinger at 2022-07-04T17:55:55-04:00 Ticky:Make json info a separate field. Fixes #21233 - - - - - 74f3867d by Matthew Pickering at 2022-07-04T17:56:30-04:00 Add docs:<pkg> command to hadrian to build docs for just one package - - - - - 418afaf1 by Matthew Pickering at 2022-07-04T17:56:30-04:00 upload-docs: propagate publish correctly in upload_sdist - - - - - ed793d7a by Matthew Pickering at 2022-07-04T17:56:30-04:00 docs-upload: Fix upload script when no packages are listed - - - - - d002c6e0 by Matthew Pickering at 2022-07-04T17:56:30-04:00 hadrian: Add --haddock-base-url option for specifying base-url when generating docs The motiviation for this flag is to be able to produce documentation which is suitable for uploading for hackage, ie, the cross-package links work correctly. There are basically three values you want to set this to: * off - default, base_url = ../%pkg% which works for local browsing * on - no argument , base_url = https:://hackage.haskell.org/package/%pkg%/docs - for hackage docs upload * on - argument, for example, base_url = http://localhost:8080/package/%pkg%/docs for testing the documentation. The `%pkg%` string is a template variable which is replaced with the package identifier for the relevant package. This is one step towards fixing #21749 - - - - - 41eb749a by Matthew Pickering at 2022-07-04T17:56:31-04:00 Add nightly job for generating docs suitable for hackage upload - - - - - 620ee7ed by Matthew Pickering at 2022-07-04T17:57:05-04:00 ghci: Support :set prompt in multi repl This adds supports for various :set commands apart from `:set <FLAG>` in multi repl, this includes `:set prompt` and so-on. Fixes #21796 - - - - - b151b65e by Matthew Pickering at 2022-07-05T16:32:31-04:00 Vendor filepath inside template-haskell Adding filepath as a dependency of template-haskell means that it can't be reinstalled if any build-plan depends on template-haskell. This is a temporary solution for the 9.4 release. A longer term solution is to split-up the template-haskell package into the wired-in part and a non-wired-in part which can be reinstalled. This was deemed quite risky on the 9.4 release timescale. Fixes #21738 - - - - - c9347ecf by John Ericson at 2022-07-05T16:33:07-04:00 Factor fields of `CoreDoSimplify` into separate data type This avoids some partiality. The work @mmhat is doing cleaning up and modularizing `Core.Opt` will build on this nicely. - - - - - d0e74992 by Eric Lindblad at 2022-07-06T01:35:48-04:00 https urls - - - - - 803e965c by Eric Lindblad at 2022-07-06T01:35:48-04:00 options and typos - - - - - 5519baa5 by Eric Lindblad at 2022-07-06T01:35:48-04:00 grammar - - - - - 4ddc1d3e by Eric Lindblad at 2022-07-06T01:35:48-04:00 sources - - - - - c95c2026 by Matthew Pickering at 2022-07-06T01:35:48-04:00 Fix lint warnings in bootstrap.py - - - - - 86ced2ad by romes at 2022-07-06T01:36:23-04:00 Restore Eq instance of ImportDeclQualifiedStyle Fixes #21819 - - - - - 3547e264 by romes at 2022-07-06T13:50:27-04:00 Prune L.H.S modules of GHC dependencies Move around datatypes, functions and instances that are GHC-specific out of the `Language.Haskell.Syntax.*` modules to reduce the GHC dependencies in them -- progressing towards #21592 Creates a module `Language.Haskell.Syntax.Basic` to hold basic definitions required by the other L.H.S modules (and don't belong in any of them) - - - - - e4eea07b by romes at 2022-07-06T13:50:27-04:00 TTG: Move CoreTickish out of LHS.Binds Remove the `[CoreTickish]` fields from datatype `HsBindLR idL idR` and move them to the extension point instance, according to the plan outlined in #21592 to separate the base AST from the GHC specific bits. - - - - - acc1816b by romes at 2022-07-06T13:50:27-04:00 TTG for ForeignImport/Export Add a TTG parameter to both `ForeignImport` and `ForeignExport` and, according to #21592, move the GHC-specific bits in them and in the other AST data types related to foreign imports and exports to the TTG extension point. - - - - - 371c5ecf by romes at 2022-07-06T13:50:27-04:00 TTG for HsTyLit Add TTG parameter to `HsTyLit` to move the GHC-specific `SourceText` fields to the extension point and out of the base AST. Progress towards #21592 - - - - - fd379d1b by romes at 2022-07-06T13:50:27-04:00 Remove many GHC dependencies from L.H.S Continue to prune the `Language.Haskell.Syntax.*` modules out of GHC imports according to the plan in the linked issue. Moves more GHC-specific declarations to `GHC.*` and brings more required GHC-independent declarations to `Language.Haskell.Syntax.*` (extending e.g. `Language.Haskell.Syntax.Basic`). Progress towards #21592 Bump haddock submodule for !8308 ------------------------- Metric Decrease: hard_hole_fits ------------------------- - - - - - c5415bc5 by Alan Zimmerman at 2022-07-06T13:50:27-04:00 Fix exact printing of the HsRule name Prior to this branch, the HsRule name was XRec pass (SourceText,RuleName) and there is an ExactPrint instance for (SourceText, RuleName). The SourceText has moved to a different location, so synthesise the original to trigger the correct instance when printing. We need both the SourceText and RuleName when exact printing, as it is possible to have a NoSourceText variant, in which case we fall back to the FastString. - - - - - 665fa5a7 by Matthew Pickering at 2022-07-06T13:51:03-04:00 driver: Fix issue with module loops and multiple home units We were attempting to rehydrate all dependencies of a particular module, but we actually only needed to rehydrate those of the current package (as those are the ones participating in the loop). This fixes loading GHC into a multi-unit session. Fixes #21814 - - - - - bbcaba6a by Andreas Klebinger at 2022-07-06T13:51:39-04:00 Remove a bogus #define from ClosureMacros.h - - - - - fa59223b by Tamar Christina at 2022-07-07T23:23:57-04:00 winio: make consoleReadNonBlocking not wait for any events at all. - - - - - 42c917df by Adam Sandberg Ericsson at 2022-07-07T23:24:34-04:00 rts: allow NULL to be used as an invalid StgStablePtr - - - - - 3739e565 by Andreas Schwab at 2022-07-07T23:25:10-04:00 RTS: Add stack marker to StgCRunAsm.S Every object file must be properly marked for non-executable stack, even if it contains no code. - - - - - a889bc05 by Ben Gamari at 2022-07-07T23:25:45-04:00 Bump unix submodule Adds `config.sub` to unix's `.gitignore`, fixing #19574. - - - - - 3609a478 by Matthew Pickering at 2022-07-09T11:11:58-04:00 ghci: Fix most calls to isLoaded to work in multi-mode The most egrarious thing this fixes is the report about the total number of loaded modules after starting a session. Ticket #20889 - - - - - fc183c90 by Matthew Pickering at 2022-07-09T11:11:58-04:00 Enable :edit command in ghci multi-mode. This works after the last change to isLoaded. Ticket #20888 - - - - - 46050534 by Simon Peyton Jones at 2022-07-09T11:12:34-04:00 Fix a scoping bug in the Specialiser In the call to `specLookupRule` in `already_covered`, in `specCalls`, we need an in-scope set that includes the free vars of the arguments. But we simply were not guaranteeing that: did not include the `rule_bndrs`. Easily fixed. I'm not sure how how this bug has lain for quite so long without biting us. Fixes #21828. - - - - - 6e8d9056 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Edit Note [idArity varies independently of dmdTypeDepth] ...and refer to it in GHC.Core.Lint.lintLetBind. Fixes #21452 - - - - - 89ba4655 by Simon Peyton Jones at 2022-07-12T13:26:52+00:00 Tiny documentation wibbles (comments only) - - - - - 61a46c6d by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix readme - - - - - 61babb5e by Eric Lindblad at 2022-07-13T08:28:29-04:00 fix bootstrap - - - - - 8b417ad5 by Eric Lindblad at 2022-07-13T08:28:29-04:00 tarball - - - - - e9d9f078 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Fix scopes for deriving clauses and instance signatures (#18425) - - - - - c4989131 by Zubin Duggal at 2022-07-13T14:00:18-04:00 hie-files: Record location of filled in default method bindings This is useful for hie files to reconstruct the evidence that default methods depend on. - - - - - 9c52e7fc by Zubin Duggal at 2022-07-13T14:00:18-04:00 testsuite: Factor out common parts from hiefile tests - - - - - 6a9e4493 by sheaf at 2022-07-13T14:00:56-04:00 Hadrian: update documentation of settings The documentation for key-value settings was a bit out of date. This patch updates it to account for `cabal.configure.opts` and `hsc2hs.run.opts`. The user-settings document was also re-arranged, to make the key-value settings more prominent (as it doesn't involve changing the Hadrian source code, and thus doesn't require any recompilation of Hadrian). - - - - - a2f142f8 by Zubin Duggal at 2022-07-13T20:43:32-04:00 Fix potential space leak that arise from ModuleGraphs retaining references to previous ModuleGraphs, in particular the lazy `mg_non_boot` field. This manifests in `extendMG`. Solution: Delete `mg_non_boot` as it is only used for `mgLookupModule`, which is only called in two places in the compiler, and should only be called at most once for every home unit: GHC.Driver.Make: mainModuleSrcPath :: Maybe String mainModuleSrcPath = do ms <- mgLookupModule mod_graph (mainModIs hue) ml_hs_file (ms_location ms) GHCI.UI: listModuleLine modl line = do graph <- GHC.getModuleGraph let this = GHC.mgLookupModule graph modl Instead `mgLookupModule` can be a linear function that looks through the entire list of `ModuleGraphNodes` Fixes #21816 - - - - - dcf8b30a by Ben Gamari at 2022-07-13T20:44:08-04:00 rts: Fix AdjustorPool bitmap manipulation Previously the implementation of bitmap_first_unset assumed that `__builtin_clz` would accept `uint8_t` however it apparently rather extends its argument to `unsigned int`. To fix this we simply revert to a naive implementation since handling the various corner cases with `clz` is quite tricky. This should be fine given that AdjustorPool isn't particularly hot. Ideally we would have a single, optimised bitmap implementation in the RTS but I'll leave this for future work. Fixes #21838. - - - - - ad8f3e15 by Luite Stegeman at 2022-07-16T07:20:36-04:00 Change GHCi bytecode return convention for unlifted datatypes. This changes the bytecode return convention for unlifted algebraic datatypes to be the same as for lifted types, i.e. ENTER/PUSH_ALTS instead of RETURN_UNLIFTED/PUSH_ALTS_UNLIFTED Fixes #20849 - - - - - 5434d1a3 by Colten Webb at 2022-07-16T07:21:15-04:00 Compute record-dot-syntax types Ensures type information for record-dot-syntax is included in HieASTs. See #21797 - - - - - 89d169ec by Colten Webb at 2022-07-16T07:21:15-04:00 Add record-dot-syntax test - - - - - 4beb9f3c by Ben Gamari at 2022-07-16T07:21:51-04:00 Document RuntimeRep polymorphism limitations of catch#, et al As noted in #21868, several primops accepting continuations producing RuntimeRep-polymorphic results aren't nearly as polymorphic as their types suggest. Document this limitation and adapt the `UnliftedWeakPtr` test to avoid breaking this limitation in `keepAlive#`. - - - - - 4ef1c65d by Ben Gamari at 2022-07-16T07:21:51-04:00 Make keepAlive# out-of-line This is a naive approach to fixing the unsoundness noticed in #21708. Specifically, we remove the lowering of `keepAlive#` via CorePrep and instead turn it into an out-of-line primop. This is simple, inefficient (since the continuation must now be heap allocated), but good enough for 9.4.1. We will revisit this (particiularly via #16098) in a future release. Metric Increase: T4978 T7257 T9203 - - - - - 1bbff35d by Greg Steuck at 2022-07-16T07:22:29-04:00 Suppress extra output from configure check for c++ libraries - - - - - 3acbd7ad by Ben Gamari at 2022-07-16T07:23:04-04:00 rel-notes: Drop mention of #21745 fix Since we have backported the fix to 9.4.1. - - - - - b27c2774 by Dominik Peteler at 2022-07-16T07:23:43-04:00 Align the behaviour of `dopt` and `log_dopt` Before the behaviour of `dopt` and `logHasDumpFlag` (and the underlying function `log_dopt`) were different as the latter did not take the verbosity level into account. This led to problems during the refactoring as we cannot simply replace calls to `dopt` with calls to `logHasDumpFlag`. In addition to that a subtle bug in the GHC module was fixed: `setSessionDynFlags` did not update the logger and as a consequence the verbosity value of the logger was not set appropriately. Fixes #21861 - - - - - 28347d71 by Douglas Wilson at 2022-07-16T13:25:06-04:00 rts: forkOn context switches the target capability Fixes #21824 - - - - - f1c44991 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Eliminate orphan Outputable instances Here we reorganize `GHC.Cmm` to eliminate the orphan `Outputable` and `OutputableP` instances for the Cmm AST. This makes it significantly easier to use the Cmm pretty-printers in tracing output without incurring module import cycles. - - - - - f2e5e763 by Ben Gamari at 2022-07-16T13:25:41-04:00 cmm: Move toBlockList to GHC.Cmm - - - - - fa092745 by Ben Gamari at 2022-07-16T13:25:41-04:00 compiler: Add haddock sections to GHC.Utils.Panic - - - - - 097759f9 by Ben Gamari at 2022-07-16T13:26:17-04:00 configure: Don't override Windows CXXFLAGS At some point we used the clang distribution from msys2's `MINGW64` environment for our Windows toolchain. This defaulted to using libgcc and libstdc++ for its runtime library. However, we found for a variety of reasons that compiler-rt, libunwind, and libc++ were more reliable, consequently we explicitly overrode the CXXFLAGS to use these. However, since then we have switched to use the `CLANG64` packaging, which default to these already. Consequently we can drop these arguments, silencing some redundant argument warnings from clang. Fixes #21669. - - - - - e38a2684 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Check that there are no NULL ctors - - - - - 616365b0 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/Elf: Introduce support for invoking finalizers on unload Addresses #20494. - - - - - cdd3be20 by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add T20494 - - - - - 03c69d8d by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Rename finit field to fini fini is short for "finalizer", which does not contain a "t". - - - - - 033580bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Refactor handling of oc->info Previously we would free oc->info after running initializers. However, we can't do this is we want to also run finalizers. Moreover, freeing oc->info so early was wrong for another reason: we will need it in order to unregister the exception tables (see the call to `RtlDeleteFunctionTable`). In service of #20494. - - - - - f17912e4 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Add finalization support This implements #20494 for the PEi386 linker. Happily, this also appears to fix `T9405`, resolving #21361. - - - - - 2cd75550 by Ben Gamari at 2022-07-16T23:50:36-04:00 Loader: Implement gnu-style -l:$path syntax Gnu ld allows `-l` to be passed an absolute file path, signalled by a `:` prefix. Implement this in the GHC's loader search logic. - - - - - 5781a360 by Ben Gamari at 2022-07-16T23:50:36-04:00 Statically-link against libc++ on Windows Unfortunately on Windows we have no RPATH-like facility, making dynamic linking extremely fragile. Since we cannot assume that the user will add their GHC installation to `$PATH` (and therefore their DLL search path) we cannot assume that the loader will be able to locate our `libc++.dll`. To avoid this, we instead statically link against `libc++.a` on Windows. Fixes #21435. - - - - - 8e2e883b by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Ensure that all .ctors/.dtors sections are run It turns out that PE objects may have multiple `.ctors`/`.dtors` sections but the RTS linker had assumed that there was only one. Fix this. Fixes #21618. - - - - - fba04387 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Respect dtor/ctor priority Previously we would run constructors and destructors in arbitrary order despite explicit priorities. Fixes #21847. - - - - - 1001952f by Ben Gamari at 2022-07-16T23:50:36-04:00 testsuite: Add test for #21618 and #21847 - - - - - 6f3816af by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/PEi386: Fix exception unwind unregistration RtlDeleteFunctionTable expects a pointer to the .pdata section yet we passed it the .xdata section. Happily, this fixes #21354. - - - - - d9bff44c by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Drop dead code - - - - - d161e6bc by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Use section flags to identify initializers - - - - - fbb17110 by Ben Gamari at 2022-07-16T23:50:36-04:00 rts/linker/MachO: Introduce finalizer support - - - - - 5b0ed8a8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Use system-cxx-std-lib instead of config.stdcxx_impl - - - - - 6c476e1a by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker/Elf: Work around GCC 6 init/fini behavior It appears that GCC 6t (at least on i386) fails to give init_array/fini_array sections the correct SHT_INIT_ARRAY/SHT_FINI_ARRAY section types, instead marking them as SHT_PROGBITS. This caused T20494 to fail on Debian. - - - - - 5f8203b8 by Ben Gamari at 2022-07-16T23:50:37-04:00 testsuite: Mark T13366Cxx as unbroken on Darwin - - - - - 1fd2f851 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Fix resolution of __dso_handle on Darwin Darwin expects a leading underscore. - - - - - a2dc00f3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Clean up section kinds - - - - - aeb1a7c3 by Ben Gamari at 2022-07-16T23:50:37-04:00 rts/linker: Ensure that __cxa_finalize is called on code unload - - - - - 028f081e by Ben Gamari at 2022-07-16T23:51:12-04:00 testsuite: Fix T11829 on Centos 7 It appears that Centos 7 has a more strict C++ compiler than most distributions since std::runtime_error is defined in <stdexcept> rather than <exception>. In T11829 we mistakenly imported the latter. - - - - - a10584e8 by Ben Gamari at 2022-07-17T22:30:32-04:00 hadrian: Rename documentation directories for consistency with make * Rename `docs` to `doc` * Place pdf documentation in `doc/` instead of `doc/pdfs/` Fixes #21164. - - - - - b27c5947 by Anselm Schüler at 2022-07-17T22:31:11-04:00 Fix incorrect proof of applyWhen’s properties - - - - - eb031a5b by Matthew Pickering at 2022-07-18T08:04:47-04:00 hadrian: Add multi:<pkg> and multi targets for starting a multi-repl This patch adds support to hadrian for starting a multi-repl containing all the packages which stage0 can build. In particular, there is the new user-facing command: ``` ./hadrian/ghci-multi ``` which when executed will start a multi-repl containing the `ghc` package and all it's dependencies. This is implemented by two new hadrian targets: ``` ./hadrian/build multi:<pkg> ``` Construct the arguments for a multi-repl session where the top-level package is <pkg>. For example, `./hadrian/ghci-multi` is implemented using `multi:ghc` target. There is also the `multi` command which constructs a repl for everything in stage0 which we can build. - - - - - 19e7cac9 by Eric Lindblad at 2022-07-18T08:05:27-04:00 changelog typo - - - - - af6731a4 by Eric Lindblad at 2022-07-18T08:05:27-04:00 typos - - - - - 415468fe by Simon Peyton Jones at 2022-07-18T16:36:54-04:00 Refactor SpecConstr to use treat bindings uniformly This patch, provoked by #21457, simplifies SpecConstr by treating top-level and nested bindings uniformly (see the new scBind). * Eliminates the mysterious scTopBindEnv * Refactors scBind to handle top-level and nested definitions uniformly. * But, for now at least, continues the status quo of not doing SpecConstr for top-level non-recursive bindings. (In contrast we do specialise nested non-recursive bindings, although the original paper did not; see Note [Local let bindings].) I tried the effect of specialising top-level non-recursive bindings (which is now dead easy to switch on, unlike before) but found some regressions, so I backed off. See !8135. It's a pure refactoring. I think it'll do a better job in a few cases, but there is no regression test. - - - - - d4d3fe6e by Andreas Klebinger at 2022-07-18T16:37:29-04:00 Rule matching: Don't compute the FVs if we don't look at them. - - - - - 5f907371 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 White space only in FamInstEnv - - - - - ae3b3b62 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make transferPolyIdInfo work for CPR I don't know why this hasn't bitten us before, but it was plain wrong. - - - - - 9bdfdd98 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Inline mapAccumLM This function is called in inner loops in the compiler, and it's overloaded and higher order. Best just to inline it. This popped up when I was looking at something else. I think perhaps GHC is delicately balanced on the cusp of inlining this automatically. - - - - - d0b806ff by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Make SetLevels honour floatConsts This fix, in the definition of profitableFloat, is just for consistency. `floatConsts` should do what it says! I don't think it'll affect anything much, though. - - - - - d1c25a48 by Simon Peyton Jones at 2022-07-18T16:38:04-04:00 Refactor wantToUnboxArg a bit * Rename GHC.Core.Opt.WorkWrap.Utils.wantToUnboxArg to canUnboxArg and similarly wantToUnboxResult to canUnboxResult. * Add GHC.Core.Opt.DmdAnal.wantToUnboxArg as a wrapper for the (new) GHC.Core.Opt.WorkWrap.Utils.canUnboxArg, avoiding some yukky duplication. I decided it was clearer to give it a new data type for its return type, because I nedeed the FD_RecBox case which was not otherwise readiliy expressible. * Add dcpc_args to WorkWrap.Utils.DataConPatContext for the payload * Get rid of the Unlift constructor of UnboxingDecision, eliminate two panics, and two arguments to canUnboxArg (new name). Much nicer now. - - - - - 6d8a715e by Teo Camarasu at 2022-07-18T16:38:44-04:00 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. - - - - - aa75bbde by Ben Gamari at 2022-07-18T16:39:20-04:00 gitignore: don't ignore all aclocal.m4 files While GHC's own aclocal.m4 is generated by the aclocal tool, other packages' aclocal.m4 are committed in the repository. Previously `.gitignore` included an entry which covered *any* file named `aclocal.m4`, which lead to quite some confusion (e.g. see #21740). Fix this by modifying GHC's `.gitignore` to only cover GHC's own `aclocal.m4`. - - - - - 4b98c5ce by Boris Lykah at 2022-07-19T02:34:12-04:00 Add mapAccumM, forAccumM to Data.Traversable Approved by Core Libraries Committee in https://github.com/haskell/core-libraries-committee/issues/65#issuecomment-1186275433 - - - - - bd92182c by Ben Gamari at 2022-07-19T02:34:47-04:00 configure: Use AC_PATH_TOOL to detect tools Previously we used AC_PATH_PROG which, as noted by #21601, does not look for tools with a target prefix, breaking cross-compilation. Fixes #21601. - - - - - e8c07aa9 by Matthew Pickering at 2022-07-19T10:07:53-04:00 driver: Fix implementation of -S We were failing to stop before running the assembler so the object file was also created. Fixes #21869 - - - - - e2f0094c by Ben Gamari at 2022-07-19T10:08:28-04:00 rts/ProfHeap: Ensure new Censuses are zeroed When growing the Census array ProfHeap previously neglected to zero the new part of the array. Consequently `freeEra` would attempt to free random words that often looked suspiciously like pointers. Fixes #21880. - - - - - 81d65f7f by sheaf at 2022-07-21T15:37:22+02:00 Make withDict opaque to the specialiser As pointed out in #21575, it is not sufficient to set withDict to inline after the typeclass specialiser, because we might inline withDict in one module and then import it in another, and we run into the same problem. This means we could still end up with incorrect runtime results because the typeclass specialiser would assume that distinct typeclass evidence terms at the same type are equal, when this is not necessarily the case when using withDict. Instead, this patch introduces a new magicId, 'nospec', which is only inlined in CorePrep. We make use of it in the definition of withDict to ensure that the typeclass specialiser does not common up distinct typeclass evidence terms. Fixes #21575 - - - - - 9a3e1f31 by Dominik Peteler at 2022-07-22T08:18:40-04:00 Refactored Simplify pass * Removed references to driver from GHC.Core.LateCC, GHC.Core.Simplify namespace and GHC.Core.Opt.Stats. Also removed services from configuration records. * Renamed GHC.Core.Opt.Simplify to GHC.Core.Opt.Simplify.Iteration. * Inlined `simplifyPgm` and renamed `simplifyPgmIO` to `simplifyPgm` and moved the Simplify driver to GHC.Core.Opt.Simplify. * Moved `SimplMode` and `FloatEnable` to GHC.Core.Opt.Simplify.Env. * Added a configuration record `TopEnvConfig` for the `SimplTopEnv` environment in GHC.Core.Opt.Simplify.Monad. * Added `SimplifyOpts` and `SimplifyExprOpts`. Provide initialization functions for those in a new module GHC.Driver.Config.Core.Opt.Simplify. Also added initialization functions for `SimplMode` to that module. * Moved `CoreToDo` and friends to a new module GHC.Core.Pipeline.Types and the counting types and functions (`SimplCount` and `Tick`) to new module GHC.Core.Opt.Stats. * Added getter functions for the fields of `SimplMode`. The pedantic bottoms option and the platform are retrieved from the ArityOpts and RuleOpts and the getter functions allow us to retrieve values from `SpecEnv` without the knowledge where the data is stored exactly. * Moved the coercion optimization options from the top environment to `SimplMode`. This way the values left in the top environment are those dealing with monadic functionality, namely logging, IO related stuff and counting. Added a note "The environments of the Simplify pass". * Removed `CoreToDo` from GHC.Core.Lint and GHC.CoreToStg.Prep and got rid of `CoreDoSimplify`. Pass `SimplifyOpts` in the `CoreToDo` type instead. * Prep work before removing `InteractiveContext` from `HscEnv`. - - - - - 2c5991cc by Simon Peyton Jones at 2022-07-22T08:18:41-04:00 Make the specialiser deal better with specialised methods This patch fixes #21848, by being more careful to update unfoldings in the type-class specialiser. See the new Note [Update unfolding after specialisation] Now that we are being so much more careful about unfoldings, it turned out that I could dispense with se_interesting, and all its tricky corners. Hooray. This fixes #21368. - - - - - ae166635 by Ben Gamari at 2022-07-22T08:18:41-04:00 ghc-boot: Clean up UTF-8 codecs In preparation for moving the UTF-8 codecs into `base`: * Move them to GHC.Utils.Encoding.UTF8 * Make names more consistent * Add some Haddocks - - - - - e8ac91db by Ben Gamari at 2022-07-22T08:18:41-04:00 base: Introduce GHC.Encoding.UTF8 Here we copy a subset of the UTF-8 implementation living in `ghc-boot` into `base`, with the intent of dropping the former in the future. For this reason, the `ghc-boot` copy is now CPP-guarded on `MIN_VERSION_base(4,18,0)`. Naturally, we can't copy *all* of the functions defined by `ghc-boot` as some depend upon `bytestring`; we rather just copy those which only depend upon `base` and `ghc-prim`. Further consolidation? ---------------------- Currently GHC ships with at least five UTF-8 implementations: * the implementation used by GHC in `ghc-boot:GHC.Utils.Encoding`; this can be used at a number of types including `Addr#`, `ByteArray#`, `ForeignPtr`, `Ptr`, `ShortByteString`, and `ByteString`. Most of this can be removed in GHC 9.6+2, when the copies in `base` will become available to `ghc-boot`. * the copy of the `ghc-boot` definition now exported by `base:GHC.Encoding.UTF8`. This can be used at `Addr#`, `Ptr`, `ByteArray#`, and `ForeignPtr` * the decoder used by `unpackCStringUtf8#` in `ghc-prim:GHC.CString`; this is specialised at `Addr#`. * the codec used by the IO subsystem in `base:GHC.IO.Encoding.UTF8`; this is specialised at `Addr#` but, unlike the above, supports recovery in the presence of partial codepoints (since in IO contexts codepoints may be broken across buffers) * the implementation provided by the `text` library This does seem a tad silly. On the other hand, these implementations *do* materially differ from one another (e.g. in the types they support, the detail in errors they can report, and the ability to recover from partial codepoints). Consequently, it's quite unclear that further consolidate would be worthwhile. - - - - - f9ad8025 by Ben Gamari at 2022-07-22T08:18:41-04:00 Add a Note summarising GHC's UTF-8 implementations GHC has a somewhat dizzying array of UTF-8 implementations. This note describes why this is the case. - - - - - 72dfad3d by Ben Gamari at 2022-07-22T08:18:42-04:00 upload_ghc_libs: Fix path to documentation The documentation was moved in a10584e8df9b346cecf700b23187044742ce0b35 but this one occurrence was note updated. Finally closes #21164. - - - - - a8b150e7 by sheaf at 2022-07-22T08:18:44-04:00 Add test for #21871 This adds a test for #21871, which was fixed by the No Skolem Info rework (MR !7105). Fixes #21871 - - - - - 6379f942 by sheaf at 2022-07-22T08:18:46-04:00 Add test for #21360 The way record updates are typechecked/desugared changed in MR !7981. Because we desugar in the typechecker to a simple case expression, the pattern match checker becomes able to spot the long-distance information and avoid emitting an incorrect pattern match warning. Fixes #21360 - - - - - ce0cd12c by sheaf at 2022-07-22T08:18:47-04:00 Hadrian: don't try to build "unix" on Windows - - - - - dc27e15a by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Implement DeepSubsumption This MR adds the language extension -XDeepSubsumption, implementing GHC proposal #511. This change mitigates the impact of GHC proposal The changes are highly localised, by design. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. The main changes are: * Add -XDeepSubsumption, which is on by default in Haskell98 and Haskell2010, but off in Haskell2021. -XDeepSubsumption largely restores the behaviour before the "simple subsumption" change. -XDeepSubsumpition has a similar flavour as -XNoMonoLocalBinds: it makes type inference more complicated and less predictable, but it may be convenient in practice. * The main changes are in: * GHC.Tc.Utils.Unify.tcSubType, which does deep susumption and eta-expanansion * GHC.Tc.Utils.Unify.tcSkolemiseET, which does deep skolemisation * In GHC.Tc.Gen.App.tcApp we call tcSubTypeNC to match the result type. Without deep subsumption, unifyExpectedType would be sufficent. See Note [Deep subsumption] in GHC.Tc.Utils.Unify. * There are no changes to Quick Look at all. * The type of `withDict` becomes ambiguous; so add -XAllowAmbiguousTypes to GHC.Magic.Dict * I fixed a small but egregious bug in GHC.Core.FVs.varTypeTyCoFVs, where we'd forgotten to take the free vars of the multiplicity of an Id. * I also had to fix tcSplitNestedSigmaTys When I did the shallow-subsumption patch commit 2b792facab46f7cdd09d12e79499f4e0dcd4293f Date: Sun Feb 2 18:23:11 2020 +0000 Simple subsumption I changed tcSplitNestedSigmaTys to not look through function arrows any more. But that was actually an un-forced change. This function is used only in * Improving error messages in GHC.Tc.Gen.Head.addFunResCtxt * Validity checking for default methods: GHC.Tc.TyCl.checkValidClass * A couple of calls in the GHCi debugger: GHC.Runtime.Heap.Inspect All to do with validity checking and error messages. Acutally its fine to look under function arrows here, and quite useful a test DeepSubsumption05 (a test motivated by a build failure in the `lens` package) shows. The fix is easy. I added Note [tcSplitNestedSigmaTys]. - - - - - e31ead39 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add tests that -XHaskell98 and -XHaskell2010 enable DeepSubsumption - - - - - 67189985 by Matthew Pickering at 2022-07-25T09:42:01-04:00 Add DeepSubsumption08 - - - - - 5e93a952 by Simon Peyton Jones at 2022-07-25T09:42:01-04:00 Fix the interaction of operator sections and deep subsumption Fixes DeepSubsumption08 - - - - - 918620d9 by Zubin Duggal at 2022-07-25T09:42:01-04:00 Add DeepSubsumption09 - - - - - 2a773259 by Gabriella Gonzalez at 2022-07-25T09:42:40-04:00 Default implementation for mempty/(<>) Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances. - - - - - 73836fc8 by Bryan Richter at 2022-07-25T09:43:16-04:00 ci: Disable (broken) perf-nofib See #21859 - - - - - c24ca5c3 by sheaf at 2022-07-25T09:43:58-04:00 Docs: clarify ConstraintKinds infelicity GHC doesn't consistently require the ConstraintKinds extension to be enabled, as it allows programs such as type families returning a constraint without this extension. MR !7784 fixes this infelicity, but breaking user programs was deemed to not be worth it, so we document it instead. Fixes #21061. - - - - - 5f2fbd5e by Simon Peyton Jones at 2022-07-25T09:44:34-04:00 More improvements to worker/wrapper This patch fixes #21888, and simplifies finaliseArgBoxities by eliminating the (recently introduced) data type FinalDecision. A delicate interaction meant that this patch commit d1c25a48154236861a413e058ea38d1b8320273f Date: Tue Jul 12 16:33:46 2022 +0100 Refactor wantToUnboxArg a bit make worker/wrapper go into an infinite loop. This patch fixes it by narrowing the handling of case (B) of Note [Boxity for bottoming functions], to deal only the arguemnts that are type variables. Only then do we drop the trimBoxity call, which is what caused the bug. I also * Added documentation of case (B), which was previously completely un-mentioned. And a regression test, T21888a, to test it. * Made unboxDeeplyDmd stop at lazy demands. It's rare anyway for a bottoming function to have a lazy argument (mainly when the data type is recursive and then we don't want to unbox deeply). Plus there is Note [No lazy, Unboxed demands in demand signature] * Refactored the Case equation for dmdAnal a bit, to do less redundant pattern matching. - - - - - b77d95f8 by Simon Peyton Jones at 2022-07-25T09:45:09-04:00 Fix a small buglet in tryEtaReduce Gergo points out (#21801) that GHC.Core.Opt.Arity.tryEtaReduce was making an ill-formed cast. It didn't matter, because the subsequent guard discarded it; but still worth fixing. Spurious warnings are distracting. - - - - - 3bbde957 by Zubin Duggal at 2022-07-25T09:45:45-04:00 Fix #21889, GHCi misbehaves with Ctrl-C on Windows On Windows, we create multiple levels of wrappers for GHCi which ultimately execute ghc --interactive. In order to handle console events properly, each of these wrappers must call FreeConsole() in order to hand off event processing to the child process. See #14150. In addition to this, FreeConsole must only be called from interactive processes (#13411). This commit makes two changes to fix this situation: 1. The hadrian wrappers generated using `hadrian/bindist/cwrappers/version-wrapper.c` call `FreeConsole` if the CPP flag INTERACTIVE_PROCESS is set, which is set when we are generating a wrapper for GHCi. 2. The GHCi wrapper in `driver/ghci/` calls the `ghc-$VER.exe` executable which is not wrapped rather than calling `ghc.exe` is is wrapped on windows (and usually non-interactive, so can't call `FreeConsole`: Before: ghci-$VER.exe calls ghci.exe which calls ghc.exe which calls ghc-$VER.exe After: ghci-$VER.exe calls ghci.exe which calls ghc-$VER.exe - - - - - 79f1b021 by Simon Jakobi at 2022-07-25T09:46:21-04:00 docs: Fix documentation of \cases Fixes #21902. - - - - - e4bf9592 by sternenseemann at 2022-07-25T09:47:01-04:00 ghc-cabal: allow Cabal 3.8 to unbreak make build When bootstrapping GHC 9.4.*, the build will fail when configuring ghc-cabal as part of the make based build system due to this upper bound, as Cabal has been updated to a 3.8 release. Reference #21914, see especially https://gitlab.haskell.org/ghc/ghc/-/issues/21914#note_444699 - - - - - 726d938e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Fix isEvaldUnfolding and isValueUnfolding This fixes (1) in #21831. Easy, obviously correct. - - - - - 5d26c321 by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Switch off eta-expansion in rules and unfoldings I think this change will make little difference except to reduce clutter. But that's it -- if it causes problems we can switch it on again. - - - - - d4fe2f4e by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Teach SpecConstr about typeDeterminesValue This patch addresses #21831, point 2. See Note [generaliseDictPats] in SpecConstr I took the opportunity to refactor the construction of specialisation rules a bit, so that the rule name says what type we are specialising at. Surprisingly, there's a 20% decrease in compile time for test perf/compiler/T18223. I took a look at it, and the code size seems the same throughout. I did a quick ticky profile which seemed to show a bit less substitution going on. Hmm. Maybe it's the "don't do eta-expansion in stable unfoldings" patch, which is part of the same MR as this patch. Anyway, since it's a move in the right direction, I didn't think it was worth looking into further. Metric Decrease: T18223 - - - - - 65f7838a by Simon Peyton Jones at 2022-07-25T14:38:14-04:00 Add a 'notes' file in testsuite/tests/perf/compiler This file is just a place to accumlate notes about particular benchmarks, so that I don't keep re-inventing the wheel. - - - - - 61faff40 by Simon Peyton Jones at 2022-07-25T14:38:50-04:00 Get the in-scope set right in FamInstEnv.injectiveBranches There was an assert error, as Gergo pointed out in #21896. I fixed this by adding an InScopeSet argument to tcUnifyTyWithTFs. And also to GHC.Core.Unify.niFixTCvSubst. I also took the opportunity to get a couple more InScopeSets right, and to change some substTyUnchecked into substTy. This MR touches a lot of other files, but only because I also took the opportunity to introduce mkInScopeSetList, and use it. - - - - - 4a7256a7 by Cheng Shao at 2022-07-25T20:41:55+00:00 Add location to cc phase - - - - - 96811ba4 by Cheng Shao at 2022-07-25T20:41:55+00:00 Avoid as pipeline when compiling c - - - - - 2869b66d by Cheng Shao at 2022-07-25T20:42:20+00:00 testsuite: Skip test cases involving -S when testing unregisterised GHC We no longer generate .s files anyway. Metric Decrease: MultiLayerModules T10421 T13035 T13701 T14697 T16875 T18140 T18304 T18923 T9198 - - - - - 82a0991a by Ben Gamari at 2022-07-25T23:32:05-04:00 testsuite: introduce nonmoving_thread_sanity way (cherry picked from commit 19f8fce3659de3d72046bea9c61d1a82904bc4ae) - - - - - 4b087973 by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Track segment state It can often be useful during debugging to be able to determine the state of a nonmoving segment. Introduce some state, enabled by DEBUG, to track this. (cherry picked from commit 40e797ef591ae3122ccc98ab0cc3cfcf9d17bd7f) - - - - - 54a5c32d by Ben Gamari at 2022-07-25T23:32:06-04:00 rts/nonmoving: Don't scavenge objects which weren't evacuated This fixes a rather subtle bug in the logic responsible for scavenging objects evacuated to the non-moving generation. In particular, objects can be allocated into the non-moving generation by two ways: a. evacuation out of from-space by the garbage collector b. direct allocation by the mutator Like all evacuation, objects moved by (a) must be scavenged, since they may contain references to other objects located in from-space. To accomplish this we have the following scheme: * each nonmoving segment's block descriptor has a scan pointer which points to the first object which has yet to be scavenged * the GC tracks a set of "todo" segments which have pending scavenging work * to scavenge a segment, we scavenge each of the unmarked blocks between the scan pointer and segment's `next_free` pointer. We skip marked blocks since we know the allocator wouldn't have allocated into marked blocks (since they contain presumably live data). We can stop at `next_free` since, by definition, the GC could not have evacuated any objects to blocks above `next_free` (otherwise `next_free wouldn't be the first free block). However, this neglected to consider objects allocated by path (b). In short, the problem is that objects directly allocated by the mutator may become unreachable (but not swept, since the containing segment is not yet full), at which point they may contain references to swept objects. Specifically, we observed this in #21885 in the following way: 1. the mutator (specifically in #21885, a `lockCAF`) allocates an object (specifically a blackhole, which here we will call `blkh`; see Note [Static objects under the nonmoving collector] for the reason why) on the non-moving heap. The bitmap of the allocated block remains 0 (since allocation doesn't affect the bitmap) and the containing segment's (which we will call `blkh_seg`) `next_free` is advanced. 2. We enter the blackhole, evaluating the blackhole to produce a result (specificaly a cons cell) in the nursery 3. The blackhole gets updated into an indirection pointing to the cons cell; it is pushed to the generational remembered set 4. we perform a GC, the cons cell is evacuated into the nonmoving heap (into segment `cons_seg`) 5. the cons cell is marked 6. the GC concludes 7. the CAF and blackhole become unreachable 8. `cons_seg` is filled 9. we start another GC; the cons cell is swept 10. we start a new GC 11. something is evacuated into `blkh_seg`, adding it to the "todo" list 12. we attempt to scavenge `blkh_seg` (namely, all unmarked blocks between `scan` and `next_free`, which includes `blkh`). We attempt to evacuate `blkh`'s indirectee, which is the previously-swept cons cell. This is unsafe, since the indirectee is no longer a valid heap object. The problem here was that the scavenging logic *assumed* that (a) was the only source of allocations into the non-moving heap and therefore *all* unmarked blocks between `scan` and `next_free` were evacuated. However, due to (b) this is not true. The solution is to ensure that that the scanned region only encompasses the region of objects allocated during evacuation. We do this by updating `scan` as we push the segment to the todo-segment list to point to the block which was evacuated into. Doing this required changing the nonmoving scavenging implementation's update of the `scan` pointer to bump it *once*, instead of after scavenging each block as was done previously. This is because we may end up evacuating into the segment being scavenged as we scavenge it. This was quite tricky to discover but the result is quite simple, demonstrating yet again that global mutable state should be used exceedingly sparingly. Fixes #21885 (cherry picked from commit 0b27ea23efcb08639309293faf13fdfef03f1060) - - - - - 25c24535 by Ben Gamari at 2022-07-25T23:32:06-04:00 testsuite: Skip a few tests as in the nonmoving collector Residency monitoring under the non-moving collector is quite conservative (e.g. the reported value is larger than reality) since otherwise we would need to block on concurrent collection. Skip a few tests that are sensitive to residency. (cherry picked from commit 6880e4fbf728c04e8ce83e725bfc028fcb18cd70) - - - - - 42147534 by sternenseemann at 2022-07-26T16:26:53-04:00 hadrian: add flag disabling selftest rules which require QuickCheck The hadrian executable depends on QuickCheck for building, meaning this library (and its dependencies) will need to be built for bootstrapping GHC in the future. Building QuickCheck, however, can require TemplateHaskell. When building a statically linking GHC toolchain, TemplateHaskell can be tricky to get to work, and cross-compiling TemplateHaskell doesn't work at all without -fexternal-interpreter, so QuickCheck introduces an element of fragility to GHC's bootstrap. Since the selftest rules are the only part of hadrian that need QuickCheck, we can easily eliminate this bootstrap dependency when required by introducing a `selftest` flag guarding the rules' inclusion. Closes #8699. - - - - - 9ea29d47 by Simon Peyton Jones at 2022-07-26T16:27:28-04:00 Regression test for #21848 - - - - - ef30e215 by Matthew Pickering at 2022-07-28T13:56:59-04:00 driver: Don't create LinkNodes when -no-link is enabled Fixes #21866 - - - - - fc23b5ed by sheaf at 2022-07-28T13:57:38-04:00 Docs: fix mistaken claim about kind signatures This patch fixes #21806 by rectifying an incorrect claim about the usage of kind variables in the header of a data declaration with a standalone kind signature. It also adds some clarifications about the number of parameters expected in GADT declarations and in type family declarations. - - - - - 2df92ee1 by Matthew Pickering at 2022-08-02T05:20:01-04:00 testsuite: Correctly set withNativeCodeGen Fixes #21918 - - - - - f2912143 by Matthew Pickering at 2022-08-02T05:20:45-04:00 Fix since annotations in GHC.Stack.CloneStack Fixes #21894 - - - - - aeb8497d by Andreas Klebinger at 2022-08-02T19:26:51-04:00 Add -dsuppress-coercion-types to make coercions even smaller. Instead of `` `cast` <Co:11> :: (Some -> Really -> Large Type)`` simply print `` `cast` <Co:11> :: ... `` - - - - - 97655ad8 by sheaf at 2022-08-02T19:27:29-04:00 User's guide: fix typo in hasfield.rst Fixes #21950 - - - - - 35aef18d by Yiyun Liu at 2022-08-04T02:55:07-04:00 Remove TCvSubst and use Subst for both term and type-level subst This patch removes the TCvSubst data type and instead uses Subst as the environment for both term and type level substitution. This change is partially motivated by the existential type proposal, which will introduce types that contain expressions and therefore forces us to carry around an "IdSubstEnv" even when substituting for types. It also reduces the amount of code because "Subst" and "TCvSubst" share a lot of common operations. There isn't any noticeable impact on performance (geo. mean for ghc/alloc is around 0.0% but we have -94 loc and one less data type to worry abount). Currently, the "TCvSubst" data type for substitution on types is identical to the "Subst" data type except the former doesn't store "IdSubstEnv". Using "Subst" for type-level substitution means there will be a redundant field stored in the data type. However, in cases where the substitution starts from the expression, using "Subst" for type-level substitution saves us from having to project "Subst" into a "TCvSubst". This probably explains why the allocation is mostly even despite the redundant field. The patch deletes "TCvSubst" and moves "Subst" and its relevant functions from "GHC.Core.Subst" into "GHC.Core.TyCo.Subst". Substitution on expressions is still defined in "GHC.Core.Subst" so we don't have to expose the definition of "Expr" in the hs-boot file that "GHC.Core.TyCo.Subst" must import to refer to "IdSubstEnv" (whose codomain is "CoreExpr"). Most functions named fooTCvSubst are renamed into fooSubst with a few exceptions (e.g. "isEmptyTCvSubst" is a distinct function from "isEmptySubst"; the former ignores the emptiness of "IdSubstEnv"). These exceptions mainly exist for performance reasons and will go away when "Expr" and "Type" are mutually recursively defined (we won't be able to take those shortcuts if we can't make the assumption that expressions don't appear in types). - - - - - b99819bd by Krzysztof Gogolewski at 2022-08-04T02:55:43-04:00 Fix TH + defer-type-errors interaction (#21920) Previously, we had to disable defer-type-errors in splices because of #7276. But this fix is no longer necessary, the test T7276 no longer segfaults and is now correctly deferred. - - - - - fb529cae by Andreas Klebinger at 2022-08-04T13:57:25-04:00 Add a note about about W/W for unlifting strict arguments This fixes #21236. - - - - - fffc75a9 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force safeInferred to avoid retaining extra copy of DynFlags This will only have a (very) modest impact on memory but we don't want to retain old copies of DynFlags hanging around so best to force this value. - - - - - 0f43837f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Force name selectors to ensure no reference to Ids enter the NameCache I observed some unforced thunks in the NameCache which were retaining a whole Id, which ends up retaining a Type.. which ends up retaining old copies of HscEnv containing stale HomeModInfo. - - - - - 0b1f5fd1 by Matthew Pickering at 2022-08-04T13:58:01-04:00 Fix leaks in --make mode when there are module loops This patch fixes quite a tricky leak where we would end up retaining stale ModDetails due to rehydrating modules against non-finalised interfaces. == Loops with multiple boot files It is possible for a module graph to have a loop (SCC, when ignoring boot files) which requires multiple boot files to break. In this case we must perform the necessary hydration steps before and after compiling modules which have boot files which are described above for corectness but also perform an additional hydration step at the end of the SCC to remove space leaks. Consider the following example: ┌───────┐ ┌───────┐ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────┬─┘ └───┬───┘ │ │ ┌────▼─────────▼──┐ │ │ │ C │ └────┬─────────┬──┘ │ │ ┌────▼──┐ ┌───▼───┐ │ │ │ │ │ A-boot│ │ B-boot│ │ │ │ │ └───────┘ └───────┘ A, B and C live together in a SCC. Say we compile the modules in order A-boot, B-boot, C, A, B then when we compile A we will perform the hydration steps (because A has a boot file). Therefore C will be hydrated relative to A, and the ModDetails for A will reference C/A. Then when B is compiled C will be rehydrated again, and so B will reference C/A,B, its interface will be hydrated relative to both A and B. Now there is a space leak because say C is a very big module, there are now two different copies of ModDetails kept alive by modules A and B. The way to avoid this space leak is to rehydrate an entire SCC together at the end of compilation so that all the ModDetails point to interfaces for .hs files. In this example, when we hydrate A, B and C together then both A and B will refer to C/A,B. See #21900 for some more discussion. ------------------------------------------------------- In addition to this simple case, there is also the potential for a leak during parallel upsweep which is also fixed by this patch. Transcibed is Note [ModuleNameSet, efficiency and space leaks] Note [ModuleNameSet, efficiency and space leaks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ During unsweep the results of compiling modules are placed into a MVar, to find the environment the module needs to compile itself in the MVar is consulted and the HomeUnitGraph is set accordingly. The reason we do this is that precisely tracking module dependencies and recreating the HUG from scratch each time is very expensive. In serial mode (-j1), this all works out fine because a module can only be compiled after its dependencies have finished compiling and not interleaved with compiling module loops. Therefore when we create the finalised or no loop interfaces, the HUG only contains finalised interfaces. In parallel mode, we have to be more careful because the HUG variable can contain non-finalised interfaces which have been started by another thread. In order to avoid a space leak where a finalised interface is compiled against a HPT which contains a non-finalised interface we have to restrict the HUG to only the visible modules. The visible modules is recording in the ModuleNameSet, this is propagated upwards whilst compiling and explains which transitive modules are visible from a certain point. This set is then used to restrict the HUG before the module is compiled to only the visible modules and thus avoiding this tricky space leak. Efficiency of the ModuleNameSet is of utmost importance because a union occurs for each edge in the module graph. Therefore the set is represented directly as an IntSet which provides suitable performance, even using a UniqSet (which is backed by an IntMap) is too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. See test "jspace" for an example which used to trigger this problem. Fixes #21900 - - - - - 1d94a59f by Matthew Pickering at 2022-08-04T13:58:01-04:00 Store interfaces in ModIfaceCache more directly I realised hydration was completely irrelavant for this cache because the ModDetails are pruned from the result. So now it simplifies things a lot to just store the ModIface and Linkable, which we can put into the cache straight away rather than wait for the final version of a HomeModInfo to appear. - - - - - 6c7cd50f by Cheng Shao at 2022-08-04T23:01:45-04:00 cmm: Remove unused ReadOnlyData16 We don't actually emit rodata16 sections anywhere. - - - - - 16333ad7 by Andreas Klebinger at 2022-08-04T23:02:20-04:00 findExternalRules: Don't needlessly traverse the list of rules. - - - - - 52c15674 by Krzysztof Gogolewski at 2022-08-05T12:47:05-04:00 Remove backported items from 9.6 release notes They have been backported to 9.4 in commits 5423d84bd9a28f, 13c81cb6be95c5, 67ccbd6b2d4b9b. - - - - - 78d232f5 by Matthew Pickering at 2022-08-05T12:47:40-04:00 ci: Fix pages job The job has been failing because we don't bundle haddock docs anymore in the docs dist created by hadrian. Fixes #21789 - - - - - 037bc9c9 by Ben Gamari at 2022-08-05T22:00:29-04:00 codeGen/X86: Don't clobber switch variable in switch generation Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968. - - - - - 50c8e1c5 by Matthew Pickering at 2022-08-05T22:01:04-04:00 Fix equality operator in jspace test - - - - - e9c77a22 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Improve BUILD_PAP comments - - - - - 41234147 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Make dropTail comment a haddock comment - - - - - ff11d579 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Add one more sanity check in stg_restore_cccs - - - - - 1f6c56ae by Andreas Klebinger at 2022-08-06T06:13:17-04:00 StgToCmm: Fix isSimpleScrut when profiling is enabled. When profiling is enabled we must enter functions that might represent thunks in order for their sccs to show up in the profile. We might allocate even if the function is already evaluated in this case. So we can't consider any potential function thunk to be a simple scrut when profiling. Not doing so caused profiled binaries to segfault. - - - - - fab0ee93 by Andreas Klebinger at 2022-08-06T06:13:17-04:00 Change `-fprof-late` to insert cost centres after unfolding creation. The former behaviour of adding cost centres after optimization but before unfoldings are created is not available via the flag `prof-late-inline` instead. I also reduced the overhead of -fprof-late* by pushing the cost centres into lambdas. This means the cost centres will only account for execution of functions and not their partial application. Further I made LATE_CC cost centres it's own CC flavour so they now won't clash with user defined ones if a user uses the same string for a custom scc. LateCC: Don't put cost centres inside constructor workers. With -fprof-late they are rarely useful as the worker is usually inlined. Even if the worker is not inlined or we use -fprof-late-linline they are generally not helpful but bloat compile and run time significantly. So we just don't add sccs inside constructor workers. ------------------------- Metric Decrease: T13701 ------------------------- - - - - - f8bec4e3 by Ben Gamari at 2022-08-06T06:13:53-04:00 gitlab-ci: Fix hadrian bootstrapping of release pipelines Previously we would attempt to test hadrian bootstrapping in the `validate` build flavour. However, `ci.sh` refuses to run validation builds during release pipelines, resulting in job failures. Fix this by testing bootstrapping in the `release` flavour during release pipelines. We also attempted to record perf notes for these builds, which is redundant work and undesirable now since we no longer build in a consistent flavour. - - - - - c0348865 by Ben Gamari at 2022-08-06T11:45:17-04:00 compiler: Eliminate two uses of foldr in favor of foldl' These two uses constructed maps, which is a case where foldl' is generally more efficient since we avoid constructing an intermediate O(n)-depth stack. - - - - - d2e4e123 by Ben Gamari at 2022-08-06T11:45:17-04:00 rts: Fix code style - - - - - 57f530d3 by Ben Gamari at 2022-08-06T11:45:17-04:00 genprimopcode: Drop ArrayArray# references As ArrayArray# no longer exists - - - - - 7267cd52 by Ben Gamari at 2022-08-06T11:45:17-04:00 base: Organize Haddocks in GHC.Conc.Sync - - - - - aa818a9f by Ben Gamari at 2022-08-06T11:48:50-04:00 Add primop to list threads A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads. - - - - - 6d1700b6 by Ben Gamari at 2022-08-06T11:51:35-04:00 rts: Move thread labels into TSO This eliminates the thread label HashTable and instead tracks this information in the TSO, allowing us to use proper StgArrBytes arrays for backing the label and greatly simplifying management of object lifetimes when we expose them to the user with the coming `threadLabel#` primop. - - - - - 1472044b by Ben Gamari at 2022-08-06T11:54:52-04:00 Add a primop to query the label of a thread - - - - - 43f2b271 by Ben Gamari at 2022-08-06T11:55:14-04:00 base: Share finalization thread label For efficiency's sake we float the thread label assigned to the finalization thread to the top-level, ensuring that we only need to encode the label once. - - - - - 1d63b4fb by Ben Gamari at 2022-08-06T11:57:11-04:00 users-guide: Add release notes entry for thread introspection support - - - - - 09bca1de by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix binary distribution install attributes Previously we would use plain `cp` to install various parts of the binary distribution. However, `cp`'s behavior w.r.t. file attributes is quite unclear; for this reason it is much better to rather use `install`. Fixes #21965. - - - - - 2b8ea16d by Ben Gamari at 2022-08-07T01:19:35-04:00 hadrian: Fix installation of system-cxx-std-lib package conf - - - - - 7b514848 by Ben Gamari at 2022-08-07T01:20:10-04:00 gitlab-ci: Bump Docker images To give the ARMv7 job access to lld, fixing #21875. - - - - - afa584a3 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Don't use mk/config.mk.in Ultimately we want to drop mk/config.mk so here I extract the bits needed by the Hadrian bindist installation logic into a Hadrian-specific file. While doing this I fixed binary distribution installation, #21901. - - - - - b9bb45d7 by Ben Gamari at 2022-08-07T05:08:52-04:00 hadrian: Fix naming of cross-compiler wrappers - - - - - 78d04cfa by Ben Gamari at 2022-08-07T11:44:58-04:00 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. - - - - - 20457d77 by Andreas Klebinger at 2022-08-08T14:42:26+02:00 NCG(x86): Compile add+shift as lea if possible. - - - - - 742292e4 by Andreas Klebinger at 2022-08-08T16:46:37-04:00 dataToTag#: Skip runtime tag check if argument is infered tagged This addresses one part of #21710. - - - - - 1504a93e by Cheng Shao at 2022-08-08T16:47:14-04:00 rts: remove redundant stg_traceCcszh This out-of-line primop has no Haskell wrapper and hasn't been used anywhere in the tree. Furthermore, the code gets in the way of !7632, so it should be garbage collected. - - - - - a52de3cb by Andreas Klebinger at 2022-08-08T16:47:50-04:00 Document a divergence from the report in parsing function lhss. GHC is happy to parse `(f) x y = x + y` when it should be a parse error based on the Haskell report. Seems harmless enough so we won't fix it but it's documented now. Fixes #19788 - - - - - 5765e133 by Ben Gamari at 2022-08-08T16:48:25-04:00 gitlab-ci: Add release job for aarch64/debian 11 - - - - - 5b26f324 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Introduce validation job for aarch64 cross-compilation Begins to address #11958. - - - - - e866625c by Ben Gamari at 2022-08-08T19:39:20-04:00 Bump process submodule - - - - - ae707762 by Ben Gamari at 2022-08-08T19:39:20-04:00 gitlab-ci: Add basic support for cross-compiler testiing Here we add a simple qemu-based test for cross-compilers. - - - - - 50912d68 by Ben Gamari at 2022-08-08T19:39:57-04:00 rts: Ensure that Array# card arrays are initialized In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143. - - - - - e5ceff56 by Ben Gamari at 2022-08-08T19:39:57-04:00 testsuite: Add test for #21962 - - - - - c1c08bd8 by Ben Gamari at 2022-08-09T02:31:14-04:00 gitlab-ci: Don't use coreutils on Darwin In general we want to ensure that the tested environment is as similar as possible to the environment the user will use. In the case of Darwin, this means we want to use the system's BSD command-line utilities, not coreutils. This would have caught #21974. - - - - - 1c582f44 by Ben Gamari at 2022-08-09T02:31:14-04:00 hadrian: Fix bindist installation on Darwin It turns out that `cp -P` on Darwin does not always copy a symlink as a symlink. In order to get these semantics one must pass `-RP`. It's not entirely clear whether this is valid under POSIX, but it is nevertheless what Apple does. - - - - - 681aa076 by Ben Gamari at 2022-08-09T02:31:49-04:00 hadrian: Fix access mode of installed package registration files Previously hadrian's bindist Makefile would modify package registrations placed by `install` via a shell pipeline and `mv`. However, the use of `mv` means that if umask is set then the user may otherwise end up with package registrations which are inaccessible. Fix this by ensuring that the mode is 0644. - - - - - e9dfd26a by Krzysztof Gogolewski at 2022-08-09T02:32:24-04:00 Cleanups around pretty-printing * Remove hack when printing OccNames. No longer needed since e3dcc0d5 * Remove unused `pprCmms` and `instance Outputable Instr` * Simplify `pprCLabel` (no need to pass platform) * Remove evil `Show`/`Eq` instances for `SDoc`. They were needed by ImmLit, but that can take just a String instead. * Remove instance `Outputable CLabel` - proper output of labels needs a platform, and is done by the `OutputableP` instance - - - - - 66d2e927 by Ben Gamari at 2022-08-09T13:46:48-04:00 rts/linker: Resolve iconv_* on FreeBSD FreeBSD's libiconv includes an implementation of the iconv_* functions in libc. Unfortunately these can only be resolved using dlvsym, which is how the RTS linker usually resolves such functions. To fix this we include an ad-hoc special case for iconv_*. Fixes #20354. - - - - - 5d66a0ce by Ben Gamari at 2022-08-09T13:46:48-04:00 system-cxx-std-lib: Add support for FreeBSD libcxxrt - - - - - ea90e61d by Ben Gamari at 2022-08-09T13:46:48-04:00 gitlab-ci: Bump to use freebsd13 runners - - - - - d71a2051 by sheaf at 2022-08-09T13:47:28-04:00 Fix size_up_alloc to account for UnliftedDatatypes The size_up_alloc function mistakenly considered any type that isn't lifted to not allocate anything, which is wrong. What we want instead is to check the type isn't boxed. This accounts for (BoxedRep Unlifted). Fixes #21939 - - - - - 76b52cf0 by Douglas Wilson at 2022-08-10T06:01:53-04:00 testsuite: 21651 add test for closeFdWith + setNumCapabilities This bug does not affect windows, which does not use the base module GHC.Event.Thread. - - - - - 7589ee72 by Douglas Wilson at 2022-08-10T06:01:53-04:00 base: Fix races in IOManager (setNumCapabilities,closeFdWith) Fix for #21651 Fixes three bugs: - writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith. - The race in closeFdWith described in the ticket. - A race in getSystemEventManager where it accesses the 'IOArray' in 'eventManager' before 'ioManagerCapabilitiesChanged' has written to 'eventManager', causing an Array Index exception. The fix here is to 'yield' and retry. - - - - - dc76439d by Trevis Elser at 2022-08-10T06:02:28-04:00 Updates language extension documentation Adding a 'Status' field with a few values: - Deprecated - Experimental - InternalUseOnly - Noting if included in 'GHC2021', 'Haskell2010' or 'Haskell98' Those values are pulled from the existing descriptions or elsewhere in the documentation. While at it, include the :implied by: where appropriate, to provide more detail. Fixes #21475 - - - - - 823fe5b5 by Jens Petersen at 2022-08-10T06:03:07-04:00 hadrian RunRest: add type signature for stageNumber avoids warning seen on 9.4.1: src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults] • Defaulting the following constraints to type ‘Integer’ (Show a0) arising from a use of ‘show’ at src/Settings/Builders/RunTest.hs:264:53-84 (Num a0) arising from a use of ‘stageNumber’ at src/Settings/Builders/RunTest.hs:264:59-83 • In the second argument of ‘(++)’, namely ‘show (stageNumber (C.stage ctx))’ In the second argument of ‘($)’, namely ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’ In the expression: arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | 264 | , arg "-e", arg $ "config.stage=" ++ show (stageNumber (C.stage ctx)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compilation tested locally - - - - - f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00 Add support for external static plugins (#20964) This patch adds a new command-line flag: -fplugin-library=<file-path>;<unit-id>;<module>;<args> used like this: -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"] It allows a plugin to be loaded directly from a shared library. With this approach, GHC doesn't compile anything for the plugin and doesn't load any .hi file for the plugin and its dependencies. As such GHC doesn't need to support two environments (one for plugins, one for target code), which was the more ambitious approach tracked in #14335. Fix #20964 Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Fix ARMv7 build It appears that the CI refactoring carried out in 5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some critical configuration: setting the build/host/target platforms and forcing use of a non-broken linker. - - - - - 596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00 gitlab-ci: Run ARMv7 jobs when ~ARM label is used - - - - - 7cabea7c by Ben Gamari at 2022-08-10T15:37:58-04:00 hadrian: Don't attempt to install documentation if doc/ doesn't exist Previously we would attempt to install documentation even if the `doc` directory doesn't exist (e.g. due to `--docs=none`). This would result in the surprising side-effect of the entire contents of the bindist being installed in the destination documentation directory. Fix this. Fixes #21976. - - - - - 67575f20 by normalcoder at 2022-08-10T15:38:34-04:00 ncg/aarch64: Don't use x18 register on AArch64/Darwin Apple's ABI documentation [1] says: "The platforms reserve register x18. Don’t use this register." While this wasn't problematic in previous Darwin releases, macOS 13 appears to start zeroing this register periodically. See #21964. [1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms - - - - - 45eb4cbe by Andreas Klebinger at 2022-08-10T22:41:12-04:00 Note [Trimming auto-rules]: State that this improves compiler perf. - - - - - 5c24b1b3 by Bodigrim at 2022-08-10T22:41:50-04:00 Document that threadDelay / timeout are susceptible to overflows on 32-bit machines - - - - - ff67c79e by Alan Zimmerman at 2022-08-11T16:19:57-04:00 EPA: DotFieldOcc does not have exact print annotations For the code {-# LANGUAGE OverloadedRecordUpdate #-} operatorUpdate f = f{(+) = 1} There are no exact print annotations for the parens around the + symbol, nor does normal ppr print them. This MR fixes that. Closes #21805 Updates haddock submodule - - - - - dca43a04 by Matthew Pickering at 2022-08-11T16:20:33-04:00 Revert "gitlab-ci: Add release job for aarch64/debian 11" This reverts commit 5765e13370634979eb6a0d9f67aa9afa797bee46. The job was not tested before being merged and fails CI (https://gitlab.haskell.org/ghc/ghc/-/jobs/1139392) Ticket #22005 - - - - - ffc9116e by Eric Lindblad at 2022-08-16T09:01:26-04:00 typo - - - - - cd6f5bfd by Ben Gamari at 2022-08-16T09:02:02-04:00 CmmToLlvm: Don't aliasify builtin LLVM variables Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019. - - - - - dc7da356 by Bryan Richter at 2022-08-16T09:02:38-04:00 run_ci: remove monoidal-containers Fixes #21492 MonoidalMap is inlined and used to implement Variables, as before. The top-level value "jobs" is reimplemented as a regular Map, since it doesn't use the monoidal union anyway. - - - - - 64110544 by Cheng Shao at 2022-08-16T09:03:15-04:00 CmmToAsm/AArch64: correct a typo - - - - - f6a5524a by Andreas Klebinger at 2022-08-16T14:34:11-04:00 Fix #21979 - compact-share failing with -O I don't have good reason to believe the optimization level should affect if sharing works or not here. So limit the test to the normal way. - - - - - 68154a9d by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix reference to dead llvm-version substitution Fixes #22052. - - - - - 28c60d26 by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Fix incorrect reference to `:extension: role - - - - - 71102c8f by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Add :ghc-flag: reference - - - - - 385f420b by Ben Gamari at 2022-08-16T14:34:47-04:00 hadrian: Place manpage in docroot This relocates it from docs/ to doc/ - - - - - 84598f2e by Ben Gamari at 2022-08-16T14:34:47-04:00 Bump haddock submodule Includes merge of `main` into `ghc-head` as well as some Haddock users guide fixes. - - - - - 59ce787c by Ben Gamari at 2022-08-16T14:34:47-04:00 base: Add changelog entries from ghc-9.2 Closes #21922. - - - - - a14e6ae3 by Ben Gamari at 2022-08-16T14:34:47-04:00 relnotes: Add "included libraries" section As noted in #21988, some users rely on this. - - - - - a4212edc by Ben Gamari at 2022-08-16T14:34:47-04:00 users-guide: Rephrase the rewrite rule documentation Previously the wording was a tad unclear. Fix this. Closes #21114. - - - - - 3e493dfd by Peter Becich at 2022-08-17T08:43:21+01:00 Implement Response File support for HPC This is an improvement to HPC authored by Richard Wallace (https://github.com/purefn) and myself. I have received permission from him to attempt to upstream it. This improvement was originally implemented as a patch to HPC via input-output-hk/haskell.nix: https://github.com/input-output-hk/haskell.nix/pull/1464 Paraphrasing Richard, HPC currently requires all inputs as command line arguments. With large projects this can result in an argument list too long error. I have only seen this error in Nix, but I assume it can occur is a plain Unix environment. This MR adds the standard response file syntax support to HPC. For example you can now pass a file to the command line which contains the arguments. ``` hpc @response_file_1 @response_file_2 ... The contents of a Response File must have this format: COMMAND ... example: report my_library.tix --include=ModuleA --include=ModuleB ``` Updates hpc submodule Co-authored-by: Richard Wallace <rwallace at thewallacepack.net> Fixes #22050 - - - - - 436867d6 by Matthew Pickering at 2022-08-18T09:24:08-04:00 ghc-heap: Fix decoding of TSO closures An extra field was added to the TSO structure in 6d1700b6 but the decoding logic in ghc-heap was not updated for this new field. Fixes #22046 - - - - - a740a4c5 by Matthew Pickering at 2022-08-18T09:24:44-04:00 driver: Honour -x option The -x option is used to manually specify which phase a file should be started to be compiled from (even if it lacks the correct extension). I just failed to implement this when refactoring the driver. In particular Cabal calls GHC with `-E -cpp -x hs Foo.cpphs` to preprocess source files using GHC. I added a test to exercise this case. Fixes #22044 - - - - - e293029d by Simon Peyton Jones at 2022-08-18T09:25:19-04:00 Be more careful in chooseInferredQuantifiers This fixes #22065. We were failing to retain a quantifier that was mentioned in the kind of another retained quantifier. Easy to fix. - - - - - 714c936f by Bryan Richter at 2022-08-18T18:37:21-04:00 testsuite: Add test for #21583 - - - - - 989b844d by Ben Gamari at 2022-08-18T18:37:57-04:00 compiler: Drop --build-id=none hack Since 2011 the object-joining implementation has had a hack to pass `--build-id=none` to `ld` when supported, seemingly to work around a linker bug. This hack is now unnecessary and may break downstream users who expect objects to have valid build-ids. Remove it. Closes #22060. - - - - - 519c712e by Matthew Pickering at 2022-08-19T00:09:11-04:00 Make ru_fn field strict to avoid retaining Ids It's better to perform this projection from Id to Name strictly so we don't retain an old Id (hence IdInfo, hence Unfolding, hence everything etc) - - - - - 7dda04b0 by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force `getOccFS bndr` to avoid retaining reference to Bndr. This is another symptom of #19619 - - - - - 4303acba by Matthew Pickering at 2022-08-19T00:09:11-04:00 Force unfoldings when they are cleaned-up in Tidy and CorePrep If these thunks are not forced then the entire unfolding for the binding is live throughout the whole of CodeGen despite the fact it should have been discarded. Fixes #22071 - - - - - 2361b3bc by Matthew Pickering at 2022-08-19T00:09:47-04:00 haddock docs: Fix links from identifiers to dependent packages When implementing the base_url changes I made the pretty bad mistake of zipping together two lists which were in different orders. The simpler thing to do is just modify `haddockDependencies` to also return the package identifier so that everything stays in sync. Fixes #22001 - - - - - 9a7e2ea1 by Matthew Pickering at 2022-08-19T00:10:23-04:00 Revert "Refactor SpecConstr to use treat bindings uniformly" This reverts commit 415468fef8a3e9181b7eca86de0e05c0cce31729. This refactoring introduced quite a severe residency regression (900MB live from 650MB live when compiling mmark), see #21993 for a reproducer and more discussion. Ticket #21993 - - - - - 9789e845 by Zachary Wood at 2022-08-19T14:17:28-04:00 tc: warn about lazy annotations on unlifted arguments (fixes #21951) - - - - - e5567289 by Andreas Klebinger at 2022-08-19T14:18:03-04:00 Fix #22048 where we failed to drop rules for -fomit-interface-pragmas. Now we also filter the local rules (again) which fixes the issue. - - - - - 51ffd009 by Swann Moreau at 2022-08-19T18:29:21-04:00 Print constraints in quotes (#21167) This patch improves the uniformity of error message formatting by printing constraints in quotes, as we do for types. Fix #21167 - - - - - ab3e0f5a by Sasha Bogicevic at 2022-08-19T18:29:57-04:00 19217 Implicitly quantify type variables in :kind command - - - - - 9939e95f by MorrowM at 2022-08-21T16:51:38-04:00 Recognize file-header pragmas in GHCi (#21507) - - - - - fb7c2d99 by Matthew Pickering at 2022-08-21T16:52:13-04:00 hadrian: Fix bootstrapping with ghc-9.4 The error was that we were trying to link together containers from boot package library (which depends template-haskell in boot package library) template-haskell from in-tree package database So the fix is to build containers in stage0 (and link against template-haskell built in stage0). Fixes #21981 - - - - - b946232c by Mario Blažević at 2022-08-22T22:06:21-04:00 Added pprType with precedence argument, as a prerequisite to fix issues #21723 and #21942. * refines the precedence levels, adding `qualPrec` and `funPrec` to better control parenthesization * `pprParendType`, `pprFunArgType`, and `instance Ppr Type` all just call `pprType` with proper precedence * `ParensT` constructor is now always printed parenthesized * adds the precedence argument to `pprTyApp` as well, as it needs to keep track and pass it down * using `>=` instead of former `>` to match the Core type printing logic * some test outputs have changed, losing extraneous parentheses - - - - - fe4ff0f7 by Mario Blažević at 2022-08-22T22:06:21-04:00 Fix and test for issue #21723 - - - - - 33968354 by Mario Blažević at 2022-08-22T22:06:21-04:00 Test for issue #21942 - - - - - c9655251 by Mario Blažević at 2022-08-22T22:06:21-04:00 Updated the changelog - - - - - 80102356 by Ben Gamari at 2022-08-22T22:06:57-04:00 hadrian: Don't duplicate binaries on installation Previously we used `install` on symbolic links, which ended up copying the target file rather than installing a symbolic link. Fixes #22062. - - - - - b929063e by M Farkas-Dyck at 2022-08-24T02:37:01-04:00 Unbreak Haddock comments in `GHC.Core.Opt.WorkWrap.Utils`. Closes #22092. - - - - - 112e4f9c by Cheng Shao at 2022-08-24T02:37:38-04:00 driver: don't actually merge objects when ar -L works - - - - - a9f0e68e by Ben Gamari at 2022-08-24T02:38:13-04:00 rts: Consistently use MiB in stats output Previously we would say `MB` even where we meant `MiB`. - - - - - a90298cc by Simon Peyton Jones at 2022-08-25T08:38:16+01:00 Fix arityType: -fpedantic-bottoms, join points, etc This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223 - - - - - 909edcfc by Ben Gamari at 2022-08-25T10:03:34-04:00 upload_ghc_libs: Add means of passing Hackage credentials - - - - - 28402eed by M Farkas-Dyck at 2022-08-25T10:04:17-04:00 Scrub some partiality in `CommonBlockElim`. - - - - - 54affbfa by Ben Gamari at 2022-08-25T20:05:31-04:00 hadrian: Fix whitespace Previously this region of Settings.Packages was incorrectly indented. - - - - - c4bba0f0 by Ben Gamari at 2022-08-25T20:05:31-04:00 validate: Drop --legacy flag In preparation for removal of the legacy `make`-based build system. - - - - - 822b0302 by Ben Gamari at 2022-08-25T20:05:31-04:00 gitlab-ci: Drop make build validation jobs In preparation for removal of the `make`-based build system - - - - - 6fd9b0a1 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop make build system Here we at long last remove the `make`-based build system, it having been replaced with the Shake-based Hadrian build system. Users are encouraged to refer to the documentation in `hadrian/doc` and this [1] blog post for details on using Hadrian. Closes #17527. [1] https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html - - - - - dbb004b0 by Ben Gamari at 2022-08-25T20:05:31-04:00 Remove testsuite/tests/perf/haddock/.gitignore As noted in #16802, this is no longer needed. Closes #16802. - - - - - fe9d824d by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop hc-build script This has not worked for many, many years and relied on the now-removed `make`-based build system. - - - - - 659502bc by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mkdirhier This is only used by nofib's dead `dist` target - - - - - 4a426924 by Ben Gamari at 2022-08-25T20:05:31-04:00 Drop mk/{build,install,config}.mk.in - - - - - 46924b75 by Ben Gamari at 2022-08-25T20:05:31-04:00 compiler: Drop comment references to make - - - - - d387f687 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add inits1 and tails1 to Data.List.NonEmpty See https://github.com/haskell/core-libraries-committee/issues/67 - - - - - 8603c921 by Harry Garrood at 2022-08-25T20:06:10-04:00 Add since annotations and changelog entries - - - - - 6b47aa1c by Krzysztof Gogolewski at 2022-08-25T20:06:46-04:00 Fix redundant import This fixes a build error on x86_64-linux-alpine3_12-validate. See the function 'loadExternalPlugins' defined in this file. - - - - - 4786acf7 by sheaf at 2022-08-26T15:05:23-04:00 Pmc: consider any 2 dicts of the same type equal This patch massages the keys used in the `TmOracle` `CoreMap` to ensure that dictionaries of coherent classes give the same key. That is, whenever we have an expression we want to insert or lookup in the `TmOracle` `CoreMap`, we first replace any dictionary `$dict_abcd :: ct` with a value of the form `error @ct`. This allows us to common-up view pattern functions with required constraints whose arguments differed only in the uniques of the dictionaries they were provided, thus fixing #21662. This is a rather ad-hoc change to the keys used in the `TmOracle` `CoreMap`. In the long run, we would probably want to use a different representation for the keys instead of simply using `CoreExpr` as-is. This more ambitious plan is outlined in #19272. Fixes #21662 Updates unix submodule - - - - - f5e0f086 by Krzysztof Gogolewski at 2022-08-26T15:06:01-04:00 Remove label style from printing context Previously, the SDocContext used for code generation contained information whether the labels should use Asm or C style. However, at every individual call site, this is known statically. This removes the parameter to 'PprCode' and replaces every 'pdoc' used to print a label in code style with 'pprCLabel' or 'pprAsmLabel'. The OutputableP instance is now used only for dumps. The output of T15155 changes, it now uses the Asm style (which is faithful to what actually happens). - - - - - 1007829b by Cheng Shao at 2022-08-26T15:06:40-04:00 boot: cleanup legacy args Cleanup legacy boot script args, following removal of the legacy make build system. - - - - - 95fe09da by Simon Peyton Jones at 2022-08-27T00:29:02-04:00 Improve SpecConstr for evals As #21763 showed, we were over-specialising in some cases, when the function involved was doing a simple 'eval', but not taking the value apart, or branching on it. This MR fixes the problem. See Note [Do not specialise evals]. Nofib barely budges, except that spectral/cichelli allocates about 3% less. Compiler bytes-allocated improves a bit geo. mean -0.1% minimum -0.5% maximum +0.0% The -0.5% is on T11303b, for what it's worth. - - - - - 565a8ec8 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Revert "Revert "Refactor SpecConstr to use treat bindings uniformly"" This reverts commit 851d8dd89a7955864b66a3da8b25f1dd88a503f8. This commit was originally reverted due to an increase in space usage. This was diagnosed as because the SCE increased in size and that was being retained by another leak. See #22102 - - - - - 82ce1654 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Avoid retaining bindings via ModGuts held on the stack It's better to overwrite the bindings fields of the ModGuts before starting an iteration as then all the old bindings can be collected as soon as the simplifier has processed them. Otherwise we end up with the old bindings being alive until right at the end of the simplifier pass as the mg_binds field is only modified right at the end. - - - - - 64779dcd by Matthew Pickering at 2022-08-27T00:29:39-04:00 Force imposs_deflt_cons in filterAlts This fixes a pretty serious space leak as the forced thunk would retain `Alt b` values which would then contain reference to a lot of old bindings and other simplifier gunk. The OtherCon unfolding was not forced on subsequent simplifier runs so more and more old stuff would be retained until the end of simplification. Fixing this has a drastic effect on maximum residency for the mmark package which goes from ``` 45,005,401,056 bytes allocated in the heap 17,227,721,856 bytes copied during GC 818,281,720 bytes maximum residency (33 sample(s)) 9,659,144 bytes maximum slop 2245 MiB total memory in use (0 MB lost due to fragmentation) ``` to ``` 45,039,453,304 bytes allocated in the heap 13,128,181,400 bytes copied during GC 331,546,608 bytes maximum residency (40 sample(s)) 7,471,120 bytes maximum slop 916 MiB total memory in use (0 MB lost due to fragmentation) ``` See #21993 for some more discussion. - - - - - a3b23a33 by Matthew Pickering at 2022-08-27T00:29:39-04:00 Use Solo to avoid retaining the SCE but to avoid performing the substitution The use of Solo here allows us to force the selection into the SCE to obtain the Subst but without forcing the substitution to be applied. The resulting thunk is placed into a lazy field which is rarely forced, so forcing it regresses peformance. - - - - - 161a6f1f by Simon Peyton Jones at 2022-08-27T00:30:14-04:00 Fix a nasty loop in Tidy As the remarkably-simple #22112 showed, we were making a black hole in the unfolding of a self-recursive binding. Boo! It's a bit tricky. Documented in GHC.Iface.Tidy, Note [tidyTopUnfolding: avoiding black holes] - - - - - 68e6786f by Giles Anderson at 2022-08-29T00:01:35+02:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Class (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnIllegalHsigDefaultMethods TcRnBadGenericMethod TcRnWarningMinimalDefIncomplete TcRnDefaultMethodForPragmaLacksBinding TcRnIgnoreSpecialisePragmaOnDefMethod TcRnBadMethodErr TcRnNoExplicitAssocTypeOrDefaultDeclaration - - - - - cbe51ac5 by Simon Peyton Jones at 2022-08-29T04:18:57-04:00 Fix a bug in anyInRnEnvR This bug was a subtle error in anyInRnEnvR, introduced by commit d4d3fe6e02c0eb2117dbbc9df72ae394edf50f06 Author: Andreas Klebinger <klebinger.andreas at gmx.at> Date: Sat Jul 9 01:19:52 2022 +0200 Rule matching: Don't compute the FVs if we don't look at them. The net result was #22028, where a rewrite rule would wrongly match on a lambda. The fix to that function is easy. - - - - - 0154bc80 by sheaf at 2022-08-30T06:05:41-04:00 Various Hadrian bootstrapping fixes - Don't always produce a distribution archive (#21629) - Use correct executable names for ghc-pkg and hsc2hs on windows (we were missing the .exe file extension) - Fix a bug where we weren't using the right archive format on Windows when unpacking the bootstrap sources. Fixes #21629 - - - - - 451b1d90 by Matthew Pickering at 2022-08-30T06:06:16-04:00 ci: Attempt using normal submodule cloning strategy We do not use any recursively cloned submodules, and this protects us from flaky upstream remotes. Fixes #22121 - - - - - 9d5ad7c4 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: stray "--" - - - - - 3a002632 by Pi Delport at 2022-08-30T22:40:46+00:00 Fix typo in Any docs: syntatic -> syntactic - - - - - 7f490b13 by Simon Peyton Jones at 2022-08-31T03:53:54-04:00 Add a missing trimArityType This buglet was exposed by #22114, a consequence of my earlier refactoring of arity for join points. - - - - - e6fc820f by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump binary submodule to 0.8.9.1 - - - - - 4c1e7b22 by Ben Gamari at 2022-08-31T13:16:01+01:00 Bump stm submodule to 2.5.1.0 - - - - - 837472b4 by Ben Gamari at 2022-08-31T13:16:01+01:00 users-guide: Document system-cxx-std-lib - - - - - f7a9947a by Douglas Wilson at 2022-08-31T13:16:01+01:00 Update submodule containers to 0.6.6 - - - - - 4ab1c2ca by Douglas Wilson at 2022-08-31T13:16:02+01:00 Update submodule process to 1.6.15.0 - - - - - 1309ea1e by Ben Gamari at 2022-08-31T13:16:02+01:00 Bump directory submodule to 1.3.7.1 - - - - - 7962a33a by Douglas Wilson at 2022-08-31T13:16:02+01:00 Bump text submodule to 2.0.1 - - - - - fd8d80c3 by Ben Gamari at 2022-08-31T13:26:52+01:00 Bump deepseq submodule to 1.4.8.0 - - - - - a9baafac by Ben Gamari at 2022-08-31T13:26:52+01:00 Add dates to base, ghc-prim changelogs - - - - - 2cee323c by Ben Gamari at 2022-08-31T13:26:52+01:00 Update autoconf scripts Scripts taken from autoconf 02ba26b218d3d3db6c56e014655faf463cefa983 - - - - - e62705ff by Ben Gamari at 2022-08-31T13:26:53+01:00 Bump bytestring submodule to 0.11.3.1 - - - - - f7b4dcbd by Douglas Wilson at 2022-08-31T13:26:53+01:00 Update submodule Cabal to tag Cabal-v3.8.1.0 closes #21931 - - - - - e8eaf807 by Matthew Pickering at 2022-08-31T18:27:57-04:00 Refine in-tree compiler args for --test-compiler=stage1 Some of the logic to calculate in-tree arguments was not correct for the stage1 compiler. Namely we were not correctly reporting whether we were building static or dynamic executables and whether debug assertions were enabled. Fixes #22096 - - - - - 6b2f7ffe by Matthew Pickering at 2022-08-31T18:27:57-04:00 Make ghcDebugAssertions into a Stage predicate (Stage -> Bool) We also care whether we have debug assertions enabled for a stage one compiler, but the way which we turned on the assertions was quite different from the stage2 compiler. This makes the logic for turning on consistent across both and has the advantage of being able to correct determine in in-tree args whether a flavour enables assertions or not. Ticket #22096 - - - - - 15111af6 by Zubin Duggal at 2022-09-01T01:18:50-04:00 Add regression test for #21550 This was fixed by ca90ffa321a31842a32be1b5b6e26743cd677ec5 "Use local instances with least superclass depth" - - - - - 7d3a055d by Krzysztof Gogolewski at 2022-09-01T01:19:26-04:00 Minor cleanup - Remove mkHeteroCoercionType, sdocImpredicativeTypes, isStateType (unused), isCoVar_maybe (duplicated by getCoVar_maybe) - Replace a few occurrences of voidPrimId with (# #). void# is a deprecated synonym for the unboxed tuple. - Use showSDoc in :show linker. This makes it consistent with the other :show commands - - - - - 31a8989a by Tommy Bidne at 2022-09-01T12:01:20-04:00 Change Ord defaults per CLC proposal Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/24#issuecomment-1233331267 - - - - - 7f527f01 by Matthew Pickering at 2022-09-01T12:01:56-04:00 Fix bootstrap with ghc-9.0 It turns out Solo is a very recent addition to base, so for older GHC versions we just defined it inline here the one place we use it in the compiler. - - - - - d2be80fd by Sebastian Graf at 2022-09-05T23:12:14-04:00 DmdAnal: Don't panic in addCaseBndrDmd (#22039) Rather conservatively return Top. See Note [Untyped demand on case-alternative binders]. I also factored `addCaseBndrDmd` into two separate functions `scrutSubDmd` and `fieldBndrDmds`. Fixes #22039. - - - - - 25f68ace by Ben Gamari at 2022-09-05T23:12:50-04:00 gitlab-ci: Ensure that ghc derivation is in scope Previously the lint-ci job attempted to use cabal-install (specifically `cabal update`) without a GHC in PATH. However, cabal-install-3.8 appears to want GHC, even for `cabal update`. - - - - - f37b621f by sheaf at 2022-09-06T11:51:53+00:00 Update instances.rst, clarifying InstanceSigs Fixes #22103 - - - - - d4f908f7 by Jan Hrček at 2022-09-06T15:36:58-04:00 Fix :add docs in user guide - - - - - 808bb793 by Cheng Shao at 2022-09-06T15:37:35-04:00 ci: remove unused build_make/test_make in ci script - - - - - d0a2efb2 by Eric Lindblad at 2022-09-07T16:42:45-04:00 typo - - - - - fac0098b by Eric Lindblad at 2022-09-07T16:42:45-04:00 typos - - - - - a581186f by Eric Lindblad at 2022-09-07T16:42:45-04:00 whitespace - - - - - 04a738cb by Cheng Shao at 2022-09-07T16:43:22-04:00 CmmToAsm: remove unused ModLocation from NatM_State - - - - - ee1cfaa9 by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Minor SDoc cleanup Change calls to renderWithContext with showSDocOneLine; it's more efficient and explanatory. Remove polyPatSig (unused) - - - - - 7918265d by Krzysztof Gogolewski at 2022-09-07T16:43:58-04:00 Remove Outputable Char instance Use 'text' instead of 'ppr'. Using 'ppr' on the list "hello" rendered as "h,e,l,l,o". - - - - - 77209ab3 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Export liftA2 from Prelude Changes: In order to be warning free and compatible, we hide Applicative(..) from Prelude in a few places and instead import it directly from Control.Applicative. Please see the migration guide at https://github.com/haskell/core-libraries-committee/blob/main/guides/export-lifta2-prelude.md for more details. This means that Applicative is now exported in its entirety from Prelude. Motivation: This change is motivated by a few things: * liftA2 is an often used function, even more so than (<*>) for some people. * When implementing Applicative, the compiler will prompt you for either an implementation of (<*>) or of liftA2, but trying to use the latter ends with an error, without further imports. This could be confusing for newbies. * For teaching, it is often times easier to introduce liftA2 first, as it is a natural generalisation of fmap. * This change seems to have been unanimously and enthusiastically accepted by the CLC members, possibly indicating a lot of love for it. * This change causes very limited breakage, see the linked issue below for an investigation on this. See https://github.com/haskell/core-libraries-committee/issues/50 for the surrounding discussion and more details. - - - - - 442a94e8 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Add changelog entry for liftA2 export from Prelude - - - - - fb968680 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule containers to one with liftA2 warnings fixed - - - - - f54ff818 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Bump submodule Cabal to one with liftA2 warnings fixed - - - - - a4b34808 by Georgi Lyubenov at 2022-09-08T17:14:36+03:00 Isolate some Applicative hidings to GHC.Prelude By reexporting the entirety of Applicative from GHC.Prelude, we can save ourselves some `hiding` and importing of `Applicative` in consumers of GHC.Prelude. This also has the benefit of isolating this type of change to GHC.Prelude, so that people in the future don't have to think about it. - - - - - 9c4ea90c by Cheng Shao at 2022-09-08T17:49:47-04:00 CmmToC: enable 64-bit CallishMachOp on 32-bit targets Normally, the unregisterised builds avoid generating 64-bit CallishMachOp in StgToCmm, so CmmToC doesn't support these. However, there do exist cases where we'd like to invoke cmmToC for other cmm inputs which may contain such CallishMachOps, and it's a rather low effort to add support for these since they only require calling into existing ghc-prim cbits. - - - - - 04062510 by Alexis King at 2022-09-11T11:30:32+02:00 Add native delimited continuations to the RTS This patch implements GHC proposal 313, "Delimited continuation primops", by adding native support for delimited continuations to the GHC RTS. All things considered, the patch is relatively small. It almost exclusively consists of changes to the RTS; the compiler itself is essentially unaffected. The primops come with fairly extensive Haddock documentation, and an overview of the implementation strategy is given in the Notes in rts/Continuation.c. This first stab at the implementation prioritizes simplicity over performance. Most notably, every continuation is always stored as a single, contiguous chunk of stack. If one of these chunks is particularly large, it can result in poor performance, as the current implementation does not attempt to cleverly squeeze a subset of the stack frames into the existing stack: it must fit all at once. If this proves to be a performance issue in practice, a cleverer strategy would be a worthwhile target for future improvements. - - - - - ee471dfb by Cheng Shao at 2022-09-12T07:07:33-04:00 rts: fix missing dirty_MVAR argument in stg_writeIOPortzh - - - - - a5f9c35f by Cheng Shao at 2022-09-12T13:29:05-04:00 ci: enable parallel compression for xz - - - - - 3a815f30 by Ryan Scott at 2022-09-12T13:29:41-04:00 Windows: Always define _UCRT when compiling C code As seen in #22159, this is required to ensure correct behavior when MinGW-w64 headers are in the `C_INCLUDE_PATH`. Fixes #22159. - - - - - 65a0bd69 by sheaf at 2022-09-13T10:27:52-04:00 Add diagnostic codes This MR adds diagnostic codes, assigning unique numeric codes to error and warnings, e.g. error: [GHC-53633] Pattern match is redundant This is achieved as follows: - a type family GhcDiagnosticCode that gives the diagnostic code for each diagnostic constructor, - a type family ConRecursInto that specifies whether to recur into an argument of the constructor to obtain a more fine-grained code (e.g. different error codes for different 'deriving' errors), - generics machinery to generate the value-level function assigning each diagnostic its error code; see Note [Diagnostic codes using generics] in GHC.Types.Error.Codes. The upshot is that, to add a new diagnostic code, contributors only need to modify the two type families mentioned above. All logic relating to diagnostic codes is thus contained to the GHC.Types.Error.Codes module, with no code duplication. This MR also refactors error message datatypes a bit, ensuring we can derive Generic for them, and cleans up the logic around constraint solver reports by splitting up 'TcSolverReportInfo' into separate datatypes (see #20772). Fixes #21684 - - - - - 362cca13 by sheaf at 2022-09-13T10:27:53-04:00 Diagnostic codes: acccept test changes The testsuite output now contains diagnostic codes, so many tests need to be updated at once. We decided it was best to keep the diagnostic codes in the testsuite output, so that contributors don't inadvertently make changes to the diagnostic codes. - - - - - 08f6730c by Adam Gundry at 2022-09-13T10:28:29-04:00 Allow imports to reference multiple fields with the same name (#21625) If a module `M` exports two fields `f` (using DuplicateRecordFields), we can still accept import M (f) import M hiding (f) and treat `f` as referencing both of them. This was accepted in GHC 9.0, but gave rise to an ambiguity error in GHC 9.2. See #21625. This patch also documents this behaviour in the user's guide, and updates the test for #16745 which is now treated differently. - - - - - c14370d7 by Cheng Shao at 2022-09-13T10:29:07-04:00 ci: remove unused appveyor config - - - - - dc6af9ed by Cheng Shao at 2022-09-13T10:29:45-04:00 compiler: remove unused lazy state monad - - - - - 646d15ad by Eric Lindblad at 2022-09-14T03:13:56-04:00 Fix typos This fixes various typos and spelling mistakes in the compiler. Fixes #21891 - - - - - 7d7e71b0 by Matthew Pickering at 2022-09-14T03:14:32-04:00 hadrian: Bump index state This bumps the index state so a build plan can also be found when booting with 9.4. Fixes #22165 - - - - - 98b62871 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Use a stamp file to record when a package is built in a certain way Before this patch which library ways we had built wasn't recorded directly. So you would run into issues if you build the .conf file with some library ways before switching the library ways which you wanted to build. Now there is one stamp file for each way, so in order to build a specific way you can need that specific stamp file rather than going indirectly via the .conf file. - - - - - b42cedbe by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Inplace/Final package databases There are now two different package databases per stage. An inplace package database contains .conf files which point directly into the build directories. The final package database contains .conf files which point into the installed locations. The inplace .conf files are created before any building happens and have fake ABI hash values. The final .conf files are created after a package finished building and contains the proper ABI has. The motivation for this is to make the dependency structure more fine-grained when building modules. Now a module depends just depends directly on M.o from package p rather than the .conf file depend on the .conf file for package p. So when all of a modules direct dependencies have finished building we can start building it rather than waiting for the whole package to finish. The secondary motivation is that the multi-repl doesn't need to build everything before starting the multi-repl session. We can just configure the inplace package-db and use that in order to start the repl. - - - - - 6515c32b by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add some more packages to multi-cradle The main improvement here is to pass `-this-unit-id` for executables so that they can be added to the multi-cradle if desired as well as normal library packages. - - - - - e470e91f by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Need builders needed by Cabal Configure in parallel Because of the use of withStaged (which needs the necessary builder) when configuring a package, the builds of stage1:exe:ghc-bin and stage1:exe:ghc-pkg where being linearised when building a specific target like `binary-dist-dir`. Thankfully the fix is quite local, to supply all the `withStaged` arguments together so the needs can be batched together and hence performed in parallel. Fixes #22093 - - - - - c4438347 by Matthew Pickering at 2022-09-14T17:17:04-04:00 Remove stage1:exe:ghc-bin pre-build from CI script CI builds stage1:exe:ghc-bin before the binary-dist target which introduces some quite bad linearisation (see #22093) because we don't build stage1 compiler in parallel with anything. Then when the binary-dist target is started we have to build stage1:exe:ghc-pkg before doing anything. Fixes #22094 - - - - - 71d8db86 by Matthew Pickering at 2022-09-14T17:17:04-04:00 hadrian: Add extra implicit dependencies from DeriveLift ghc -M should know that modules which use DeriveLift (or TemplateHaskellQuotes) need TH.Lib.Internal but until it does, we have to add these extra edges manually or the modules will be compiled before TH.Lib.Internal is compiled which leads to a desugarer error. - - - - - 43e574f0 by Greg Steuck at 2022-09-14T17:17:43-04:00 Repair c++ probing on OpenBSD Failure without this change: ``` checking C++ standard library flavour... libc++ checking for linkage against 'c++ c++abi'... failed checking for linkage against 'c++ cxxrt'... failed configure: error: Failed to find C++ standard library ``` - - - - - 534b39ee by Douglas Wilson at 2022-09-14T17:18:21-04:00 libraries: template-haskell: vendor filepath differently Vendoring with ../ in hs-source-dirs prevents upload to hackage. (cherry picked from commit 1446be7586ba70f9136496f9b67f792955447842) - - - - - bdd61cd6 by M Farkas-Dyck at 2022-09-14T22:39:34-04:00 Unbreak Hadrian with Cabal 3.8. - - - - - df04d6ec by Krzysztof Gogolewski at 2022-09-14T22:40:09-04:00 Fix typos - - - - - d6ea8356 by Andreas Klebinger at 2022-09-15T10:12:41+02:00 Tag inference: Fix #21954 by retaining tagsigs of vars in function position. For an expression like: case x of y Con z -> z If we also retain the tag sig for z we can generate code to immediately return it rather than calling out to stg_ap_0_fast. - - - - - 7cce7007 by Andreas Klebinger at 2022-09-15T10:12:42+02:00 Stg.InferTags.Rewrite - Avoid some thunks. - - - - - 88c4cbdb by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: enable -fprof-late only for profiling ways - - - - - d7235831 by Cheng Shao at 2022-09-16T13:57:56-04:00 hadrian: add late_ccs flavour transformer - - - - - ce203753 by Cheng Shao at 2022-09-16T13:58:34-04:00 configure: remove unused program checks - - - - - 9b4c1056 by Pierre Le Marre at 2022-09-16T13:59:16-04:00 Update to Unicode 15.0 - - - - - c6e9b89a by Bodigrim at 2022-09-16T13:59:55-04:00 Avoid partial head and tail in ghc-heap; replace with total pattern-matching - - - - - 616afde3 by Cheng Shao at 2022-09-16T14:00:33-04:00 hadrian: relax Cabal upper bound to allow building with Cabal-3.8 A follow up of !8910. - - - - - df35d994 by Alexis King at 2022-09-16T14:01:11-04:00 Add links to the continuations haddocks in the docs for each primop fixes #22176 - - - - - 383f7549 by Matthew Pickering at 2022-09-16T21:42:10-04:00 -Wunused-pattern-binds: Recurse into patterns to check whether there's a splice See the examples in #22057 which show we have to traverse deeply into a pattern to determine whether it contains a splice or not. The original implementation pointed this out but deemed this very shallow traversal "too expensive". Fixes #22057 I also fixed an oversight in !7821 which meant we lost a warning which was present in 9.2.2. Fixes #22067 - - - - - 5031bf49 by sheaf at 2022-09-16T21:42:49-04:00 Hadrian: Don't try to build terminfo on Windows Commit b42cedbe introduced a dependency on terminfo on Windows, but that package isn't available on Windows. - - - - - c9afe221 by M Farkas-Dyck at 2022-09-17T06:44:47-04:00 Clean up some. In particular: • Delete some dead code, largely under `GHC.Utils`. • Clean up a few definitions in `GHC.Utils.(Misc, Monad)`. • Clean up `GHC.Types.SrcLoc`. • Derive stock `Functor, Foldable, Traversable` for more types. • Derive more instances for newtypes. Bump haddock submodule. - - - - - 85431ac3 by Cheng Shao at 2022-09-17T06:45:25-04:00 driver: pass original Cmm filename in ModLocation When compiling Cmm, the ml_hs_file field is used to indicate Cmm filename when later generating DWARF information. We should pass the original filename here, otherwise for preprocessed Cmm files, the filename will be a temporary filename which is confusing. - - - - - 63aa0069 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: remove legacy logging cabal flag - - - - - bd0f4184 by Cheng Shao at 2022-09-17T06:46:04-04:00 rts: make threaded ways optional For certain targets (e.g. wasm32-wasi), the threaded rts is known not to work. This patch adds a "threaded" cabal flag to rts to make threaded rts ways optional. Hadrian enables this flag iff the flavour rtsWays contains threaded ways. - - - - - 8a666ad2 by Ryan Scott at 2022-09-18T08:00:44-04:00 DeriveFunctor: Check for last type variables using dataConUnivTyVars Previously, derived instances of `Functor` (as well as the related classes `Foldable`, `Traversable`, and `Generic1`) would determine which constraints to infer by checking for fields that contain the last type variable. The problem was that this last type variable was taken from `tyConTyVars`. For GADTs, the type variables in each data constructor are _not_ the same type variables as in `tyConTyVars`, leading to #22167. This fixes the issue by instead checking for the last type variable using `dataConUnivTyVars`. (This is very similar in spirit to the fix for #21185, which also replaced an errant use of `tyConTyVars` with type variables from each data constructor.) Fixes #22167. - - - - - 78037167 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: pass updated buffer to actions (#22201) In the lexer, predicates have the following type: { ... } :: user -- predicate state -> AlexInput -- input stream before the token -> Int -- length of the token -> AlexInput -- input stream after the token -> Bool -- True <=> accept the token This is documented in the Alex manual. There is access to the input stream both before and after the token. But when the time comes to construct the token, GHC passes only the initial string buffer to the lexer action. This patch fixes it: - type Action = PsSpan -> StringBuffer -> Int -> P (PsLocated Token) + type Action = PsSpan -> StringBuffer -> Int -> StringBuffer -> P (PsLocated Token) Now lexer actions have access to the string buffer both before and after the token, just like the predicates. It's just a matter of passing an additional function parameter throughout the lexer. - - - - - 75746594 by Vladislav Zavialov at 2022-09-18T08:01:20-04:00 Lexer: define varsym without predicates (#22201) Before this patch, the varsym lexing rules were defined as follows: <0> { @varsym / { precededByClosingToken `alexAndPred` followedByOpeningToken } { varsym_tight_infix } @varsym / { followedByOpeningToken } { varsym_prefix } @varsym / { precededByClosingToken } { varsym_suffix } @varsym { varsym_loose_infix } } Unfortunately, this meant that the predicates 'precededByClosingToken' and 'followedByOpeningToken' were recomputed several times before we could figure out the whitespace context. With this patch, we check for whitespace context directly in the lexer action: <0> { @varsym { with_op_ws varsym } } The checking for opening/closing tokens happens in 'with_op_ws' now, which is part of the lexer action rather than the lexer predicate. - - - - - c1f81b38 by M Farkas-Dyck at 2022-09-19T09:07:05-04:00 Scrub partiality about `NewOrData`. Rather than a list of constructors and a `NewOrData` flag, we define `data DataDefnCons a = NewTypeCon a | DataTypeCons [a]`, which enforces a newtype to have exactly one constructor. Closes #22070. Bump haddock submodule. - - - - - 1e1ed8c5 by Cheng Shao at 2022-09-19T09:07:43-04:00 CmmToC: emit __builtin_unreachable() after noreturn ccalls Emit a __builtin_unreachable() call after a foreign call marked as CmmNeverReturns. This is crucial to generate correctly typed code for wasm; as for other archs, this is also beneficial for the C compiler optimizations. - - - - - 19f45a25 by Jan Hrček at 2022-09-20T03:49:29-04:00 Document :unadd GHCi command in user guide - - - - - 545ff490 by sheaf at 2022-09-20T03:50:06-04:00 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). - - - - - 59fe128c by Vladislav Zavialov at 2022-09-20T03:50:42-04:00 Fix -Woperator-whitespace for consym (part of #19372) Due to an oversight, the initial specification and implementation of -Woperator-whitespace focused on varsym exclusively and completely ignored consym. This meant that expressions such as "x+ y" would produce a warning, while "x:+ y" would not. The specification was corrected in ghc-proposals pull request #404, and this patch updates the implementation accordingly. Regression test included. - - - - - c4c2cca0 by John Ericson at 2022-09-20T13:11:49-04:00 Add `Eq` and `Ord` instances for `Generically1` These are needed so the subsequent commit overhauling the `*1` classes type-checks. - - - - - 7beb356e by John Ericson at 2022-09-20T13:11:50-04:00 Relax instances for Functor combinators; put superclass on Class1 and Class2 to make non-breaking This change is approved by the Core Libraries commitee in https://github.com/haskell/core-libraries-committee/issues/10 The first change makes the `Eq`, `Ord`, `Show`, and `Read` instances for `Sum`, `Product`, and `Compose` match those for `:+:`, `:*:`, and `:.:`. These have the proper flexible contexts that are exactly what the instance needs: For example, instead of ```haskell instance (Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where (==) = eq1 ``` we do ```haskell deriving instance Eq (f (g a)) => Eq (Compose f g a) ``` But, that change alone is rather breaking, because until now `Eq (f a)` and `Eq1 f` (and respectively the other classes and their `*1` equivalents too) are *incomparable* constraints. This has always been an annoyance of working with the `*1` classes, and now it would rear it's head one last time as an pesky migration. Instead, we give the `*1` classes superclasses, like so: ```haskell (forall a. Eq a => Eq (f a)) => Eq1 f ``` along with some laws that canonicity is preserved, like: ```haskell liftEq (==) = (==) ``` and likewise for `*2` classes: ```haskell (forall a. Eq a => Eq1 (f a)) => Eq2 f ``` and laws: ```haskell liftEq2 (==) = liftEq1 ``` The `*1` classes also have default methods using the `*2` classes where possible. What this means, as explained in the docs, is that `*1` classes really are generations of the regular classes, indicating that the methods can be split into a canonical lifting combined with a canonical inner, with the super class "witnessing" the laws[1] in a fashion. Circling back to the pragmatics of migrating, note that the superclass means evidence for the old `Sum`, `Product`, and `Compose` instances is (more than) sufficient, so breakage is less likely --- as long no instances are "missing", existing polymorphic code will continue to work. Breakage can occur when a datatype implements the `*1` class but not the corresponding regular class, but this is almost certainly an oversight. For example, containers made that mistake for `Tree` and `Ord`, which I fixed in https://github.com/haskell/containers/pull/761, but fixing the issue by adding `Ord1` was extremely *un*controversial. `Generically1` was also missing `Eq`, `Ord`, `Read,` and `Show` instances. It is unlikely this would have been caught without implementing this change. ----- [1]: In fact, someday, when the laws are part of the language and not only documentation, we might be able to drop the superclass field of the dictionary by using the laws to recover the superclass in an instance-agnostic manner, e.g. with a *non*-overloaded function with type: ```haskell DictEq1 f -> DictEq a -> DictEq (f a) ``` But I don't wish to get into optomizations now, just demonstrate the close relationship between the law and the superclass. Bump haddock submodule because of test output changing. - - - - - 6a8c6b5e by Tom Ellis at 2022-09-20T13:12:27-04:00 Add notes to ghc-prim Haddocks that users should not import it - - - - - ee9d0f5c by matoro at 2022-09-20T13:13:06-04:00 docs: clarify that LLVM codegen is not available in unregisterised mode The current docs are misleading and suggest that it is possible to use LLVM codegen from an unregisterised build. This is not the case; attempting to pass `-fllvm` to an unregisterised build warns: ``` when making flags consistent: warning: Target platform uses unregisterised ABI, so compiling via C ``` and uses the C codegen anyway. - - - - - 854224ed by Nicolas Trangez at 2022-09-20T20:14:29-04:00 rts: remove copy-paste error from `cabal.rts.in` This was, likely accidentally, introduced in 4bf542bf1c. See: 4bf542bf1cdf2fa468457fc0af21333478293476 - - - - - c8ae3add by Matthew Pickering at 2022-09-20T20:15:04-04:00 hadrian: Add extra_dependencies edges for all different ways The hack to add extra dependencies needed by DeriveLift extension missed the cases for profiles and dynamic ways. For the profiled way this leads to errors like: ``` GHC error in desugarer lookup in Data.IntSet.Internal: Failed to load interface for ‘Language.Haskell.TH.Lib.Internal’ Perhaps you haven't installed the profiling libraries for package ‘template-haskell’? Use -v (or `:set -v` in ghci) to see a list of the files searched for. ghc: panic! (the 'impossible' happened) GHC version 9.5.20220916: initDs ``` Therefore the fix is to add these extra edges in. Fixes #22197 - - - - - a971657d by Mon Aaraj at 2022-09-21T06:41:24+03:00 users-guide: fix incorrect ghcappdata folder for unix and windows - - - - - 06ccad0d by sheaf at 2022-09-21T08:28:49-04:00 Don't use isUnliftedType in isTagged The function GHC.Stg.InferTags.Rewrite.isTagged can be given the Id of a join point, which might be representation polymorphic. This would cause the call to isUnliftedType to crash. It's better to use typeLevity_maybe instead. Fixes #22212 - - - - - c0ba775d by Teo Camarasu at 2022-09-21T14:30:37-04:00 Add fragmentation statistic to GHC.Stats Implements #21537 - - - - - 2463df2f by Torsten Schmits at 2022-09-21T14:31:24-04:00 Rename Solo[constructor] to MkSolo Part of proposal 475 (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0475-tuple-syntax.rst) Moves all tuples to GHC.Tuple.Prim Updates ghc-prim version (and bumps bounds in dependents) updates haddock submodule updates deepseq submodule updates text submodule - - - - - 9034fada by Matthew Pickering at 2022-09-22T09:25:29-04:00 Update filepath to filepath-1.4.100.0 Updates submodule * Always rely on vendored filepath * filepath must be built as stage0 dependency because it uses template-haskell. Towards #22098 - - - - - 615e2278 by Krzysztof Gogolewski at 2022-09-22T09:26:05-04:00 Minor refactor around Outputable * Replace 'text . show' and 'ppr' with 'int'. * Remove Outputable.hs-boot, no longer needed * Use pprWithCommas * Factor out instructions in AArch64 codegen - - - - - aeafdba5 by Sebastian Graf at 2022-09-27T15:14:54+02:00 Demand: Clear distinction between Call SubDmd and eval Dmd (#21717) In #21717 we saw a reportedly unsound strictness signature due to an unsound definition of plusSubDmd on Calls. This patch contains a description and the fix to the unsoundness as outlined in `Note [Call SubDemand vs. evaluation Demand]`. This fix means we also get rid of the special handling of `-fpedantic-bottoms` in eta-reduction. Thanks to less strict and actually sound strictness results, we will no longer eta-reduce the problematic cases in the first place, even without `-fpedantic-bottoms`. So fixing the unsoundness also makes our eta-reduction code simpler with less hacks to explain. But there is another, more unfortunate side-effect: We *unfix* #21085, but fortunately we have a new fix ready: See `Note [mkCall and plusSubDmd]`. There's another change: I decided to make `Note [SubDemand denotes at least one evaluation]` a lot simpler by using `plusSubDmd` (instead of `lubPlusSubDmd`) even if both argument demands are lazy. That leads to less precise results, but in turn rids ourselves from the need for 4 different `OpMode`s and the complication of `Note [Manual specialisation of lub*Dmd/plus*Dmd]`. The result is simpler code that is in line with the paper draft on Demand Analysis. I left the abandoned idea in `Note [Unrealised opportunity in plusDmd]` for posterity. The fallout in terms of regressions is negligible, as the testsuite and NoFib shows. ``` Program Allocs Instrs -------------------------------------------------------------------------------- hidden +0.2% -0.2% linear -0.0% -0.7% -------------------------------------------------------------------------------- Min -0.0% -0.7% Max +0.2% +0.0% Geometric Mean +0.0% -0.0% ``` Fixes #21717. - - - - - 9b1595c8 by Ross Paterson at 2022-09-27T14:12:01-04:00 implement proposal 106 (Define Kinds Without Promotion) (fixes #6024) includes corresponding changes to haddock submodule - - - - - c2d73cb4 by Andreas Klebinger at 2022-09-28T15:07:30-04:00 Apply some tricks to speed up core lint. Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 ------------------------- - - - - - b74b6191 by sheaf at 2022-09-28T15:08:10-04:00 matchLocalInst: do domination analysis When multiple Given quantified constraints match a Wanted, and there is a quantified constraint that dominates all others, we now pick it to solve the Wanted. See Note [Use only the best matching quantified constraint]. For example: [G] d1: forall a b. ( Eq a, Num b, C a b ) => D a b [G] d2: forall a . C a Int => D a Int [W] {w}: D a Int When solving the Wanted, we find that both Givens match, but we pick the second, because it has a weaker precondition, C a Int, compared to (Eq a, Num Int, C a Int). We thus say that d2 dominates d1; see Note [When does a quantified instance dominate another?]. This domination test is done purely in terms of superclass expansion, in the function GHC.Tc.Solver.Interact.impliedBySCs. We don't attempt to do a full round of constraint solving; this simple check suffices for now. Fixes #22216 and #22223 - - - - - 2a53ac18 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Improve aggressive specialisation This patch fixes #21286, by not unboxing dictionaries in worker/wrapper (ever). The main payload is tiny: * In `GHC.Core.Opt.DmdAnal.finaliseArgBoxities`, do not unbox dictionaries in `get_dmd`. See Note [Do not unbox class dictionaries] in that module * I also found that imported wrappers were being fruitlessly specialised, so I fixed that too, in canSpecImport. See Note [Specialising imported functions] point (2). In doing due diligence in the testsuite I fixed a number of other things: * Improve Note [Specialising unfoldings] in GHC.Core.Unfold.Make, and Note [Inline specialisations] in GHC.Core.Opt.Specialise, and remove duplication between the two. The new Note describes how we specialise functions with an INLINABLE pragma. And simplify the defn of `spec_unf` in `GHC.Core.Opt.Specialise.specCalls`. * Improve Note [Worker/wrapper for INLINABLE functions] in GHC.Core.Opt.WorkWrap. And (critially) make an actual change which is to propagate the user-written pragma from the original function to the wrapper; see `mkStrWrapperInlinePrag`. * Write new Note [Specialising imported functions] in GHC.Core.Opt.Specialise All this has a big effect on some compile times. This is compiler/perf, showing only changes over 1%: Metrics: compile_time/bytes allocated ------------------------------------- LargeRecord(normal) -50.2% GOOD ManyConstructors(normal) +1.0% MultiLayerModulesTH_OneShot(normal) +2.6% PmSeriesG(normal) -1.1% T10547(normal) -1.2% T11195(normal) -1.2% T11276(normal) -1.0% T11303b(normal) -1.6% T11545(normal) -1.4% T11822(normal) -1.3% T12150(optasm) -1.0% T12234(optasm) -1.2% T13056(optasm) -9.3% GOOD T13253(normal) -3.8% GOOD T15164(normal) -3.6% GOOD T16190(normal) -2.1% T16577(normal) -2.8% GOOD T16875(normal) -1.6% T17836(normal) +2.2% T17977b(normal) -1.0% T18223(normal) -33.3% GOOD T18282(normal) -3.4% GOOD T18304(normal) -1.4% T18698a(normal) -1.4% GOOD T18698b(normal) -1.3% GOOD T19695(normal) -2.5% GOOD T5837(normal) -2.3% T9630(normal) -33.0% GOOD WWRec(normal) -9.7% GOOD hard_hole_fits(normal) -2.1% GOOD hie002(normal) +1.6% geo. mean -2.2% minimum -50.2% maximum +2.6% I diligently investigated some of the big drops. * Caused by not doing w/w for dictionaries: T13056, T15164, WWRec, T18223 * Caused by not fruitlessly specialising wrappers LargeRecord, T9630 For runtimes, here is perf/should+_run: Metrics: runtime/bytes allocated -------------------------------- T12990(normal) -3.8% T5205(normal) -1.3% T9203(normal) -10.7% GOOD haddock.Cabal(normal) +0.1% haddock.base(normal) -1.1% haddock.compiler(normal) -0.3% lazy-bs-alloc(normal) -0.2% ------------------------------------------ geo. mean -0.3% minimum -10.7% maximum +0.1% I did not investigate exactly what happens in T9203. Nofib is a wash: +-------------------------------++--+-----------+-----------+ | || | tsv (rel) | std. err. | +===============================++==+===========+===========+ | real/anna || | -0.13% | 0.0% | | real/fem || | +0.13% | 0.0% | | real/fulsom || | -0.16% | 0.0% | | real/lift || | -1.55% | 0.0% | | real/reptile || | -0.11% | 0.0% | | real/smallpt || | +0.51% | 0.0% | | spectral/constraints || | +0.20% | 0.0% | | spectral/dom-lt || | +1.80% | 0.0% | | spectral/expert || | +0.33% | 0.0% | +===============================++==+===========+===========+ | geom mean || | | | +-------------------------------++--+-----------+-----------+ I spent quite some time investigating dom-lt, but it's pretty complicated. See my note on !7847. Conclusion: it's just a delicate inlining interaction, and we have plenty of those. Metric Decrease: LargeRecord T13056 T13253 T15164 T16577 T18223 T18282 T18698a T18698b T19695 T9630 WWRec hard_hole_fits T9203 - - - - - addeefc0 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 Refactor UnfoldingSource and IfaceUnfolding I finally got tired of the way that IfaceUnfolding reflected a previous structure of unfoldings, not the current one. This MR refactors UnfoldingSource and IfaceUnfolding to be simpler and more consistent. It's largely just a refactor, but in UnfoldingSource (which moves to GHC.Types.Basic, since it is now used in IfaceSyn too), I distinguish between /user-specified/ and /system-generated/ stable unfoldings. data UnfoldingSource = VanillaSrc | StableUserSrc -- From a user-specified pragma | StableSystemSrc -- From a system-generated unfolding | CompulsorySrc This has a minor effect in CSE (see the use of isisStableUserUnfolding in GHC.Core.Opt.CSE), which I tripped over when working on specialisation, but it seems like a Good Thing to know anyway. - - - - - 7be6f9a4 by Simon Peyton Jones at 2022-09-28T17:49:09-04:00 INLINE/INLINEABLE pragmas in Foreign.Marshal.Array Foreign.Marshal.Array contains many small functions, all of which are overloaded, and which are critical for performance. Yet none of them had pragmas, so it was a fluke whether or not they got inlined. This patch makes them all either INLINE (small ones) or INLINEABLE and hence specialisable (larger ones). See Note [Specialising array operations] in that module. - - - - - b0c89dfa by Jade Lovelace at 2022-09-28T17:49:49-04:00 Export OnOff from GHC.Driver.Session I was working on fixing an issue where HLS was trying to pass its DynFlags to HLint, but didn't pass any of the disabled language extensions, which HLint would then assume are on because of their default values. Currently it's not possible to get any of the "No" flags because the `DynFlags.extensions` field can't really be used since it is [OnOff Extension] and OnOff is not exported. So let's export it. - - - - - 2f050687 by Bodigrim at 2022-09-28T17:50:28-04:00 Avoid Data.List.group; prefer Data.List.NonEmpty.group This allows to avoid further partiality, e. g., map head . group is replaced by map NE.head . NE.group, and there are less panic calls. - - - - - bc0020fa by M Farkas-Dyck at 2022-09-28T22:51:59-04:00 Clean up `findWiredInUnit`. In particular, avoid `head`. - - - - - 6a2eec98 by Bodigrim at 2022-09-28T22:52:38-04:00 Eliminate headFS, use unconsFS instead A small step towards #22185 to avoid partial functions + safe implementation of `startsWithUnderscore`. - - - - - 5a535172 by Sebastian Graf at 2022-09-29T17:04:20+02:00 Demand: Format Call SubDemands `Cn(sd)` as `C(n,sd)` (#22231) Justification in #22231. Short form: In a demand like `1C1(C1(L))` it was too easy to confuse which `1` belongs to which `C`. Now that should be more obvious. Fixes #22231 - - - - - ea0083bf by Bryan Richter at 2022-09-29T15:48:38-04:00 Revert "ci: enable parallel compression for xz" Combined wxth XZ_OPT=9, this blew the memory capacity of CI runners. This reverts commit a5f9c35f5831ef5108e87813a96eac62803852ab. - - - - - f5e8f493 by Sebastian Graf at 2022-09-30T18:42:13+02:00 Boxity: Don't update Boxity unless worker/wrapper follows (#21754) A small refactoring in our Core Opt pipeline and some new functions for transfering argument boxities from one signature to another to facilitate `Note [Don't change boxity without worker/wrapper]`. Fixes #21754. - - - - - 4baf7b1c by M Farkas-Dyck at 2022-09-30T17:45:47-04:00 Scrub various partiality involving empty lists. Avoids some uses of `head` and `tail`, and some panics when an argument is null. - - - - - 95ead839 by Alexis King at 2022-10-01T00:37:43-04:00 Fix a bug in continuation capture across multiple stack chunks - - - - - 22096652 by Bodigrim at 2022-10-01T00:38:22-04:00 Enforce internal invariant of OrdList and fix bugs in viewCons / viewSnoc `viewCons` used to ignore `Many` constructor completely, returning `VNothing`. `viewSnoc` violated internal invariant of `Many` being a non-empty list. - - - - - 48ab9ca5 by Nicolas Trangez at 2022-10-04T20:34:10-04:00 chore: extend `.editorconfig` for C files - - - - - b8df5c72 by Brandon Chinn at 2022-10-04T20:34:46-04:00 Fix docs for pattern synonyms - - - - - 463ffe02 by Oleg Grenrus at 2022-10-04T20:35:24-04:00 Use sameByteArray# in sameByteArray - - - - - fbe1e86e by Pierre Le Marre at 2022-10-05T15:58:43+02:00 Minor fixes following Unicode 15.0.0 update - Fix changelog for Unicode 15.0.0 - Fix the checksums of the downloaded Unicode files, in base's tool: "ucd2haskell". - - - - - 8a31d02e by Cheng Shao at 2022-10-05T20:40:41-04:00 rts: don't enforce aligned((8)) on 32-bit targets We simply need to align to the word size for pointer tagging to work. On 32-bit targets, aligned((8)) is wasteful. - - - - - 532de368 by Ryan Scott at 2022-10-06T07:45:46-04:00 Export symbolSing, SSymbol, and friends (CLC#85) This implements this Core Libraries Proposal: https://github.com/haskell/core-libraries-committee/issues/85 In particular, it: 1. Exposes the `symbolSing` method of `KnownSymbol`, 2. Exports the abstract `SSymbol` type used in `symbolSing`, and 3. Defines an API for interacting with `SSymbol`. This also makes corresponding changes for `natSing`/`KnownNat`/`SNat` and `charSing`/`KnownChar`/`SChar`. This fixes #15183 and addresses part (2) of #21568. - - - - - d83a92e6 by sheaf at 2022-10-07T07:36:30-04:00 Remove mention of make from README.md - - - - - 945e8e49 by Bodigrim at 2022-10-10T17:13:31-04:00 Add a newline before since pragma in Data.Array.Byte - - - - - 44fcdb04 by Vladislav Zavialov at 2022-10-10T17:14:06-04:00 Parser/PostProcess: rename failOp* functions There are three functions named failOp* in the parser: failOpNotEnabledImportQualifiedPost failOpImportQualifiedTwice failOpFewArgs Only the last one has anything to do with operators. The other two were named this way either by mistake or due to a misunderstanding of what "op" stands for. This small patch corrects this. - - - - - 96d32ff2 by Simon Peyton Jones at 2022-10-10T22:30:21+01:00 Make rewrite rules "win" over inlining If a rewrite rule and a rewrite rule compete in the simplifier, this patch makes sure that the rewrite rule "win". That is, in general a bit fragile, but it's a huge help when making specialisation work reliably, as #21851 and #22097 showed. The change is fairly straightforwad, and documented in Note [Rewrite rules and inlining] in GHC.Core.Opt.Simplify.Iteration. Compile-times change, up and down a bit -- in some cases because we get better specialisation. But the payoff (more reliable specialisation) is large. Metrics: compile_time/bytes allocated ----------------------------------------------- T10421(normal) +3.7% BAD T10421a(normal) +5.5% T13253(normal) +1.3% T14052(ghci) +1.8% T15304(normal) -1.4% T16577(normal) +3.1% BAD T17516(normal) +2.3% T17836(normal) -1.9% T18223(normal) -1.8% T8095(normal) -1.3% T9961(normal) +2.5% BAD geo. mean +0.0% minimum -1.9% maximum +5.5% Nofib results are (bytes allocated) +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || +0.27% | | imaginary/rfib || -0.04% | | real/anna || +0.02% | | real/fem || -0.04% | | real/fluid || +1.68% | | real/gamteb || -0.34% | | real/gg || +1.54% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/infer || -0.03% | | real/prolog || +0.02% | | real/veritas || -0.47% | | shootout/fannkuch-redux || -0.03% | | shootout/k-nucleotide || -0.02% | | shootout/n-body || -0.06% | | shootout/spectral-norm || -0.01% | | spectral/cryptarithm2 || +1.25% | | spectral/fibheaps || +18.33% | | spectral/last-piece || -0.34% | +===============================++==========+ | geom mean || +0.17% | There are extensive notes in !8897 about the regressions. Briefly * fibheaps: there was a very delicately balanced inlining that tipped over the wrong way after this change. * cryptarithm2 and paraffins are caused by #22274, which is a separate issue really. (I.e. the right fix is *not* to make inlining "win" over rules.) So I'm accepting these changes Metric Increase: T10421 T16577 T9961 - - - - - ed4b5885 by Joachim Breitner at 2022-10-10T23:16:11-04:00 Utils.JSON: do not escapeJsonString in ToJson String instance as `escapeJsonString` is used in `renderJSON`, so the `JSString` constructor is meant to carry the unescaped string. - - - - - fbb88740 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Tidy implicit binds We want to put implicit binds into fat interface files, so the easiest thing to do seems to be to treat them uniformly with other binders. - - - - - e058b138 by Matthew Pickering at 2022-10-11T12:48:45-04:00 Interface Files with Core Definitions This commit adds three new flags * -fwrite-if-simplified-core: Writes the whole core program into an interface file * -fbyte-code-and-object-code: Generate both byte code and object code when compiling a file * -fprefer-byte-code: Prefer to use byte-code if it's available when running TH splices. The goal for including the core bindings in an interface file is to be able to restart the compiler pipeline at the point just after simplification and before code generation. Once compilation is restarted then code can be created for the byte code backend. This can significantly speed up start-times for projects in GHCi. HLS already implements its own version of these extended interface files for this reason. Preferring to use byte-code means that we can avoid some potentially expensive code generation steps (see #21700) * Producing object code is much slower than producing bytecode, and normally you need to compile with `-dynamic-too` to produce code in the static and dynamic way, the dynamic way just for Template Haskell execution when using a dynamically linked compiler. * Linking many large object files, which happens once per splice, can be quite expensive compared to linking bytecode. And you can get GHC to compile the necessary byte code so `-fprefer-byte-code` has access to it by using `-fbyte-code-and-object-code`. Fixes #21067 - - - - - 9789ea8e by Matthew Pickering at 2022-10-11T12:48:45-04:00 Teach -fno-code about -fprefer-byte-code This patch teachs the code generation logic of -fno-code about -fprefer-byte-code, so that if we need to generate code for a module which prefers byte code, then we generate byte code rather than object code. We keep track separately which modules need object code and which byte code and then enable the relevant code generation for each. Typically the option will be enabled globally so one of these sets should be empty and we will just turn on byte code or object code generation. We also fix the bug where we would generate code for a module which enables Template Haskell despite the fact it was unecessary. Fixes #22016 - - - - - caced757 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Don't keep exit join points so much We were religiously keeping exit join points throughout, which had some bad effects (#21148, #22084). This MR does two things: * Arranges that exit join points are inhibited from inlining only in /one/ Simplifier pass (right after Exitification). See Note [Be selective about not-inlining exit join points] in GHC.Core.Opt.Exitify It's not a big deal, but it shaves 0.1% off compile times. * Inline used-once non-recursive join points very aggressively Given join j x = rhs in joinrec k y = ....j x.... where this is the only occurrence of `j`, we want to inline `j`. (Unless sm_keep_exits is on.) See Note [Inline used-once non-recursive join points] in GHC.Core.Opt.Simplify.Utils This is just a tidy-up really. It doesn't change allocation, but getting rid of a binding is always good. Very effect on nofib -- some up and down. - - - - - 284cf387 by Simon Peyton Jones at 2022-10-11T12:49:21-04:00 Make SpecConstr bale out less often When doing performance debugging on #22084 / !8901, I found that the algorithm in SpecConstr.decreaseSpecCount was so aggressive that if there were /more/ specialisations available for an outer function, that could more or less kill off specialisation for an /inner/ function. (An example was in nofib/spectral/fibheaps.) This patch makes it a bit more aggressive, by dividing by 2, rather than by the number of outer specialisations. This makes the program bigger, temporarily: T19695(normal) ghc/alloc +11.3% BAD because we get more specialisation. But lots of other programs compile a bit faster and the geometric mean in perf/compiler is 0.0%. Metric Increase: T19695 - - - - - 66af1399 by Cheng Shao at 2022-10-11T12:49:59-04:00 CmmToC: emit explicit tail calls when the C compiler supports it Clang 13+ supports annotating a return statement using the musttail attribute, which guarantees that it lowers to a tail call if compilation succeeds. This patch takes advantage of that feature for the unregisterised code generator. The configure script tests availability of the musttail attribute, if it's available, the Cmm tail calls will become C tail calls that avoids the mini interpreter trampoline overhead. Nothing is affected if the musttail attribute is not supported. Clang documentation: https://clang.llvm.org/docs/AttributeReference.html#musttail - - - - - 7f0decd5 by Matthew Pickering at 2022-10-11T12:50:40-04:00 Don't include BufPos in interface files Ticket #22162 pointed out that the build directory was leaking into the ABI hash of a module because the BufPos depended on the location of the build tree. BufPos is only used in GHC.Parser.PostProcess.Haddock, and the information doesn't need to be propagated outside the context of a module. Fixes #22162 - - - - - dce9f320 by Cheng Shao at 2022-10-11T12:51:19-04:00 CLabel: fix isInfoTableLabel isInfoTableLabel does not take Cmm info table into account. This patch is required for data section layout of wasm32 NCG to work. - - - - - da679f2e by Bodigrim at 2022-10-11T18:02:59-04:00 Extend documentation for Data.List, mostly wrt infinite lists - - - - - 9c099387 by jwaldmann at 2022-10-11T18:02:59-04:00 Expand comment for Data.List.permutations - - - - - d3863cb7 by Bodigrim at 2022-10-11T18:03:37-04:00 ByteArray# is unlifted, not unboxed - - - - - f6260e8b by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Add missing declaration of stg_noDuplicate - - - - - 69ccec2c by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move CString, CStringLen to GHC.Foreign - - - - - f6e8feb4 by Ben Gamari at 2022-10-11T23:45:10-04:00 base: Move IPE helpers to GHC.InfoProv - - - - - 866c736e by Ben Gamari at 2022-10-11T23:45:10-04:00 rts: Refactor IPE tracing support - - - - - 6b0d2022 by Ben Gamari at 2022-10-11T23:45:10-04:00 Refactor IPE initialization Here we refactor the representation of info table provenance information in object code to significantly reduce its size and link-time impact. Specifically, we deduplicate strings and represent them as 32-bit offsets into a common string table. In addition, we rework the registration logic to eliminate allocation from the registration path, which is run from a static initializer where things like allocation are technically undefined behavior (although it did previously seem to work). For similar reasons we eliminate lock usage from registration path, instead relying on atomic CAS. Closes #22077. - - - - - 9b572d54 by Ben Gamari at 2022-10-11T23:45:10-04:00 Separate IPE source file from span The source file name can very often be shared across many IPE entries whereas the source coordinates are generally unique. Separate the two to exploit sharing of the former. - - - - - 27978ceb by Krzysztof Gogolewski at 2022-10-11T23:45:46-04:00 Make Cmm Lint messages use dump style Lint errors indicate an internal error in GHC, so it makes sense to use it instead of the user style. This is consistent with Core Lint and STG Lint: https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Core/Lint.hs#L429 https://gitlab.haskell.org/ghc/ghc/-/blob/22096652/compiler/GHC/Stg/Lint.hs#L144 Fixes #22218. - - - - - 64a390d9 by Bryan Richter at 2022-10-12T09:52:51+03:00 Mark T7919 as fragile On x86_64-linux, T7919 timed out ~30 times during July 2022. And again ~30 times in September 2022. - - - - - 481467a5 by Ben Gamari at 2022-10-12T08:08:37-04:00 rts: Don't hint inlining of appendToRunQueue These hints have resulted in compile-time warnings due to failed inlinings for quite some time. Moreover, it's quite unlikely that inlining them is all that beneficial given that they are rather sizeable functions. Resolves #22280. - - - - - 81915089 by Curran McConnell at 2022-10-12T16:32:26-04:00 remove name shadowing - - - - - 626652f7 by Tamar Christina at 2022-10-12T16:33:13-04:00 winio: do not re-translate input when handle is uncooked - - - - - 5172789a by Charles Taylor at 2022-10-12T16:33:57-04:00 Unrestricted OverloadedLabels (#11671) Implements GHC proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst - - - - - ce293908 by Andreas Klebinger at 2022-10-13T05:58:19-04:00 Add a perf test for the generics code pattern from #21839. This code showed a strong shift between compile time (got worse) and run time (got a lot better) recently which is perfectly acceptable. However it wasn't clear why the compile time regression was happening initially so I'm adding this test to make it easier to track such changes in the future. - - - - - 78ab7afe by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Consolidate initializer/finalizer handling Here we extend our treatment of initializer/finalizer priorities to include ELF and in so doing refactor things to share the implementation with PEi386. As well, I fix a subtle misconception of the ordering behavior for `.ctors`. Fixes #21847. - - - - - 44692713 by Ben Gamari at 2022-10-13T05:58:56-04:00 rts/linker: Add support for .fini sections - - - - - beebf546 by Simon Hengel at 2022-10-13T05:59:37-04:00 Update phases.rst (the name of the original source file is $1, not $2) - - - - - eda6c05e by Finley McIlwaine at 2022-10-13T06:00:17-04:00 Clearer error msg for newtype GADTs with defaulted kind When a newtype introduces GADT eq_specs due to a defaulted RuntimeRep, we detect this and print the error message with explicit kinds. This also refactors newtype type checking to use the new diagnostic infra. Fixes #21447 - - - - - 43ab435a by Pierre Le Marre at 2022-10-14T07:45:43-04:00 Add standard Unicode case predicates isUpperCase and isLowerCase. These predicates use the standard Unicode case properties and are more intuitive than isUpper and isLower. Approved by CLC in https://github.com/haskell/core-libraries-committee/issues/90#issuecomment-1276649403. Fixes #14589 - - - - - aec5a443 by Bodigrim at 2022-10-14T07:46:21-04:00 Add type signatures in where-clause of Data.List.permutations The type of interleave' is very much revealing, otherwise it's extremely tough to decipher. - - - - - ee0deb80 by Ben Gamari at 2022-10-14T18:29:20-04:00 rts: Use pthread_setname_np correctly on Darwin As noted in #22206, pthread_setname_np on Darwin only supports setting the name of the calling thread. Consequently we must introduce a trampoline which first sets the thread name before entering the thread entrypoint. - - - - - 8eff62a4 by Ben Gamari at 2022-10-14T18:29:57-04:00 testsuite: Add test for #22282 This will complement mpickering's more general port of foundation's numerical testsuite, providing a test for the specific case found in #22282. - - - - - 62a55001 by Ben Gamari at 2022-10-14T18:29:57-04:00 ncg/aarch64: Fix sub-word sign extension yet again In adc7f108141a973b6dcb02a7836eed65d61230e8 we fixed a number of issues to do with sign extension in the AArch64 NCG found by ghc/test-primops>. However, this patch made a critical error, assuming that getSomeReg would allocate a fresh register for the result of its evaluation. However, this is not the case as `getSomeReg (CmmReg r) == r`. Consequently, any mutation of the register returned by `getSomeReg` may have unwanted side-effects on other expressions also mentioning `r`. In the fix listed above, this manifested as the registers containing the operands of binary arithmetic operations being incorrectly sign-extended. This resulted in #22282. Sadly, the rather simple structure of the tests generated by `test-primops` meant that this particular case was not exercised. Even more surprisingly, none of our testsuite caught this case. Here we fix this by ensuring that intermediate sign extension is performed in a fresh register. Fixes #22282. - - - - - 54e41b16 by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: ensure we are below maxHeapSize after returning megablocks When the heap is heavily block fragmented the live byte size might be low while the memory usage is high. We want to ensure that heap overflow triggers in these cases. We do so by checking that we can return enough megablocks to under maxHeapSize at the end of GC. - - - - - 29bb90db by Teo Camarasu at 2022-10-15T18:09:24+01:00 rts: trigger a major collection if megablock usage exceeds maxHeapSize When the heap is suffering from block fragmentation, live bytes might be low while megablock usage is high. If megablock usage exceeds maxHeapSize, we want to trigger a major GC to try to recover some memory otherwise we will die from a heapOverflow at the end of the GC. Fixes #21927 - - - - - 4a4641ca by Teo Camarasu at 2022-10-15T18:11:29+01:00 Add realease note for #21927 - - - - - c1e5719a by Sebastian Graf at 2022-10-17T11:58:46-04:00 DmdAnal: Look through unfoldings of DataCon wrappers (#22241) Previously, the demand signature we computed upfront for a DataCon wrapper lacked boxity information and was much less precise than the demand transformer for the DataCon worker. In this patch we adopt the solution to look through unfoldings of DataCon wrappers during Demand Analysis, but still attach a demand signature for other passes such as the Simplifier. See `Note [DmdAnal for DataCon wrappers]` for more details. Fixes #22241. - - - - - 8c72411d by Gergo ERDI at 2022-10-17T19:20:04-04:00 Add `Enum (Down a)` instance that swaps `succ` and `pred` See https://github.com/haskell/core-libraries-committee/issues/51 for discussion. The key points driving the implementation are the following two ideas: * For the `Int` type, `comparing (complement @Int)` behaves exactly as an order-swapping `compare @Int`. * `enumFrom @(Down a)` can be implemented in terms of `enumFromThen @a`, if only the corner case of starting at the very end is handled specially - - - - - d80ad2f4 by Alan Zimmerman at 2022-10-17T19:20:40-04:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 08ab5419 by Andreas Klebinger at 2022-10-17T19:21:15-04:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - ff6275ef by Andreas Klebinger at 2022-10-17T19:21:52-04:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - abb82f38 by Eric Lindblad at 2022-10-17T19:22:33-04:00 example rewrite - - - - - 39beb801 by Eric Lindblad at 2022-10-17T19:22:33-04:00 remove redirect - - - - - 0d9fb651 by Eric Lindblad at 2022-10-17T19:22:33-04:00 use heredoc - - - - - 0fa2d185 by Matthew Pickering at 2022-10-17T19:23:10-04:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - ced664a2 by Krzysztof Gogolewski at 2022-10-17T19:23:10-04:00 Fix T15155l not getting -fllvm - - - - - 0ac60423 by Andreas Klebinger at 2022-10-18T03:34:47-04:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 9ecd1ac0 by M Farkas-Dyck at 2022-10-18T03:35:38-04:00 Make `Functor` a superclass of `TrieMap`, which lets us derive the `map` functions. - - - - - f60244d7 by Ben Gamari at 2022-10-18T03:36:15-04:00 configure: Bump minimum bootstrap GHC version Fixes #22245 - - - - - ba4bd4a4 by Matthew Pickering at 2022-10-18T03:36:55-04:00 Build System: Remove out-of-date comment about make build system Both make and hadrian interleave compilation of modules of different modules and don't respect the package boundaries. Therefore I just remove this comment which points out this "difference". Fixes #22253 - - - - - e1bbd368 by Matthew Pickering at 2022-10-18T16:15:49+02:00 Allow configuration of error message printing This MR implements the idea of #21731 that the printing of a diagnostic method should be configurable at the printing time. The interface of the `Diagnostic` class is modified from: ``` class Diagnostic a where diagnosticMessage :: a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` to ``` class Diagnostic a where type DiagnosticOpts a defaultDiagnosticOpts :: DiagnosticOpts a diagnosticMessage :: DiagnosticOpts a -> a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` and so each `Diagnostic` can implement their own configuration record which can then be supplied by a client in order to dictate how to print out the error message. At the moment this only allows us to implement #21722 nicely but in future it is more natural to separate the configuration of how much information we put into an error message and how much we decide to print out of it. Updates Haddock submodule - - - - - 99dc3e3d by Matthew Pickering at 2022-10-18T16:15:53+02:00 Add -fsuppress-error-contexts to disable printing error contexts in errors In many development environments, the source span is the primary means of seeing what an error message relates to, and the In the expression: and In an equation for: clauses are not particularly relevant. However, they can grow to be quite long, which can make the message itself both feel overwhelming and interact badly with limited-space areas. It's simple to implement this flag so we might as well do it and give the user control about how they see their messages. Fixes #21722 - - - - - 5b3a992f by Dai at 2022-10-19T10:45:45-04:00 Add VecSlot for unboxed sums of SIMD vectors This patch adds the missing `VecRep` case to `primRepSlot` function and all the necessary machinery to carry this new `VecSlot` through code generation. This allows programs involving unboxed sums of SIMD vectors to be written and compiled. Fixes #22187 - - - - - 6d7d9181 by sheaf at 2022-10-19T10:45:45-04:00 Remove SIMD conversions This patch makes it so that packing/unpacking SIMD vectors always uses the right sized types, e.g. unpacking a Word16X4# will give a tuple of Word16#s. As a result, we can get rid of the conversion instructions that were previously required. Fixes #22296 - - - - - 3be48877 by sheaf at 2022-10-19T10:45:45-04:00 Cmm Lint: relax SIMD register assignment check As noted in #22297, SIMD vector registers can be used to store different kinds of values, e.g. xmm1 can be used both to store integer and floating point values. The Cmm type system doesn't properly account for this, so we weaken the Cmm register assignment lint check to only compare widths when comparing a vector type with its allocated vector register. - - - - - f7b7a312 by sheaf at 2022-10-19T10:45:45-04:00 Disable some SIMD tests on non-X86 architectures - - - - - 83638dce by M Farkas-Dyck at 2022-10-19T10:46:29-04:00 Scrub various partiality involving lists (again). Lets us avoid some use of `head` and `tail`, and some panics. - - - - - c3732c62 by M Farkas-Dyck at 2022-10-19T10:47:13-04:00 Enforce invariant of `ListBag` constructor. - - - - - 488d3631 by Bodigrim at 2022-10-19T10:47:52-04:00 More precise types for fields of OverlappingInstances and UnsafeOverlap in TcSolverReportMsg It's clear from asserts in `GHC.Tc.Errors` that `overlappingInstances_matches` and `unsafeOverlapped` are supposed to be non-empty, and `unsafeOverlap_matches` contains a single instance, but these invariants are immediately lost afterwards and not encoded in types. This patch enforces the invariants by pattern matching and makes types more precise, avoiding asserts and partial functions such as `head`. - - - - - 607ce263 by sheaf at 2022-10-19T10:47:52-04:00 Rename unsafeOverlap_matches -> unsafeOverlap_match in UnsafeOverlap - - - - - 1fab9598 by Matthew Pickering at 2022-10-19T10:48:29-04:00 Add SpliceTypes test for hie files This test checks that typed splices and quotes get the right type information when used in hiefiles. See #21619 - - - - - a8b52786 by Jan Hrček at 2022-10-19T10:49:09-04:00 Small language fixes in 'Using GHC' - - - - - 1dab1167 by Gergő Érdi at 2022-10-19T10:49:51-04:00 Fix typo in `Opt_WriteIfSimplifiedCore`'s name - - - - - b17cfc9c by sheaf at 2022-10-19T10:50:37-04:00 TyEq:N assertion: only for saturated applications The assertion that checked TyEq:N in canEqCanLHSFinish incorrectly triggered in the case of an unsaturated newtype TyCon heading the RHS, even though we can't unwrap such an application. Now, we only trigger an assertion failure in case of a saturated application of a newtype TyCon. Fixes #22310 - - - - - ff6f2228 by M Farkas-Dyck at 2022-10-20T16:15:51-04:00 CoreToStg: purge `DynFlags`. - - - - - 1ebd521f by Matthew Pickering at 2022-10-20T16:16:27-04:00 ci: Make fat014 test robust For some reason I implemented this as a makefile test rather than a ghci_script test. Hopefully making it a ghci_script test makes it more robust. Fixes #22313 - - - - - 8cd6f435 by Curran McConnell at 2022-10-21T02:58:01-04:00 remove a no-warn directive from GHC.Cmm.ContFlowOpt This patch is motivated by the desire to remove the {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} directive at the top of GHC.Cmm.ContFlowOpt. (Based on the text in this coding standards doc, I understand it's a goal of the project to remove such directives.) I chose this task because I'm a new contributor to GHC, and it seemed like a good way to get acquainted with the patching process. In order to address the warning that arose when I removed the no-warn directive, I added a case to removeUnreachableBlocksProc to handle the CmmData constructor. Clearly, since this partial function has not been erroring out in the wild, its inputs are always in practice wrapped by the CmmProc constructor. Therefore the CmmData case is handled by a precise panic (which is an improvement over the partial pattern match from before). - - - - - a2af7c4c by Nicolas Trangez at 2022-10-21T02:58:39-04:00 build: get rid of `HAVE_TIME_H` As advertized by `autoreconf`: > All current systems provide time.h; it need not be checked for. Hence, remove the check for it in `configure.ac` and remove conditional inclusion of the header in `HAVE_TIME_H` blocks where applicable. The `time.h` header was being included in various source files without a `HAVE_TIME_H` guard already anyway. - - - - - 25cdc630 by Nicolas Trangez at 2022-10-21T02:58:39-04:00 rts: remove use of `TIME_WITH_SYS_TIME` `autoreconf` will insert an `m4_warning` when the obsolescent `AC_HEADER_TIME` macro is used: > Update your code to rely only on HAVE_SYS_TIME_H, > then remove this warning and the obsolete code below it. > All current systems provide time.h; it need not be checked for. > Not all systems provide sys/time.h, but those that do, all allow > you to include it and time.h simultaneously. Presence of `sys/time.h` was already checked in an earlier `AC_CHECK_HEADERS` invocation, so `AC_HEADER_TIME` can be dropped and guards relying on `TIME_WITH_SYS_TIME` can be reworked to (unconditionally) include `time.h` and include `sys/time.h` based on `HAVE_SYS_TIME_H`. Note the documentation of `AC_HEADER_TIME` in (at least) Autoconf 2.67 says > This macro is obsolescent, as current systems can include both files > when they exist. New programs need not use this macro. - - - - - 1fe7921c by Eric Lindblad at 2022-10-21T02:59:21-04:00 runhaskell - - - - - e3b3986e by David Feuer at 2022-10-21T03:00:00-04:00 Document how to quote certain names with spaces Quoting a name for Template Haskell is a bit tricky if the second character of that name is a single quote. The User's Guide falsely claimed that it was impossible. Document how to do it. Fixes #22236 - - - - - 0eba81e8 by Krzysztof Gogolewski at 2022-10-21T03:00:00-04:00 Fix syntax - - - - - a4dbd102 by Ben Gamari at 2022-10-21T09:11:12-04:00 Fix manifest filename when writing Windows .rc files As noted in #12971, we previously used `show` which resulted in inappropriate escaping of non-ASCII characters. - - - - - 30f0d9a9 by Ben Gamari at 2022-10-21T09:11:12-04:00 Write response files in UTF-8 on Windows This reverts the workaround introduced in f63c8ef33ec9666688163abe4ccf2d6c0428a7e7, which taught our response file logic to write response files with the `latin1` encoding to workaround `gcc`'s lacking Unicode support. This is now no longer necessary (and in fact actively unhelpful) since we rather use Clang. - - - - - b8304648 by M Farkas-Dyck at 2022-10-21T09:11:56-04:00 Scrub some partiality in `GHC.Core.Opt.Simplify.Utils`. - - - - - 09ec7de2 by Teo Camarasu at 2022-10-21T13:23:07-04:00 template-haskell: Improve documentation of strictness annotation types Before it was undocumentated that DecidedLazy can be returned by reifyConStrictness for strict fields. This can happen when a field has an unlifted type or its the single field of a newtype constructor. Fixes #21380 - - - - - 88172069 by M Farkas-Dyck at 2022-10-21T13:23:51-04:00 Delete `eqExpr`, since GHC 9.4 has been released. - - - - - 86e6549e by Ömer Sinan Ağacan at 2022-10-22T07:41:30-04:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const 0; // padding for indirectee const 0; // static link const 0; // saved info const hey1_r1Gg_bytes; // the payload } This is much smaller in code. Metric Decrease: T10421 T11195 T12150 T12425 T16577 T18282 T18698a T18698b Co-Authored By: Ben Gamari <ben at well-typed.com> - - - - - 1937016b by Andreas Klebinger at 2022-10-22T07:42:06-04:00 hadrian: Improve error for wrong key/value errors. - - - - - 11fe42d8 by Vladislav Zavialov at 2022-10-23T00:11:50+03:00 Class layout info (#19623) Updates the haddock submodule. - - - - - f0a90c11 by Sven Tennie at 2022-10-24T00:12:51-04:00 Pin used way for test cloneMyStack (#21977) cloneMyStack checks the order of closures on the cloned stack. This may change for different ways. Thus we limit this test to one way (normal). - - - - - 0614e74d by Aaron Allen at 2022-10-24T17:11:21+02:00 Convert Diagnostics in GHC.Tc.Gen.Splice (#20116) Replaces uses of `TcRnUnknownMessage` in `GHC.Tc.Gen.Splice` with structured diagnostics. closes #20116 - - - - - 8d2dbe2d by Andreas Klebinger at 2022-10-24T15:59:41-04:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 41406da5 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 5a997e16 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 7f203d00 by Sylvain Henry at 2022-10-25T18:07:43-04:00 Numeric exceptions: replace FFI calls with primops ghc-bignum needs a way to raise numerical exceptions defined in base package. At the time we used FFI calls into primops defined in the RTS. These FFI calls had to be wrapped into hacky bottoming functions because "foreign import prim" syntax doesn't support giving a bottoming demand to the foreign call (cf #16929). These hacky wrapper functions trip up the JavaScript backend (#21078) because they are polymorphic in their return type. This commit replaces them with primops very similar to raise# but raising predefined exceptions. - - - - - 0988a23d by Sylvain Henry at 2022-10-25T18:08:24-04:00 Enable popcount rewrite rule when cross-compiling The comment applies only when host's word size < target's word size. So we can relax the guard. - - - - - a2f53ac8 by Sylvain Henry at 2022-10-25T18:09:05-04:00 Add GHC.SysTools.Cpp module Move doCpp out of the driver to be able to use it in the upcoming JS backend. - - - - - 1fd7f201 by Ben Gamari at 2022-10-25T18:09:42-04:00 llvm-targets: Add datalayouts for big-endian AArch64 targets Fixes #22311. Thanks to @zeldin for the patch. - - - - - f5a486eb by Krzysztof Gogolewski at 2022-10-25T18:10:19-04:00 Cleanup String/FastString conversions Remove unused mkPtrString and isUnderscoreFS. We no longer use mkPtrString since 1d03d8bef96. Remove unnecessary conversions between FastString and String and back. - - - - - f7bfb40c by Ryan Scott at 2022-10-26T00:01:24-04:00 Broaden the in-scope sets for liftEnvSubst and composeTCvSubst This patch fixes two distinct (but closely related) buglets that were uncovered in #22235: * `liftEnvSubst` used an empty in-scope set, which was not wide enough to cover the variables in the range of the substitution. This patch fixes this by populating the in-scope set from the free variables in the range of the substitution. * `composeTCvSubst` applied the first substitution argument to the range of the second substitution argument, but the first substitution's in-scope set was not wide enough to cover the range of the second substutition. We similarly fix this issue in this patch by widening the first substitution's in-scope set before applying it. Fixes #22235. - - - - - 0270cc54 by Vladislav Zavialov at 2022-10-26T00:02:01-04:00 Introduce TcRnWithHsDocContext (#22346) Before this patch, GHC used withHsDocContext to attach an HsDocContext to an error message: addErr $ mkTcRnUnknownMessage $ mkPlainError noHints (withHsDocContext ctxt msg) The problem with this approach is that it only works with TcRnUnknownMessage. But could we attach an HsDocContext to a structured error message in a generic way? This patch solves the problem by introducing a new constructor to TcRnMessage: data TcRnMessage where ... TcRnWithHsDocContext :: !HsDocContext -> !TcRnMessage -> TcRnMessage ... - - - - - 9ab31f42 by Sylvain Henry at 2022-10-26T09:32:20+02:00 Testsuite: more precise test options Necessary for newer cross-compiling backends (JS, Wasm) that don't support TH yet. - - - - - f60a1a62 by Vladislav Zavialov at 2022-10-26T12:17:14-04:00 Use TcRnVDQInTermType in noNestedForallsContextsErr (#20115) When faced with VDQ in the type of a term, GHC generates the following error message: Illegal visible, dependent quantification in the type of a term (GHC does not yet support this) Prior to this patch, there were two ways this message could have been generated and represented: 1. with the dedicated constructor TcRnVDQInTermType (see check_type in GHC.Tc.Validity) 2. with the transitional constructor TcRnUnknownMessage (see noNestedForallsContextsErr in GHC.Rename.Utils) Not only this led to duplication of code generating the final SDoc, it also made it tricky to track the origin of the error message. This patch fixes the problem by using TcRnVDQInTermType exclusively. - - - - - 223e159d by Owen Shepherd at 2022-10-27T13:54:33-04:00 Remove source location information from interface files This change aims to minimize source location information leaking into interface files, which makes ABI hashes dependent on the build location. The `Binary (Located a)` instance has been removed completely. It seems that the HIE interface still needs the ability to serialize SrcSpans, but by wrapping the instances, it should be a lot more difficult to inadvertently add source location information. - - - - - 22e3deb9 by Simon Peyton Jones at 2022-10-27T13:55:37-04:00 Add missing dict binds to specialiser I had forgotten to add the auxiliary dict bindings to the /unfolding/ of a specialised function. This caused #22358, which reports failures when compiling Hackage packages fixed-vector indexed-traversable Regression test T22357 is snarfed from indexed-traversable - - - - - a8ed36f9 by Evan Relf at 2022-10-27T13:56:36-04:00 Fix broken link to `async` package - - - - - 750846cd by Zubin Duggal at 2022-10-28T00:49:22-04:00 Pass correct package db when testing stage1. It used to pick the db for stage-2 which obviously didn't work. - - - - - ad612f55 by Krzysztof Gogolewski at 2022-10-28T00:50:00-04:00 Minor SDoc-related cleanup * Rename pprCLabel to pprCLabelStyle, and use the name pprCLabel for a function using CStyle (analogous to pprAsmLabel) * Move LabelStyle to the CLabel module, it no longer needs to be in Outputable. * Move calls to 'text' right next to literals, to make sure the text/str rule is triggered. * Remove FastString/String roundtrip in Tc.Deriv.Generate * Introduce showSDocForUser', which abstracts over a pattern in GHCi.UI - - - - - c2872f3f by Bryan Richter at 2022-10-28T11:36:34+03:00 CI: Don't run lint-submods on nightly Fixes #22325 - - - - - 270037fa by Hécate Moonlight at 2022-10-28T19:46:12-04:00 Start the deprecation process for GHC.Pack - - - - - d45d8cb3 by M Farkas-Dyck at 2022-11-01T12:47:21-04:00 Drop a kludge for binutils<2.17, which is now over 10 years old. - - - - - 8ee8b418 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: `name` argument of `createOSThread` can be `const` Since we don't intend to ever change the incoming string, declare this to be true. Also, in the POSIX implementation, the argument is no longer `STG_UNUSED` (since ee0deb8054da2a597fc5624469b4c44fd769ada2) in any code path. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 - - - - - 13b5f102 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix lifetime of `start_thread`s `name` value Since, unlike the code in ee0deb8054da2^, usage of the `name` value passed to `createOSThread` now outlives said function's lifetime, and could hence be released by the caller by the time the new thread runs `start_thread`, it needs to be copied. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - edd175c9 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix OS thread naming in ticker Since ee0deb805, the use of `pthread_setname_np` on Darwin was fixed when invoking `createOSThread`. However, the 'ticker' has some thread-creation code which doesn't rely on `createOSThread`, yet also uses `pthread_setname_np`. This patch enforces all thread creation to go through a single function, which uses the (correct) thread-naming code introduced in ee0deb805. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22206 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - b7a00113 by Krzysztof Gogolewski at 2022-11-01T12:48:35-04:00 Typo: rename -fwrite-if-simplfied-core to -fwrite-if-simplified-core - - - - - 30e625e6 by Vladislav Zavialov at 2022-11-01T12:49:10-04:00 ThToHs: fix overzealous parenthesization Before this patch, when converting from TH.Exp to LHsExpr GhcPs, the compiler inserted more parentheses than required: ((f a) (b + c)) d This was happening because the LHS of the function application was parenthesized as if it was the RHS. Now we use funPrec and appPrec appropriately and produce sensibly parenthesized expressions: f a (b + c) d I also took the opportunity to remove the special case for LamE, which was not special at all and simply duplicated code. - - - - - 0560821f by Simon Peyton Jones at 2022-11-01T12:49:47-04:00 Add accurate skolem info when quantifying Ticket #22379 revealed that skolemiseQuantifiedTyVar was dropping the passed-in skol_info on the floor when it encountered a SkolemTv. Bad! Several TyCons thereby share a single SkolemInfo on their binders, which lead to bogus error reports. - - - - - 38d19668 by Fendor at 2022-11-01T12:50:25-04:00 Expose UnitEnvGraphKey for user-code - - - - - 77e24902 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Shrink test case for #22357 Ryan Scott offered a cut-down repro case (60 lines instead of more than 700 lines) - - - - - 4521f649 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Add two tests for #17366 - - - - - 6b400d26 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_NORETURN` Instead of sprinkling the codebase with `GNU(C3)_ATTRIBUTE(__noreturn__)`, add a `STG_NORETURN` macro (for, basically, the same thing) similar to `STG_UNUSED` and others, and update the code to use this macro where applicable. - - - - - f9638654 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: consistently use `STG_UNUSED` - - - - - 81a58433 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_USED` Similar to `STG_UNUSED`, have a specific macro for `__attribute__(used)`. - - - - - 41e1f748 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_MALLOC` Instead of using `GNUC3_ATTRIBUTE(__malloc__)`, provide a `STG_MALLOC` macro definition and use it instead. - - - - - 3a9a8bde by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `STG_UNUSED` - - - - - 9ab999de by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: specify deallocator of allocating functions This patch adds a new `STG_MALLOC1` macro (and its counterpart `STG_MALLOC2` for completeness) which allows to specify the deallocation function to be used with allocations of allocating functions, and applies it to `stg*allocBytes`. It also fixes a case where `free` was used to free up an `stgMallocBytes` allocation, found by the above change. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 81c0c7c9 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `alloc_size` attribute This patch adds the `STG_ALLOC_SIZE1` and `STG_ALLOC_SIZE2` macros which allow to set the `alloc_size` attribute on functions, when available. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 99a1d896 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: add and use `STG_RETURNS_NONNULL` See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - c235b399 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: tag `stgStrndup` as `STG_MALLOC` See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - ed81b448 by Oleg Grenrus at 2022-11-02T12:07:27-04:00 Move Symbol implementation note out of public haddock - - - - - 284fd39c by Ben Gamari at 2022-11-03T01:58:54-04:00 gen-dll: Drop it Currently it is only used by the make build system, which is soon to be retired, and it has not built since 41cf758b. We may need to reintroduce it when dynamic-linking support is introduced on Windows, but we will cross that bridge once we get there. Fixes #21753. - - - - - 24f4f54f by Matthew Pickering at 2022-11-03T01:59:30-04:00 Port foundation numeric tests to GHC testsuite This commit ports the numeric tests which found a regression in GHC-9.4. https://github.com/haskell-foundation/foundation/issues/571 Included in the commit is a simple random number generator and simplified QuickCheck implementation. In future these could be factored out of this standalone file and reused as a general purpose library which could be used for other QuickCheck style tests in the testsuite. See #22282 - - - - - d51bf7bd by M Farkas-Dyck at 2022-11-03T02:00:13-04:00 git: ignore HIE files. Cleans up git status if one sets -fwrite-ide-info in hadrian/ghci. - - - - - a9fc15b1 by Matthew Pickering at 2022-11-03T02:00:49-04:00 Clarify status of bindings in WholeCoreBindings Gergo points out that these bindings are tidied, rather than prepd as the variable claims. Therefore we update the name of the variable to reflect reality and add a comment to the data type to try to erase any future confusion. Fixes #22307 - - - - - 634da448 by Bodigrim at 2022-11-03T21:25:02+00:00 Fix haddocks for GHC.IORef - - - - - 31125154 by Andreas Klebinger at 2022-11-03T23:08:09-04:00 Export pprTrace and friends from GHC.Prelude. Introduces GHC.Prelude.Basic which can be used in modules which are a dependency of the ppr code. - - - - - bdc8cbb3 by Bryan Richter at 2022-11-04T10:27:37+02:00 CI: Allow hadrian-ghc-in-ghci to run in nightlies Since lint-submods doesn't run in nightlies, hadrian-ghc-in-ghci needs to mark it as "optional" so it can run if the job doesn't exist. Fixes #22396. - - - - - 3c0e3793 by Krzysztof Gogolewski at 2022-11-05T00:29:57-04:00 Minor refactor around FastStrings Pass FastStrings to functions directly, to make sure the rule for fsLit "literal" fires. Remove SDoc indirection in GHCi.UI.Tags and GHC.Unit.Module.Graph. - - - - - e41b2f55 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump unix submodule to 2.8.0.0 Also bumps process and ghc-boot bounds on unix. For hadrian, when cross-compiling, we add -Wwarn=unused-imports -Wwarn=unused-top-binds to validation flavour. Further fixes in unix and/or hsc2hs is needed to make it completely free of warnings; for the time being, this change is needed to unblock other cross-compilation related work. - - - - - 42938a58 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump Win32 submodule to 2.13.4.0 Fixes #22098 - - - - - e7372bc5 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump ci-images revision ci-images has recently been updated, including changes needed for wasm32-wasi CI. - - - - - 88cb9492 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump gmp-tarballs submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 69427ce9 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump haskeline submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 5fe11fe6 by Carter Schonwald at 2022-11-07T13:22:14-05:00 bump llvm upper bound - - - - - 68f49874 by M Farkas-Dyck at 2022-11-08T12:53:55-05:00 Define `Infinite` list and use where appropriate. Also add perf test for infinite list fusion. In particular, in `GHC.Core`, often we deal with infinite lists of roles. Also in a few locations we deal with infinite lists of names. Thanks to simonpj for helping to write the Note [Fusion for `Infinite` lists]. - - - - - ce726cd2 by Ross Paterson at 2022-11-08T12:54:34-05:00 Fix TypeData issues (fixes #22315 and #22332) There were two bugs here: 1. Treating type-level constructors as PromotedDataCon doesn't always work, in particular because constructors promoted via DataKinds are called both T and 'T. (Tests T22332a, T22332b, T22315a, T22315b) Fix: guard these cases with isDataKindsPromotedDataCon. 2. Type-level constructors were sent to the code generator, producing things like constructor wrappers. (Tests T22332a, T22332b) Fix: test for them in isDataTyCon. Other changes: * changed the marking of "type data" DataCon's as suggested by SPJ. * added a test TDGADT for a type-level GADT. * comment tweaks * change tcIfaceTyCon to ignore IfaceTyConInfo, so that IfaceTyConInfo is used only for pretty printing, not for typechecking. (SPJ) - - - - - 132f8908 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Clarify msum/asum documentation - - - - - bb5888c5 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Add example for (<$) - - - - - 080fffa1 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Document what Alternative/MonadPlus instances actually do - - - - - 92ccb8de by Giles Anderson at 2022-11-09T09:27:52-05:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Instance (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnWarnUnsatisfiedMinimalDefinition TcRnMisplacedInstSig TcRnBadBootFamInstDeclErr TcRnIllegalFamilyInstance TcRnAssocInClassErr TcRnBadFamInstDecl TcRnNotOpenFamily - - - - - 90c5abd4 by Hécate Moonlight at 2022-11-09T09:28:30-05:00 GHCi tags generation phase 2 see #19884 - - - - - f9f17b68 by Simon Peyton Jones at 2022-11-10T12:20:03+00:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. The reorganisation in the Simplifier improve compile times a bit (geom mean -0.1%), but T9961 is an outlier Metric Decrease: T9961 - - - - - 2b3d0bee by Simon Peyton Jones at 2022-11-10T12:21:13+00:00 Make indexError work better The problem here is described at some length in Note [Boxity for bottoming functions] and Note [Reboxed crud for bottoming calls] in GHC.Core.Opt.DmdAnal. This patch adds a SPECIALISE pragma for indexError, which makes it much less vulnerable to the problem described in these Notes. (This came up in another line of work, where a small change made indexError do reboxing (in nofib/spectral/simple/table_sort) that didn't happen before my change. I've opened #22404 to document the fagility. - - - - - 399e921b by Simon Peyton Jones at 2022-11-10T12:21:14+00:00 Fix DsUselessSpecialiseForClassMethodSelector msg The error message for DsUselessSpecialiseForClassMethodSelector was just wrong (a typo in some earlier work); trivial fix - - - - - dac0682a by Sebastian Graf at 2022-11-10T21:16:01-05:00 WorkWrap: Unboxing unboxed tuples is not always useful (#22388) See Note [Unboxing through unboxed tuples]. Fixes #22388. - - - - - 1230c268 by Sebastian Graf at 2022-11-10T21:16:01-05:00 Boxity: Handle argument budget of unboxed tuples correctly (#21737) Now Budget roughly tracks the combined width of all arguments after unarisation. See the changes to `Note [Worker argument budgets]`. Fixes #21737. - - - - - 2829fd92 by Cheng Shao at 2022-11-11T00:26:54-05:00 autoconf: check getpid getuid raise This patch adds checks for getpid, getuid and raise in autoconf. These functions are absent in wasm32-wasi and thus needs to be checked. - - - - - f5dfd1b4 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add -Wwarn only for cross-compiling unix - - - - - 2e6ab453 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add targetSupportsThreadedRts flag This patch adds a targetSupportsThreadedRts flag to indicate whether the target supports the threaded rts at all, different from existing targetSupportsSMP that checks whether -N is supported by the RTS. All existing flavours have also been updated accordingly to respect this flags. Some targets (e.g. wasm32-wasi) does not support the threaded rts, therefore this flag is needed for the default flavours to work. It makes more sense to have proper autoconf logic to check for threading support, but for the time being, we just set the flag to False iff the target is wasm32. - - - - - 8104f6f5 by Cheng Shao at 2022-11-11T00:26:55-05:00 Fix Cmm symbol kind - - - - - b2035823 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add the two key graph modules from Martin Erwig's FGL Martin Erwig's FGL (Functional Graph Library) provides an "inductive" representation of graphs. A general graph has labeled nodes and labeled edges. The key operation on a graph is to decompose it by removing one node, together with the edges that connect the node to the rest of the graph. There is also an inverse composition operation. The decomposition and composition operations make this representation of graphs exceptionally well suited to implement graph algorithms in which the graph is continually changing, as alluded to in #21259. This commit adds `GHC.Data.Graph.Inductive.Graph`, which defines the interface, and `GHC.Data.Graph.Inductive.PatriciaTree`, which provides an implementation. Both modules are taken from `fgl-5.7.0.3` on Hackage, with these changes: - Copyright and license text have been copied into the files themselves, not stored separately. - Some calls to `error` have been replaced with calls to `panic`. - Conditional-compilation support for older versions of GHC, `containers`, and `base` has been removed. - - - - - 3633a5f5 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add new modules for reducibility and WebAssembly translation - - - - - df7bfef8 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add support for the wasm32-wasi target tuple This patch adds the wasm32-wasi tuple support to various places in the tree: autoconf, hadrian, ghc-boot and also the compiler. The codegen logic will come in subsequent commits. - - - - - 32ae62e6 by Cheng Shao at 2022-11-11T00:26:55-05:00 deriveConstants: parse .ll output for wasm32 due to broken nm This patch makes deriveConstants emit and parse an .ll file when targeting wasm. It's a necessary workaround for broken llvm-nm on wasm, which isn't capable of reporting correct constant values when parsing an object. - - - - - 07e92c92 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: workaround cmm's improper variadic ccall breaking wasm32 typechecking Unlike other targets, wasm requires the function signature of the call site and callee to strictly match. So in Cmm, when we call a C function that actually returns a value, we need to add an _unused local variable to receive it, otherwise type error awaits. An even bigger problem is calling variadic functions like barf() and such. Cmm doesn't support CAPI calling convention yet, so calls to variadic functions just happen to work in some cases with some target's ABI. But again, it doesn't work with wasm. Fortunately, the wasm C ABI lowers varargs to a stack pointer argument, and it can be passed NULL when no other arguments are expected to be passed. So we also add the additional unused NULL arguments to those functions, so to fix wasm, while not affecting behavior on other targets. - - - - - 00124d12 by Cheng Shao at 2022-11-11T00:26:55-05:00 testsuite: correct sleep() signature in T5611 In libc, sleep() returns an integer. The ccall type signature should match the libc definition, otherwise it causes linker error on wasm. - - - - - d72466a9 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: prefer ffi_type_void over FFI_TYPE_VOID This patch uses ffi_type_void instead of FFI_TYPE_VOID in the interpreter code, since the FFI_TYPE_* macros are not available in libffi-wasm32 yet. The libffi public documentation also only mentions the lower-case ffi_type_* symbols, so we should prefer the lower-case API here. - - - - - 4d36a1d3 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't define RTS_USER_SIGNALS when signal.h is not present In the rts, we have a RTS_USER_SIGNALS macro, and most signal-related logic is guarded with RTS_USER_SIGNALS. This patch extends the range of code guarded with RTS_USER_SIGNALS, and define RTS_USER_SIGNALS iff signal.h is actually detected by autoconf. This is required for wasm32-wasi to work, which lacks signals. - - - - - 3f1e164f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: use HAVE_GETPID to guard subprocess related logic We've previously added detection of getpid() in autoconf. This patch uses HAVE_GETPID to guard some subprocess related logic in the RTS. This is required for certain targets like wasm32-wasi, where there isn't a process model at all. - - - - - 50bf5e77 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: IPE.c: don't do mutex stuff when THREADED_RTS is not defined This patch adds the missing THREADED_RTS CPP guard to mutex logic in IPE.c. - - - - - ed3b3da0 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: genericRaise: use exit() instead when not HAVE_RAISE We check existence of raise() in autoconf, and here, if not HAVE_RAISE, we should use exit() instead in genericRaise. - - - - - c0ba1547 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: checkSuid: don't do it when not HAVE_GETUID When getuid() is not present, don't do checkSuid since it doesn't make sense anyway on that target. - - - - - d2d6dfd2 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 placeholder linker This patch adds minimal placeholder linker logic for wasm32, just enough to unblock compiling rts on wasm32. RTS linker functionality is not properly implemented yet for wasm32. - - - - - 65ba3285 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: chdir to PWD on wasm32 This patch adds a wasm32-specific behavior to RtsStartup logic. When the PWD environment variable is present, we chdir() to it first. The point is to workaround an issue in wasi-libc: it's currently not possible to specify the initial working directory, it always defaults to / (in the virtual filesystem mapped from some host directory). For some use cases this is sufficient, but there are some other cases (e.g. in the testsuite) where the program needs to access files outside. - - - - - 65b82542 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: no timer for wasm32 Due to the lack of threads, on wasm32 there can't be a background timer that periodically resets the context switch flag. This patch disables timer for wasm32, and also makes the scheduler default to -C0 on wasm32 to avoid starving threads. - - - - - e007586f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsSymbols: empty RTS_POSIX_ONLY_SYMBOLS for wasm32 The default RTS_POSIX_ONLY_SYMBOLS doesn't make sense on wasm32. - - - - - 0e33f667 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: Schedule: no FORKPROCESS_PRIMOP_SUPPORTED on wasm32 On wasm32 there isn't a process model at all, so no FORKPROCESS_PRIMOP_SUPPORTED. - - - - - 88bbdb31 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: LibffiAdjustor: adapt to ffi_alloc_prep_closure interface for wasm32 libffi-wasm32 only supports non-standard libffi closure api via ffi_alloc_prep_closure(). This patch implements ffi_alloc_prep_closure() via standard libffi closure api on other targets, and uses it to implement adjustor functionality. - - - - - 15138746 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't return memory to OS on wasm32 This patch makes the storage manager not return any memory on wasm32. The detailed reason is described in Note [Megablock allocator on wasm]. - - - - - 631af3cc by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: make flushExec a no-op on wasm32 This patch makes flushExec a no-op on wasm32, since there's no such thing as executable memory on wasm32 in the first place. - - - - - 654a3d46 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: don't call resetTerminalSettings, freeThreadingResources on wasm32 This patch prevents resetTerminalSettings and freeThreadingResources to be called on wasm32, since there is no TTY or threading on wasm32 at all. - - - - - f271e7ca by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: OSThreads.h: stub types for wasm32 This patch defines stub Condition/Mutex/OSThreadId/ThreadLocalKey types for wasm32, just enough to unblock compiling RTS. Any threading-related functionality has been patched to be disabled on wasm32. - - - - - a6ac67b0 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add register mapping for wasm32 This patch adds register mapping logic for wasm32. See Note [Register mapping on WebAssembly] in wasm32 NCG for more description. - - - - - d7b33982 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 specific logic This patch adds the rest of wasm32 specific logic in rts. - - - - - 7f59b0f3 by Cheng Shao at 2022-11-11T00:26:55-05:00 base: fall back to using monotonic clock to emulate cputime on wasm32 On wasm32, we have to fall back to using monotonic clock to emulate cputime, since there's no native support for cputime as a clock id. - - - - - 5fcbae0b by Cheng Shao at 2022-11-11T00:26:55-05:00 base: more autoconf checks for wasm32 This patch adds more autoconf checks to base, since those functions and headers may exist on other POSIX systems but don't exist on wasm32. - - - - - 00a9359f by Cheng Shao at 2022-11-11T00:26:55-05:00 base: avoid using unsupported posix functionality on wasm32 This base patch avoids using unsupported posix functionality on wasm32. - - - - - 34b8f611 by Cheng Shao at 2022-11-11T00:26:55-05:00 autoconf: set CrossCompiling=YES in cross bindist configure This patch fixes the bindist autoconf logic to properly set CrossCompiling=YES when it's a cross GHC bindist. - - - - - 5ebeaa45 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: add util functions for UniqFM and UniqMap This patch adds addToUFM_L (backed by insertLookupWithKey), addToUniqMap_L and intersectUniqMap_C. These UniqFM/UniqMap util functions are used by the wasm32 NCG. - - - - - 177c56c1 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: avoid -Wl,--no-as-needed for wasm32 The driver used to pass -Wl,--no-as-needed for LLD linking. This is actually only supported for ELF targets, and must be avoided when linking for wasm32. - - - - - 06f01c74 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: allow big arith for wasm32 This patch enables Cmm big arithmetic on wasm32, since 64-bit arithmetic can be efficiently lowered to wasm32 opcodes. - - - - - df6bb112 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: pass -Wa,--no-type-check for wasm32 when runAsPhase This patch passes -Wa,--no-type-check for wasm32 when compiling assembly. See the added note for more detailed explanation. - - - - - c1fe4ab6 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: enforce cmm switch planning for wasm32 This patch forcibly enable Cmm switch planning for wasm32, since otherwise the switch tables we generate may exceed the br_table maximum allowed size. - - - - - a8adc71e by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: annotate CmmFileEmbed with blob length This patch adds the blob length field to CmmFileEmbed. The wasm32 NCG needs to know the precise size of each data segment. - - - - - 36340328 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: wasm32 NCG This patch adds the wasm32 NCG. - - - - - 435f42ea by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add wasm32-wasi release bindist job - - - - - d8262fdc by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add a stronger test for cross bindists This commit adds a simple GHC API program that parses and reprints the original hello world program used for basic testing of cross bindists. Before there's full cross-compilation support in the test suite driver, this provides better coverage than the original test. - - - - - 8e6ae882 by Cheng Shao at 2022-11-11T00:26:55-05:00 CODEOWNERS: add wasm-specific maintainers - - - - - 707d5651 by Zubin Duggal at 2022-11-11T00:27:31-05:00 Clarify that LLVM upper bound is non-inclusive during configure (#22411) - - - - - 430eccef by Ben Gamari at 2022-11-11T13:16:45-05:00 rts: Check for program_invocation_short_name via autoconf Instead of assuming support on all Linuxes. - - - - - 6dab0046 by Matthew Pickering at 2022-11-11T13:17:22-05:00 driver: Fix -fdefer-diagnostics flag The `withDeferredDiagnostics` wrapper wasn't doing anything because the session it was modifying wasn't used in hsc_env. Therefore the fix is simple, just push the `getSession` call into the scope of `withDeferredDiagnostics`. Fixes #22391 - - - - - d0c691b6 by Simon Peyton Jones at 2022-11-11T13:18:07-05:00 Add a fast path for data constructor workers See Note [Fast path for data constructors] in GHC.Core.Opt.Simplify.Iteration This bypasses lots of expensive logic, in the special case of applications of data constructors. It is a surprisingly worthwhile improvement, as you can see in the figures below. Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Read(normal) -2.0% CoOpt_Singletons(normal) -2.0% ManyConstructors(normal) -1.3% T10421(normal) -1.9% GOOD T10421a(normal) -1.5% T10858(normal) -1.6% T11545(normal) -1.7% T12234(optasm) -1.3% T12425(optasm) -1.9% GOOD T13035(normal) -1.0% GOOD T13056(optasm) -1.8% T13253(normal) -3.3% GOOD T15164(normal) -1.7% T15304(normal) -3.4% T15630(normal) -2.8% T16577(normal) -4.3% GOOD T17096(normal) -1.1% T17516(normal) -3.1% T18282(normal) -1.9% T18304(normal) -1.2% T18698a(normal) -1.2% GOOD T18698b(normal) -1.5% GOOD T18923(normal) -1.3% T1969(normal) -1.3% GOOD T19695(normal) -4.4% GOOD T21839c(normal) -2.7% GOOD T21839r(normal) -2.7% GOOD T4801(normal) -3.8% GOOD T5642(normal) -3.1% GOOD T6048(optasm) -2.5% GOOD T9020(optasm) -2.7% GOOD T9630(normal) -2.1% GOOD T9961(normal) -11.7% GOOD WWRec(normal) -1.0% geo. mean -1.1% minimum -11.7% maximum +0.1% Metric Decrease: T10421 T12425 T13035 T13253 T16577 T18698a T18698b T1969 T19695 T21839c T21839r T4801 T5642 T6048 T9020 T9630 T9961 - - - - - 3c37d30b by Krzysztof Gogolewski at 2022-11-11T19:18:39+01:00 Use a more efficient printer for code generation (#21853) The changes in `GHC.Utils.Outputable` are the bulk of the patch and drive the rest. The types `HLine` and `HDoc` in Outputable can be used instead of `SDoc` and support printing directly to a handle with `bPutHDoc`. See Note [SDoc versus HDoc] and Note [HLine versus HDoc]. The classes `IsLine` and `IsDoc` are used to make the existing code polymorphic over `HLine`/`HDoc` and `SDoc`. This is done for X86, PPC, AArch64, DWARF and dependencies (printing module names, labels etc.). Co-authored-by: Alexis King <lexi.lambda at gmail.com> Metric Decrease: CoOpt_Read ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13379 T18140 T18282 T18698a T18698b T1969 T20049 T21839c T21839r T3064 T3294 T4801 T5321FD T5321Fun T5631 T6048 T783 T9198 T9233 - - - - - 6b92b47f by Matthew Craven at 2022-11-11T18:32:14-05:00 Weaken wrinkle 1 of Note [Scrutinee Constant Folding] Fixes #22375. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 154c70f6 by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Fix fragile RULE setup in GHC.Float In testing my type-vs-constraint patch I found that the handling of Natural literals was very fragile -- and I somehow tripped that fragility in my work. So this patch fixes the fragility. See Note [realToFrac natural-to-float] This made a big (9%) difference in one existing test in perf/should_run/T1-359 Metric Decrease: T10359 - - - - - 778c6adc by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Type vs Constraint: finally nailed This big patch addresses the rats-nest of issues that have plagued us for years, about the relationship between Type and Constraint. See #11715/#21623. The main payload of the patch is: * To introduce CONSTRAINT :: RuntimeRep -> Type * To make TYPE and CONSTRAINT distinct throughout the compiler Two overview Notes in GHC.Builtin.Types.Prim * Note [TYPE and CONSTRAINT] * Note [Type and Constraint are not apart] This is the main complication. The specifics * New primitive types (GHC.Builtin.Types.Prim) - CONSTRAINT - ctArrowTyCon (=>) - tcArrowTyCon (-=>) - ccArrowTyCon (==>) - funTyCon FUN -- Not new See Note [Function type constructors and FunTy] and Note [TYPE and CONSTRAINT] * GHC.Builtin.Types: - New type Constraint = CONSTRAINT LiftedRep - I also stopped nonEmptyTyCon being built-in; it only needs to be wired-in * Exploit the fact that Type and Constraint are distinct throughout GHC - Get rid of tcView in favour of coreView. - Many tcXX functions become XX functions. e.g. tcGetCastedTyVar --> getCastedTyVar * Kill off Note [ForAllTy and typechecker equality], in (old) GHC.Tc.Solver.Canonical. It said that typechecker-equality should ignore the specified/inferred distinction when comparein two ForAllTys. But that wsa only weakly supported and (worse) implies that we need a separate typechecker equality, different from core equality. No no no. * GHC.Core.TyCon: kill off FunTyCon in data TyCon. There was no need for it, and anyway now we have four of them! * GHC.Core.TyCo.Rep: add two FunTyFlags to FunCo See Note [FunCo] in that module. * GHC.Core.Type. Lots and lots of changes driven by adding CONSTRAINT. The key new function is sORTKind_maybe; most other changes are built on top of that. See also `funTyConAppTy_maybe` and `tyConAppFun_maybe`. * Fix a longstanding bug in GHC.Core.Type.typeKind, and Core Lint, in kinding ForAllTys. See new tules (FORALL1) and (FORALL2) in GHC.Core.Type. (The bug was that before (forall (cv::t1 ~# t2). blah), where blah::TYPE IntRep, would get kind (TYPE IntRep), but it should be (TYPE LiftedRep). See Note [Kinding rules for types] in GHC.Core.Type. * GHC.Core.TyCo.Compare is a new module in which we do eqType and cmpType. Of course, no tcEqType any more. * GHC.Core.TyCo.FVs. I moved some free-var-like function into this module: tyConsOfType, visVarsOfType, and occCheckExpand. Refactoring only. * GHC.Builtin.Types. Compiletely re-engineer boxingDataCon_maybe to have one for each /RuntimeRep/, rather than one for each /Type/. This dramatically widens the range of types we can auto-box. See Note [Boxing constructors] in GHC.Builtin.Types The boxing types themselves are declared in library ghc-prim:GHC.Types. GHC.Core.Make. Re-engineer the treatment of "big" tuples (mkBigCoreVarTup etc) GHC.Core.Make, so that it auto-boxes unboxed values and (crucially) types of kind Constraint. That allows the desugaring for arrows to work; it gathers up free variables (including dictionaries) into tuples. See Note [Big tuples] in GHC.Core.Make. There is still work to do here: #22336. But things are better than before. * GHC.Core.Make. We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and aBSENT_CONSTRAINT_ERROR_ID for vaues of kind Constraint. Ditto noInlineId vs noInlieConstraintId in GHC.Types.Id.Make; see Note [inlineId magic]. * GHC.Core.TyCo.Rep. Completely refactor the NthCo coercion. It is now called SelCo, and its fields are much more descriptive than the single Int we used to have. A great improvement. See Note [SelCo] in GHC.Core.TyCo.Rep. * GHC.Core.RoughMap.roughMatchTyConName. Collapse TYPE and CONSTRAINT to a single TyCon, so that the rough-map does not distinguish them. * GHC.Core.DataCon - Mainly just improve documentation * Some significant renamings: GHC.Core.Multiplicity: Many --> ManyTy (easier to grep for) One --> OneTy GHC.Core.TyCo.Rep TyCoBinder --> GHC.Core.Var.PiTyBinder GHC.Core.Var TyCoVarBinder --> ForAllTyBinder AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag GHC.Core.TyCon TyConTyCoBinder --> TyConPiTyBinder Many functions are renamed in consequence e.g. isinvisibleArgFlag becomes isInvisibleForAllTyFlag, etc * I refactored FunTyFlag (was AnonArgFlag) into a simple, flat data type data FunTyFlag = FTF_T_T -- (->) Type -> Type | FTF_T_C -- (-=>) Type -> Constraint | FTF_C_T -- (=>) Constraint -> Type | FTF_C_C -- (==>) Constraint -> Constraint * GHC.Tc.Errors.Ppr. Some significant refactoring in the TypeEqMisMatch case of pprMismatchMsg. * I made the tyConUnique field of TyCon strict, because I saw code with lots of silly eval's. That revealed that GHC.Settings.Constants.mAX_SUM_SIZE can only be 63, because we pack the sum tag into a 6-bit field. (Lurking bug squashed.) Fixes * #21530 Updates haddock submodule slightly. Performance changes ~~~~~~~~~~~~~~~~~~~ I was worried that compile times would get worse, but after some careful profiling we are down to a geometric mean 0.1% increase in allocation (in perf/compiler). That seems fine. There is a big runtime improvement in T10359 Metric Decrease: LargeRecord MultiLayerModulesTH_OneShot T13386 T13719 Metric Increase: T8095 - - - - - 360f5fec by Simon Peyton Jones at 2022-11-11T23:40:11+00:00 Indent closing "#-}" to silence HLint - - - - - e160cf47 by Krzysztof Gogolewski at 2022-11-12T08:05:28-05:00 Fix merge conflict in T18355.stderr Fixes #22446 - - - - - 294f9073 by Simon Peyton Jones at 2022-11-12T23:14:13+00:00 Fix a trivial typo in dataConNonlinearType Fixes #22416 - - - - - 268a3ce9 by Ben Gamari at 2022-11-14T09:36:57-05:00 eventlog: Ensure that IPE output contains actual info table pointers The refactoring in 866c736e introduced a rather subtle change in the semantics of the IPE eventlog output, changing the eventlog field from encoding info table pointers to "TNTC pointers" (which point to entry code when tables-next-to-code is enabled). Fix this. Fixes #22452. - - - - - d91db679 by Matthew Pickering at 2022-11-14T16:48:10-05:00 testsuite: Add tests for T22347 These are fixed in recent versions but might as well add regression tests. See #22347 - - - - - 8f6c576b by Matthew Pickering at 2022-11-14T16:48:45-05:00 testsuite: Improve output from tests which have failing pre_cmd There are two changes: * If a pre_cmd fails, then don't attempt to run the test. * If a pre_cmd fails, then print the stdout and stderr from running that command (which hopefully has a nice error message). For example: ``` =====> 1 of 1 [0, 0, 0] *** framework failure for test-defaulting-plugin(normal) pre_cmd failed: 2 ** pre_cmd was "$MAKE -s --no-print-directory -C defaulting-plugin package.test-defaulting-plugin TOP={top}". stdout: stderr: DefaultLifted.hs:19:13: error: [GHC-76037] Not in scope: type constructor or class ‘Typ’ Suggested fix: Perhaps use one of these: ‘Type’ (imported from GHC.Tc.Utils.TcType), data constructor ‘Type’ (imported from GHC.Plugins) | 19 | instance Eq Typ where | ^^^ make: *** [Makefile:17: package.test-defaulting-plugin] Error 1 Performance Metrics (test environment: local): ``` Fixes #22329 - - - - - 2b7d5ccc by Madeline Haraj at 2022-11-14T22:44:17+00:00 Implement UNPACK support for sum types. This is based on osa's unpack_sums PR from ages past. The meat of the patch is implemented in dataConArgUnpackSum and described in Note [UNPACK for sum types]. - - - - - 78f7ecb0 by Andreas Klebinger at 2022-11-14T22:20:29-05:00 Expand on the need to clone local binders. Fixes #22402. - - - - - 65ce43cc by Krzysztof Gogolewski at 2022-11-14T22:21:05-05:00 Fix :i Constraint printing "type Constraint = Constraint" Since Constraint became a synonym for CONSTRAINT 'LiftedRep, we need the same code for handling printing as for the synonym Type = TYPE 'LiftedRep. This addresses the same bug as #18594, so I'm reusing the test. - - - - - 94549f8f by ARATA Mizuki at 2022-11-15T21:36:03-05:00 configure: Don't check for an unsupported version of LLVM The upper bound is not inclusive. Fixes #22449 - - - - - 02d3511b by Bodigrim at 2022-11-15T21:36:41-05:00 Fix capitalization in haddock for TestEquality - - - - - 08bf2881 by Cheng Shao at 2022-11-16T09:16:29+00:00 base: make Foreign.Marshal.Pool use RTS internal arena for allocation `Foreign.Marshal.Pool` used to call `malloc` once for each allocation request. Each `Pool` maintained a list of allocated pointers, and traverses the list to `free` each one of those pointers. The extra O(n) overhead is apparently bad for a `Pool` that serves a lot of small allocation requests. This patch uses the RTS internal arena to implement `Pool`, with these benefits: - Gets rid of the extra O(n) overhead. - The RTS arena is simply a bump allocator backed by the block allocator, each allocation request is likely faster than a libc `malloc` call. Closes #14762 #18338. - - - - - 37cfe3c0 by Krzysztof Gogolewski at 2022-11-16T14:50:06-05:00 Misc cleanup * Replace catMaybes . map f with mapMaybe f * Use concatFS to concatenate multiple FastStrings * Fix documentation of -exclude-module * Cleanup getIgnoreCount in GHCi.UI - - - - - b0ac3813 by Lawton Nichols at 2022-11-19T03:22:14-05:00 Give better errors for code corrupted by Unicode smart quotes (#21843) Previously, we emitted a generic and potentially confusing error during lexical analysis on programs containing smart quotes (“/”/‘/’). This commit adds smart quote-aware lexer errors. - - - - - cb8430f8 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make OpaqueNo* tests less noisy to unrelated changes - - - - - b1a8af69 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Simplifier: Consider `seq` as a `BoringCtxt` (#22317) See `Note [Seq is boring]` for the rationale. Fixes #22317. - - - - - 9fd11585 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make T21839c's ghc/max threshold more forgiving - - - - - 4b6251ab by Simon Peyton Jones at 2022-11-19T03:23:24-05:00 Be more careful when reporting unbound RULE binders See Note [Variables unbound on the LHS] in GHC.HsToCore.Binds. Fixes #22471. - - - - - e8f2b80d by Peter Trommler at 2022-11-19T03:23:59-05:00 PPC NCG: Fix generating assembler code Fixes #22479 - - - - - f2f9ef07 by Bodigrim at 2022-11-20T18:39:30-05:00 Extend documentation for Data.IORef - - - - - ef511b23 by Simon Peyton Jones at 2022-11-20T18:40:05-05:00 Buglet in GHC.Tc.Module.checkBootTyCon This lurking bug used the wrong function to compare two types in GHC.Tc.Module.checkBootTyCon It's hard to trigger the bug, which only came up during !9343, so there's no regression test in this MR. - - - - - 451aeac3 by Bodigrim at 2022-11-20T18:40:44-05:00 Add since pragmas for c_interruptible_open and hostIsThreaded - - - - - 8d6aaa49 by Duncan Coutts at 2022-11-22T02:06:16-05:00 Introduce CapIOManager as the per-cap I/O mangager state Rather than each I/O manager adding things into the Capability structure ad-hoc, we should have a common CapIOManager iomgr member of the Capability structure, with a common interface to initialise etc. The content of the CapIOManager struct will be defined differently for each I/O manager implementation. Eventually we should be able to have the CapIOManager be opaque to the rest of the RTS, and known just to the I/O manager implementation. We plan for that by making the Capability contain a pointer to the CapIOManager rather than containing the structure directly. Initially just move the Unix threaded I/O manager's control FD. - - - - - 8901285e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Add hook markCapabilityIOManager To allow I/O managers to have GC roots in the Capability, within the CapIOManager structure. Not yet used in this patch. - - - - - 5cf709c5 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move APPEND_TO_BLOCKED_QUEUE from cmm to C The I/O and delay blocking primitives for the non-threaded way currently access the blocked_queue and sleeping_queue directly. We want to move where those queues are to make their ownership clearer: to have them clearly belong to the I/O manager impls rather than to the scheduler. Ultimately we will want to change their representation too. It's inconvenient to do that if these queues are accessed directly from cmm code. So as a first step, replace the APPEND_TO_BLOCKED_QUEUE with a C version appendToIOBlockedQueue(), and replace the open-coded sleeping_queue insertion with insertIntoSleepingQueue(). - - - - - ced9acdb by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move {blocked,sleeping}_queue from scheduler global vars to CapIOManager The blocked_queue_{hd,tl} and the sleeping_queue are currently cooperatively managed between the scheduler and (some but not all of) the non-threaded I/O manager implementations. They lived as global vars with the scheduler, but are poked by I/O primops and the I/O manager backends. This patch is a step on the path towards making the management of I/O or timer blocking belong to the I/O managers and not the scheduler. Specifically, this patch moves the {blocked,sleeping}_queue from being global vars in the scheduler to being members of the CapIOManager struct within each Capability. They are not yet exclusively used by the I/O managers: they are still poked from a couple other places, notably in the scheduler before calling awaitEvent. - - - - - 0f68919e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Remove the now-unused markScheduler The global vars {blocked,sleeping}_queue are now in the Capability and so get marked there via markCapabilityIOManager. - - - - - 39a91f60 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move macros for checking for pending IO or timers from Schedule.h to Schedule.c and IOManager.h This is just moving, the next step will be to rejig them slightly. For the non-threaded RTS the scheduler needs to be able to test for there being pending I/O operation or pending timers. The implementation of these tests should really be considered to be part of the I/O managers and not part of the scheduler. - - - - - 664b034b by Duncan Coutts at 2022-11-22T02:06:17-05:00 Replace EMPTY_{BLOCKED,SLEEPING}_QUEUE macros by function These are the macros originaly from Scheduler.h, previously moved to IOManager.h, and now replaced with a single inline function anyPendingTimeoutsOrIO(). We can use a single function since the two macros were always checked together. Note that since anyPendingTimeoutsOrIO is defined for all IO manager cases, including threaded, we do not need to guard its use by cpp #if !defined(THREADED_RTS) - - - - - 32946220 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Expand emptyThreadQueues inline for clarity It was not really adding anything. The name no longer meant anything since those I/O and timeout queues do not belong to the scheuler. In one of the two places it was used, the comments already had to explain what it did, whereas now the code matches the comment nicely. - - - - - 9943baf9 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move the awaitEvent declaration into IOManager.h And add or adjust comments at the use sites of awaitEvent. - - - - - 054dcc9d by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to awaitEvent It is currently only used in the non-threaded RTS so it works to use MainCapability, but it's a bit nicer to pass the cap anyway. It's certainly shorter. - - - - - 667fe5a4 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to appendToIOBlockedQueue And to insertIntoSleepingQueue. Again, it's a bit cleaner and simpler though not strictly necessary given that these primops are currently only used in the non-threaded RTS. - - - - - 7181b074 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Reveiew feedback: improve one of the TODO comments The one about the nonsense (const False) test on WinIO for there being any IO or timers pending, leading to unnecessary complication later in the scheduler. - - - - - e5b68183 by Andreas Klebinger at 2022-11-22T02:06:52-05:00 Optimize getLevity. Avoid the intermediate data structures allocated by splitTyConApp. This avoids ~0.5% of allocations for a build using -O2. Fixes #22254 - - - - - de5fb348 by Andreas Klebinger at 2022-11-22T02:07:28-05:00 hadrian:Set TNTC when running testsuite. - - - - - 9d61c182 by Oleg Grenrus at 2022-11-22T15:59:34-05:00 Add unsafePtrEquality# restricted to UnliftedTypes - - - - - e817c871 by Jonathan Dowland at 2022-11-22T16:00:14-05:00 utils/unlit: adjust parser to match Report spec The Haskell 2010 Report says that, for Latex-style Literate format, "Program code begins on the first line following a line that begins \begin{code}". (This is unchanged from the 98 Report) However the unlit.c implementation only matches a line that contains "\begin{code}" and nothing else. One consequence of this is that one cannot suffix Latex options to the code environment. I.e., this does not work: \begin{code}[label=foo,caption=Foo Code] Adjust the matcher to conform to the specification from the Report. The Haskell Wiki currently recommends suffixing a '%' to \begin{code} in order to deliberately hide a code block from Haskell. This is bad advice, as it's relying on an implementation quirk rather than specified behaviour. None-the-less, some people have tried to use it, c.f. <https://mail.haskell.org/pipermail/haskell-cafe/2009-September/066780.html> An alternative solution is to define a separate, equivalent Latex environment to "code", that is functionally identical in Latex but ignored by unlit. This should not be a burden: users are required to manually define the code environment anyway, as it is not provided by the Latex verbatim or lstlistings packages usually used for presenting code in documents. Fixes #3549. - - - - - 0b7fef11 by Teo Camarasu at 2022-11-23T12:44:33-05:00 Fix eventlog all option Previously it didn't enable/disable nonmoving_gc and ticky event types Fixes #21813 - - - - - 04d0618c by Arnaud Spiwack at 2022-11-23T12:45:14-05:00 Expand Note [Linear types] with the stance on linting linearity Per the discussion on #22123 - - - - - e1538516 by Lawton Nichols at 2022-11-23T12:45:55-05:00 Add documentation on custom Prelude modules (#22228) Specifically, custom Prelude modules that are named `Prelude`. - - - - - b5c71454 by Sylvain Henry at 2022-11-23T12:46:35-05:00 Don't let configure perform trivial substitutions (#21846) Hadrian now performs substitutions, especially to generate .cabal files from .cabal.in files. Two benefits: 1. We won't have to re-configure when we modify thing.cabal.in. Hadrian will take care of this for us. 2. It paves the way to allow the same package to be configured differently by Hadrian in the same session. This will be useful to fix #19174: we want to build a stage2 cross-compiler for the host platform and a stage1 compiler for the cross target platform in the same Hadrian session. - - - - - 99aca26b by nineonine at 2022-11-23T12:47:11-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043) Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043 - - - - - 040bfdc3 by M Farkas-Dyck at 2022-11-23T21:59:03-05:00 Scrub some no-warning pragmas. - - - - - 178c1fd8 by Vladislav Zavialov at 2022-11-23T21:59:39-05:00 Check if the SDoc starts with a single quote (#22488) This patch fixes pretty-printing of character literals inside promoted lists and tuples. When we pretty-print a promoted list or tuple whose first element starts with a single quote, we want to add a space between the opening bracket and the element: '[True] -- ok '[ 'True] -- ok '['True] -- not ok If we don't add the space, we accidentally produce a character literal '['. Before this patch, pprSpaceIfPromotedTyCon inspected the type as an AST and tried to guess if it would be rendered with a single quote. However, it missed the case when the inner type was itself a character literal: '[ 'x'] -- ok '['x'] -- not ok Instead of adding this particular case, I opted for a more future-proof solution: check the SDoc directly. This way we can detect if the single quote is actually there instead of trying to predict it from the AST. The new function is called spaceIfSingleQuote. - - - - - 11627c42 by Matthew Pickering at 2022-11-23T22:00:15-05:00 notes: Fix references to HPT space leak note Updating this note was missed when updating the HPT to the HUG. Fixes #22477 - - - - - 86ff1523 by Andrei Borzenkov at 2022-11-24T17:24:51-05:00 Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115) Problem: avoid usage of TcRnMessageUnknown Solution: The following `TcRnMessage` messages has been introduced: TcRnNoRebindableSyntaxRecordDot TcRnNoFieldPunsRecordDot TcRnIllegalStaticExpression TcRnIllegalStaticFormInSplice TcRnListComprehensionDuplicateBinding TcRnEmptyStmtsGroup TcRnLastStmtNotExpr TcRnUnexpectedStatementInContext TcRnIllegalTupleSection TcRnIllegalImplicitParameterBindings TcRnSectionWithoutParentheses Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - d198a19a by Cheng Shao at 2022-11-24T17:25:29-05:00 rts: fix missing Arena.h symbols in RtsSymbols.c It was an unfortunate oversight in !8961 and broke devel2 builds. - - - - - 5943e739 by Bodigrim at 2022-11-25T04:38:28-05:00 Assorted fixes to avoid Data.List.{head,tail} - - - - - 1f1b99b8 by sheaf at 2022-11-25T04:38:28-05:00 Review suggestions for assorted fixes to avoid Data.List.{head,tail} - - - - - 13d627bb by Vladislav Zavialov at 2022-11-25T04:39:04-05:00 Print unticked promoted data constructors (#20531) Before this patch, GHC unconditionally printed ticks before promoted data constructors: ghci> type T = True -- unticked (user-written) ghci> :kind! T T :: Bool = 'True -- ticked (compiler output) After this patch, GHC prints ticks only when necessary: ghci> type F = False -- unticked (user-written) ghci> :kind! F F :: Bool = False -- unticked (compiler output) ghci> data False -- introduce ambiguity ghci> :kind! F F :: Bool = 'False -- ticked by necessity (compiler output) The old behavior can be enabled by -fprint-redundant-promotion-ticks. Summary of changes: * Rename PrintUnqualified to NamePprCtx * Add QueryPromotionTick to it * Consult the GlobalRdrEnv to decide whether to print a tick (see mkPromTick) * Introduce -fprint-redundant-promotion-ticks Co-authored-by: Artyom Kuznetsov <hi at wzrd.ht> - - - - - d10dc6bd by Simon Peyton Jones at 2022-11-25T22:31:27+00:00 Fix decomposition of TyConApps Ticket #22331 showed that we were being too eager to decompose a Wanted TyConApp, leading to incompleteness in the solver. To understand all this I ended up doing a substantial rewrite of the old Note [Decomposing equalities], now reborn as Note [Decomposing TyConApp equalities]. Plus rewrites of other related Notes. The actual fix is very minor and actually simplifies the code: in `can_decompose` in `GHC.Tc.Solver.Canonical.canTyConApp`, we now call `noMatchableIrreds`. A closely related refactor: we stop trying to use the same "no matchable givens" function here as in `matchClassInst`. Instead split into two much simpler functions. - - - - - 2da5c38a by Will Hawkins at 2022-11-26T04:05:04-05:00 Redirect output of musttail attribute test Compilation output from test for support of musttail attribute leaked to the console. - - - - - 0eb1c331 by Cheng Shao at 2022-11-28T08:55:53+00:00 Move hs_mulIntMayOflo cbits to ghc-prim It's only used by wasm NCG at the moment, but ghc-prim is a more reasonable place for hosting out-of-line primops. Also, we only need a single version of hs_mulIntMayOflo. - - - - - 36b53a9d by Cheng Shao at 2022-11-28T09:05:57+00:00 compiler: generate ccalls for clz/ctz/popcnt in wasm NCG We used to generate a single wasm clz/ctz/popcnt opcode, but it's wrong when it comes to subwords, so might as well generate ccalls for them. See #22470 for details. - - - - - d4134e92 by Cheng Shao at 2022-11-28T23:48:14-05:00 compiler: remove unused MO_U_MulMayOflo We actually only emit MO_S_MulMayOflo and never emit MO_U_MulMayOflo anywhere. - - - - - 8d15eadc by Apoorv Ingle at 2022-11-29T03:09:31-05:00 Killing cc_fundeps, streamlining kind equality orientation, and type equality processing order Fixes: #217093 Associated to #19415 This change * Flips the orientation of the the generated kind equality coercion in canEqLHSHetero; * Removes `cc_fundeps` in CDictCan as the check was incomplete; * Changes `canDecomposableTyConAppOk` to ensure we process kind equalities before type equalities and avoiding a call to `canEqLHSHetero` while processing wanted TyConApp equalities * Adds 2 new tests for validating the change - testsuites/typecheck/should_compile/T21703.hs and - testsuites/typecheck/should_fail/T19415b.hs (a simpler version of T19415.hs) * Misc: Due to the change in the equality direction some error messages now have flipped type mismatch errors * Changes in Notes: - Note [Fundeps with instances, and equality orientation] supercedes Note [Fundeps with instances] - Added Note [Kind Equality Orientation] to visualize the kind flipping - Added Note [Decomposing Dependent TyCons and Processing Wanted Equalties] - - - - - 646969d4 by Krzysztof Gogolewski at 2022-11-29T03:10:13-05:00 Change printing of sized literals to match the proposal Literals in Core were printed as e.g. 0xFF#16 :: Int16#. The proposal 451 now specifies syntax 0xFF#Int16. This change affects the Core printer only - more to be done later. Part of #21422. - - - - - 02e282ec by Simon Peyton Jones at 2022-11-29T03:10:48-05:00 Be a bit more selective about floating bottoming expressions This MR arranges to float a bottoming expression to the top only if it escapes a value lambda. See #22494 and Note [Floating to the top] in SetLevels. This has a generally beneficial effect in nofib +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || -0.93% | | imaginary/rfib || -0.05% | | real/fem || -0.03% | | real/fluid || -0.01% | | real/fulsom || +0.05% | | real/gamteb || -0.27% | | real/gg || -0.10% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/scs || -11.13% | | shootout/k-nucleotide || -0.01% | | shootout/n-body || -0.08% | | shootout/reverse-complement || -0.00% | | shootout/spectral-norm || -0.02% | | spectral/fibheaps || -0.20% | | spectral/hartel/fft || -1.04% | | spectral/hartel/solid || +0.33% | | spectral/hartel/wave4main || -0.35% | | spectral/mate || +0.76% | +===============================++==========+ | geom mean || -0.12% | The effect on compile time is generally slightly beneficial Metrics: compile_time/bytes allocated ---------------------------------------------- MultiLayerModulesTH_OneShot(normal) +0.3% PmSeriesG(normal) -0.2% PmSeriesT(normal) -0.1% T10421(normal) -0.1% T10421a(normal) -0.1% T10858(normal) -0.1% T11276(normal) -0.1% T11303b(normal) -0.2% T11545(normal) -0.1% T11822(normal) -0.1% T12150(optasm) -0.1% T12234(optasm) -0.3% T13035(normal) -0.2% T16190(normal) -0.1% T16875(normal) -0.4% T17836b(normal) -0.2% T17977(normal) -0.2% T17977b(normal) -0.2% T18140(normal) -0.1% T18282(normal) -0.1% T18304(normal) -0.2% T18698a(normal) -0.1% T18923(normal) -0.1% T20049(normal) -0.1% T21839r(normal) -0.1% T5837(normal) -0.4% T6048(optasm) +3.2% BAD T9198(normal) -0.2% T9630(normal) -0.1% TcPlugin_RewritePerf(normal) -0.4% hard_hole_fits(normal) -0.1% geo. mean -0.0% minimum -0.4% maximum +3.2% The T6048 outlier is hard to pin down, but it may be the effect of reading in more interface files definitions. It's a small program for which compile time is very short, so I'm not bothered about it. Metric Increase: T6048 - - - - - ab23dc5e by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Mark unpack_sums_6 as fragile due to #22504 This test is explicitly dependent upon runtime, which is generally not appropriate given that the testsuite is run in parallel and generally saturates the CPU. - - - - - def47dd3 by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Don't use grep -q in unpack_sums_7 `grep -q` closes stdin as soon as it finds the pattern it is looking for, resulting in #22484. - - - - - cc25d52e by Sylvain Henry at 2022-11-29T09:44:31+01:00 Add Javascript backend Add JS backend adapted from the GHCJS project by Luite Stegeman. Some features haven't been ported or implemented yet. Tests for these features have been disabled with an associated gitlab ticket. Bump array submodule Work funded by IOG. Co-authored-by: Jeffrey Young <jeffrey.young at iohk.io> Co-authored-by: Luite Stegeman <stegeman at gmail.com> Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 68c966cd by sheaf at 2022-11-30T09:31:25-05:00 Fix @since annotations on WithDict and Coercible Fixes #22453 - - - - - a3a8e9e9 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. - - - - - a9d9b8c0 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Use mkNakedFunTy in tcPatSynSig As #22521 showed, in tcPatSynSig we make a "fake type" to kind-generalise; and that type has unzonked type variables in it. So we must not use `mkFunTy` (which checks FunTy's invariants) via `mkPhiTy` when building this type. Instead we need to use `mkNakedFunTy`. Easy fix. - - - - - 31462d98 by Andreas Klebinger at 2022-11-30T14:50:58-05:00 Properly cast values when writing/reading unboxed sums. Unboxed sums might store a Int8# value as Int64#. This patch makes sure we keep track of the actual value type. See Note [Casting slot arguments] for the details. - - - - - 10a2a7de by Oleg Grenrus at 2022-11-30T14:51:39-05:00 Move Void to GHC.Base... This change would allow `Void` to be used deeper in module graph. For example exported from `Prelude` (though that might be already possible). Also this change includes a change `stimes @Void _ x = x`, https://github.com/haskell/core-libraries-committee/issues/95 While the above is not required, maintaining old stimes behavior would be tricky as `GHC.Base` doesn't know about `Num` or `Integral`, which would require more hs-boot files. - - - - - b4cfa8e2 by Sebastian Graf at 2022-11-30T14:52:24-05:00 DmdAnal: Reflect the `seq` of strict fields of a DataCon worker (#22475) See the updated `Note [Data-con worker strictness]` and the new `Note [Demand transformer for data constructors]`. Fixes #22475. - - - - - d87f28d8 by Baldur Blöndal at 2022-11-30T21:16:36+01:00 Make Functor a quantified superclass of Bifunctor. See https://github.com/haskell/core-libraries-committee/issues/91 for discussion. This change relates Bifunctor with Functor by requiring second = fmap. Moreover this change is a step towards unblocking the major version bump of bifunctors and profunctors to major version 6. This paves the way to move the Profunctor class into base. For that Functor first similarly becomes a superclass of Profunctor in the new major version 6. - - - - - 72cf4c5d by doyougnu at 2022-12-01T12:36:44-05:00 FastString: SAT bucket_match Metric Decrease: MultiLayerModulesTH_OneShot - - - - - afc2540d by Simon Peyton Jones at 2022-12-01T12:37:20-05:00 Add a missing varToCoreExpr in etaBodyForJoinPoint This subtle bug showed up when compiling a library with 9.4. See #22491. The bug is present in master, but it is hard to trigger; the new regression test T22491 fails in 9.4. The fix was easy: just add a missing varToCoreExpr in etaBodyForJoinPoint. The fix is definitely right though! I also did some other minor refatoring: * Moved the preInlineUnconditionally test in simplExprF1 to before the call to joinPointBinding_maybe, to avoid fruitless eta-expansion. * Added a boolean from_lam flag to simplNonRecE, to avoid two fruitless tests, and commented it a bit better. These refactorings seem to save 0.1% on compile-time allocation in perf/compiler; with a max saving of 1.4% in T9961 Metric Decrease: T9961 - - - - - 81eeec7f by M Farkas-Dyck at 2022-12-01T12:37:56-05:00 CI: Forbid the fully static build on Alpine to fail. To do so, we mark some tests broken in this configuration. - - - - - c5d1bf29 by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Remove ARMv7 jobs These jobs fail (and are allowed to fail) nearly every time. Soon they won't even be able to run at all, as we won't currently have runners that can run them. Fixing the latter problem is tracked in #22409. I went ahead and removed all settings and configurations. - - - - - d82992fd by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Fix CI lint Failure was introduced by conflicting changes to gen_ci.hs that did *not* trigger git conflicts. - - - - - ce126993 by Simon Peyton Jones at 2022-12-02T01:22:12-05:00 Refactor TyCon to have a top-level product This patch changes the representation of TyCon so that it has a top-level product type, with a field that gives the details (newtype, type family etc), #22458. Not much change in allocation, but execution seems to be a bit faster. Includes a change to the haddock submodule to adjust for API changes. - - - - - 74c767df by Matthew Pickering at 2022-12-02T01:22:48-05:00 ApplicativeDo: Set pattern location before running exhaustiveness checker This improves the error messages of the exhaustiveness checker when checking statements which have been moved around with ApplicativeDo. Before: Test.hs:2:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 2 | let x = () | ^^^^^^^^^^ After: Test.hs:4:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 4 | ~(Just res1) <- seq x (pure $ Nothing @()) | Fixes #22483 - - - - - 85ecc1a0 by Matthew Pickering at 2022-12-02T19:46:43-05:00 Add special case for :Main module in `GHC.IfaceToCore.mk_top_id` See Note [Root-main Id] The `:Main` special binding is actually defined in the current module (hence don't go looking for it externally) but the module name is rOOT_MAIN rather than the current module so we need this special case. There was already some similar logic in `GHC.Rename.Env` for External Core, but now the "External Core" is in interface files it needs to be moved here instead. Fixes #22405 - - - - - 108c319f by Krzysztof Gogolewski at 2022-12-02T19:47:18-05:00 Fix linearity checking in Lint Lint was not able to see that x*y <= x*y, because this inequality was decomposed to x <= x*y && y <= x*y, but there was no rule to see that x <= x*y. Fixes #22546. - - - - - bb674262 by Bryan Richter at 2022-12-03T04:38:46-05:00 Mark T16916 fragile See https://gitlab.haskell.org/ghc/ghc/-/issues/16966 - - - - - 5d267d46 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 Refactor: FreshOrReuse instead of addTyClTyVarBinds This is a refactoring that should have no effect on observable behavior. Prior to this change, GHC.HsToCore.Quote contained a few closely related functions to process type variable bindings: addSimpleTyVarBinds, addHsTyVarBinds, addQTyVarBinds, and addTyClTyVarBinds. We can classify them by their input type and name generation strategy: Fresh names only Reuse bound names +---------------------+-------------------+ [Name] | addSimpleTyVarBinds | | [LHsTyVarBndr flag GhcRn] | addHsTyVarBinds | | LHsQTyVars GhcRn | addQTyVarBinds | addTyClTyVarBinds | +---------------------+-------------------+ Note how two functions are missing. Because of this omission, there were two places where a LHsQTyVars value was constructed just to be able to pass it to addTyClTyVarBinds: 1. mk_qtvs in addHsOuterFamEqnTyVarBinds -- bad 2. mkHsQTvs in repFamilyDecl -- bad This prevented me from making other changes to LHsQTyVars, so the main goal of this refactoring is to get rid of those workarounds. The most direct solution would be to define the missing functions. But that would lead to a certain amount of code duplication. To avoid code duplication, I factored out the name generation strategy into a function parameter: data FreshOrReuse = FreshNamesOnly | ReuseBoundNames addSimpleTyVarBinds :: FreshOrReuse -> ... addHsTyVarBinds :: FreshOrReuse -> ... addQTyVarBinds :: FreshOrReuse -> ... - - - - - c189b831 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 addHsOuterFamEqnTyVarBinds: use FreshNamesOnly for explicit binders Consider this example: [d| instance forall a. C [a] where type forall b. G [a] b = Proxy b |] When we process "forall b." in the associated type instance, it is unambiguously the binding site for "b" and we want a fresh name for it. Therefore, FreshNamesOnly is more fitting than ReuseBoundNames. This should not have any observable effect but it avoids pointless lookups in the MetaEnv. - - - - - 42512264 by Ross Paterson at 2022-12-03T10:32:45+00:00 Handle type data declarations in Template Haskell quotations and splices (fixes #22500) This adds a TypeDataD constructor to the Template Haskell Dec type, and ensures that the constructors it contains go in the TyCls namespace. - - - - - 1a767fa3 by Vladislav Zavialov at 2022-12-05T05:18:50-05:00 Add BufSpan to EpaLocation (#22319, #22558) The key part of this patch is the change to mkTokenLocation: - mkTokenLocation (RealSrcSpan r _) = TokenLoc (EpaSpan r) + mkTokenLocation (RealSrcSpan r mb) = TokenLoc (EpaSpan r mb) mkTokenLocation used to discard the BufSpan, but now it is saved and can be retrieved from LHsToken or LHsUniToken. This is made possible by the following change to EpaLocation: - data EpaLocation = EpaSpan !RealSrcSpan + data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | ... The end goal is to make use of the BufSpan in Parser/PostProcess/Haddock. - - - - - cd31acad by sheaf at 2022-12-06T15:45:58-05:00 Hadrian: fix ghcDebugAssertions off-by-one error Commit 6b2f7ffe changed the logic that decided whether to enable debug assertions. However, it had an off-by-one error, as the stage parameter to the function inconsistently referred to the stage of the compiler being used to build or the stage of the compiler we are building. This patch makes it consistent. Now the parameter always refers to the the compiler which is being built. In particular, this patch re-enables assertions in the stage 2 compiler when building with devel2 flavour, and disables assertions in the stage 2 compiler when building with validate flavour. Some extra performance tests are now run in the "validate" jobs because the stage2 compiler no longer contains assertions. ------------------------- Metric Decrease: CoOpt_Singletons MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot T11374 T12227 T12234 T13253-spj T13701 T14683 T14697 T15703 T17096 T17516 T18304 T18478 T18923 T5030 T9872b TcPlugin_RewritePerf Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T13386 T13719 T3294 T9233 T9675 parsing001 ------------------------- - - - - - 21d66db1 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInstallNameTool - - - - - aaaaa79b by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of askOtool - - - - - 4e28f49e by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInjectRPaths - - - - - a7422580 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of Linker.MacOS - - - - - e902d771 by Matthew Craven at 2022-12-08T08:30:23-05:00 Fix bounds-checking buglet in Data.Array.Byte ...another manifestation of #20851 which I unfortunately missed in my first pass. - - - - - 8d36c0c6 by Gergő Érdi at 2022-12-08T08:31:03-05:00 Remove copy-pasted definitions of `graphFromEdgedVertices*` - - - - - c5d8ed3a by Gergő Érdi at 2022-12-08T08:31:03-05:00 Add version of `reachableGraph` that avoids loop for cyclic inputs by building its result connected component by component Fixes #22512 - - - - - 90cd5396 by Krzysztof Gogolewski at 2022-12-08T08:31:39-05:00 Mark Type.Reflection.Unsafe as Unsafe This module can be used to construct ill-formed TypeReps, so it should be Unsafe. - - - - - 2057c77d by Ian-Woo Kim at 2022-12-08T08:32:19-05:00 Truncate eventlog event for large payload (#20221) RTS eventlog events for postCapsetVecEvent are truncated if payload is larger than EVENT_PAYLOAD_SIZE_MAX Previously, postCapsetVecEvent records eventlog event with payload of variable size larger than EVENT_PAYLOAD_SIZE_MAX (2^16) without any validation, resulting in corrupted data. For example, this happens when a Haskell binary is invoked with very long command line arguments exceeding 2^16 bytes (see #20221). Now we check the size of accumulated payload messages incrementally, and truncate the message just before the payload size exceeds EVENT_PAYLOAD_SIZE_MAX. RTS will warn the user with a message showing how many arguments are truncated. - - - - - 9ec76f61 by Cheng Shao at 2022-12-08T08:32:59-05:00 hadrian: don't add debug info to non-debug ways of rts Hadrian used to pass -g when building all ways of rts. It makes output binaries larger (especially so for wasm backend), and isn't needed by most users out there, so this patch removes that flag. In case the debug info is desired, we still pass -g3 when building the debug way, and there's also the debug_info flavour transformer which ensures -g3 is passed for all rts ways. - - - - - 7658cdd4 by Krzysztof Gogolewski at 2022-12-08T08:33:36-05:00 Restore show (typeRep @[]) == "[]" The Show instance for TypeRep [] has changed in 9.5 to output "List" because the name of the type constructor changed. This seems to be accidental and is inconsistent with TypeReps of saturated lists, which are printed as e.g. "[Int]". For now, I'm restoring the old behavior; in the future, maybe we should show TypeReps without puns (List, Tuple, Type). - - - - - 216deefd by Matthew Pickering at 2022-12-08T22:45:27-05:00 Add test for #22162 - - - - - 5d0a311f by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job to test interface file determinism guarantees In this job we can run on every commit we add a test which builds the Cabal library twice and checks that the ABI hash and interface hash is stable across the two builds. * We run the test 20 times to try to weed out any race conditions due to `-j` * We run the builds in different temporary directories to try to weed out anything related to build directory affecting ABI or interface file hash. Fixes #22180 - - - - - 0a76d7d4 by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job for testing interface stability across builds The idea is that both the bindists should product libraries with the same ABI and interface hash. So the job checks with ghc-pkg to make sure the computed ABI is the same. In future this job can be extended to check for the other facets of interface determinism. Fixes #22180 - - - - - 74c9bf91 by Matthew Pickering at 2022-12-08T22:45:27-05:00 backpack: Be more careful when adding together ImportAvails There was some code in the signature merging logic which added together the ImportAvails of the signature and the signature which was merged into it. This had the side-effect of making the merged signature depend on the signature (via a normal module dependency). The intention was to propagate orphan instances through the merge but this also messed up recompilation logic because we shouldn't be attempting to load B.hi when mergeing it. The fix is to just combine the part of ImportAvails that we intended to (transitive info, orphan instances and type family instances) rather than the whole thing. - - - - - d122e022 by Matthew Pickering at 2022-12-08T22:45:27-05:00 Fix mk_mod_usage_info if the interface file is not already loaded In #22217 it was observed that the order modules are compiled in affects the contents of an interface file. This was because a module dependended on another module indirectly, via a re-export but the interface file for this module was never loaded because the symbol was never used in the file. If we decide that we depend on a module then we jolly well ought to record this fact in the interface file! Otherwise it could lead to very subtle recompilation bugs if the dependency is not tracked and the module is updated. Therefore the best thing to do is just to make sure the file is loaded by calling the `loadSysInterface` function. This first checks the caches (like we did before) but then actually goes to find the interface on disk if it wasn't loaded. Fixes #22217 - - - - - ea25088d by lrzlin at 2022-12-08T22:46:06-05:00 Add initial support for LoongArch Architecture. - - - - - 9eb9d2f4 by Bodigrim at 2022-12-08T22:46:47-05:00 Update submodule mtl to 2.3.1, parsec to 3.1.15.1, haddock and Cabal to HEAD - - - - - 08d8fe2a by Bodigrim at 2022-12-08T22:46:47-05:00 Allow mtl-2.3 in hadrian - - - - - 3807a46c by Bodigrim at 2022-12-08T22:46:47-05:00 Support mtl-2.3 in check-exact - - - - - ef702a18 by Bodigrim at 2022-12-08T22:46:47-05:00 Fix tests - - - - - 3144e8ff by Sebastian Graf at 2022-12-08T22:47:22-05:00 Make (^) INLINE (#22324) So that we get to cancel away the allocation for the lazily used base. We can move `powImpl` (which *is* strict in the base) to the top-level so that we don't duplicate too much code and move the SPECIALISATION pragmas onto `powImpl`. The net effect of this change is that `(^)` plays along much better with inlining thresholds and loopification (#22227), for example in `x2n1`. Fixes #22324. - - - - - 1d3a8b8e by Matthew Pickering at 2022-12-08T22:47:59-05:00 Typeable: Fix module locations of some definitions in GHC.Types There was some confusion in Data.Typeable about which module certain wired-in things were defined in. Just because something is wired-in doesn't mean it comes from GHC.Prim, in particular things like LiftedRep and RuntimeRep are defined in GHC.Types and that's the end of the story. Things like Int#, Float# etc are defined in GHC.Prim as they have no Haskell definition site at all so we need to generate type representations for them (which live in GHC.Types). Fixes #22510 - - - - - 0f7588b5 by Sebastian Graf at 2022-12-08T22:48:34-05:00 Make `drop` and `dropWhile` fuse (#18964) I copied the fusion framework we have in place for `take`. T18964 asserts that we regress neither when fusion fires nor when it doesn't. Fixes #18964. - - - - - 26e71562 by Sebastian Graf at 2022-12-08T22:49:10-05:00 Do not strictify a DFun's parameter dictionaries (#22549) ... thus fixing #22549. The details are in the refurbished and no longer dead `Note [Do not strictify a DFun's parameter dictionaries]`. There's a regression test in T22549. - - - - - 36093407 by John Ericson at 2022-12-08T22:49:45-05:00 Delete `rts/package.conf.in` It is a relic of the Make build system. The RTS now uses a `package.conf` file generated the usual way by Cabal. - - - - - b0cc2fcf by Krzysztof Gogolewski at 2022-12-08T22:50:21-05:00 Fixes around primitive literals * The SourceText of primitive characters 'a'# did not include the #, unlike for other primitive literals 1#, 1##, 1.0#, 1.0##, "a"#. We can now remove the function pp_st_suffix, which was a hack to add the # back. * Negative primitive literals shouldn't use parentheses, as described in Note [Printing of literals in Core]. Added a testcase to T14681. - - - - - aacf616d by Bryan Richter at 2022-12-08T22:50:56-05:00 testsuite: Mark conc024 fragile on Windows - - - - - ed239a24 by Ryan Scott at 2022-12-09T09:42:16-05:00 Document TH splices' interaction with INCOHERENT instances Top-level declaration splices can having surprising interactions with `INCOHERENT` instances, as observed in #22492. This patch resolves #22492 by documenting this strange interaction in the GHC User's Guide. [ci skip] - - - - - 1023b432 by Mike Pilgrem at 2022-12-09T09:42:56-05:00 Fix #22300 Document GHC's extensions to valid whitespace - - - - - 79b0cec0 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Add support for environments that don't have setImmediate - - - - - 5b007ec5 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Fix bound thread status - - - - - 65335d10 by Matthew Pickering at 2022-12-09T20:15:45-05:00 Update containers submodule This contains a fix necessary for the multi-repl to work on GHC's code base where we try to load containers and template-haskell into the same session. - - - - - 4937c0bb by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-multi: Put interface files in separate directories Before we were putting all the interface files in the same directory which was leading to collisions if the files were called the same thing. - - - - - 8acb5b7b by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-toolargs: Add filepath to allowed repl targets - - - - - 5949d927 by Matthew Pickering at 2022-12-09T20:15:45-05:00 driver: Set correct UnitId when rehydrating modules We were not setting the UnitId before rehydrating modules which just led to us attempting to find things in the wrong HPT. The test for this is the hadrian-multi command (which is now added as a CI job). Fixes #22222 - - - - - ab06c0f0 by Matthew Pickering at 2022-12-09T20:15:45-05:00 ci: Add job to test hadrian-multi command I am not sure this job is good because it requires booting HEAD with HEAD, but it should be fine. - - - - - fac3e568 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hadrian: Update bootstrap plans to 9.2.* series and 9.4.* series. This updates the build plans for the most recent compiler versions, as well as fixing the hadrian-bootstrap-gen script to a specific GHC version. - - - - - 195b08b4 by Matthew Pickering at 2022-12-09T20:16:20-05:00 ci: Bump boot images to use ghc-9.4.3 Also updates the bootstrap jobs to test booting 9.2 and 9.4. - - - - - c658c580 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hlint: Removed redundant UnboxedSums pragmas UnboxedSums is quite confusingly implied by UnboxedTuples, alas, just the way it is. See #22485 - - - - - b3e98a92 by Oleg Grenrus at 2022-12-11T12:26:17-05:00 Add heqT, a kind-heterogeneous variant of heq CLC proposal https://github.com/haskell/core-libraries-committee/issues/99 - - - - - bfd7c1e6 by Bodigrim at 2022-12-11T12:26:55-05:00 Document that Bifunctor instances for tuples are lawful only up to laziness - - - - - 5d1a1881 by Bryan Richter at 2022-12-12T16:22:36-05:00 Mark T21336a fragile - - - - - c30accc2 by Matthew Pickering at 2022-12-12T16:23:11-05:00 Add test for #21476 This issues seems to have been fixed since the ticket was made, so let's add a test and move on. Fixes #21476 - - - - - e9d74a3e by Sebastian Graf at 2022-12-13T22:18:39-05:00 Respect -XStrict in the pattern-match checker (#21761) We were missing a call to `decideBangHood` in the pattern-match checker. There is another call in `matchWrapper.mk_eqn_info` which seems redundant but really is not; see `Note [Desugaring -XStrict matches in Pmc]`. Fixes #21761. - - - - - 884790e2 by Gergő Érdi at 2022-12-13T22:19:14-05:00 Fix loop in the interface representation of some `Unfolding` fields As discovered in #22272, dehydration of the unfolding info of a recursive definition used to involve a traversal of the definition itself, which in turn involves traversing the unfolding info. Hence, a loop. Instead, we now store enough data in the interface that we can produce the unfolding info without this traversal. See Note [Tying the 'CoreUnfolding' knot] for details. Fixes #22272 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 9f301189 by Alan Zimmerman at 2022-12-13T22:19:50-05:00 EPA: When splitting out header comments, keep ones for first decl Any comments immediately preceding the first declaration are no longer kept as header comments, but attach to the first declaration instead. - - - - - 8b1f1b45 by Sylvain Henry at 2022-12-13T22:20:28-05:00 JS: fix object file name comparison (#22578) - - - - - e9e161bb by Bryan Richter at 2022-12-13T22:21:03-05:00 configure: Bump min bootstrap GHC version to 9.2 - - - - - 75855643 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Don't enable TSAN in stage0 build - - - - - da7b51d8 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce blockConcat - - - - - 34f6b09c by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce MemoryOrderings - - - - - 43beaa7b by Ben Gamari at 2022-12-15T03:54:02-05:00 llvm: Respect memory specified orderings - - - - - 8faf74fc by Ben Gamari at 2022-12-15T03:54:02-05:00 Codegen/x86: Eliminate barrier for relaxed accesses - - - - - 6cc3944a by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Reduce some repetition - - - - - 6c9862c4 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Add syntax for ordered loads and stores - - - - - 748490d2 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Atomic load syntax Originally I had thought I would just use the `prim` call syntax instead of introducing new syntax for atomic loads. However, it turns out that `prim` call syntax tends to make things quite unreadable. This new syntax seems quite natural. - - - - - 28c6781a by Ben Gamari at 2022-12-15T03:54:02-05:00 codeGen: Introduce ThreadSanitizer instrumentation This introduces a new Cmm pass which instruments the program with ThreadSanitizer annotations, allowing full tracking of mutator memory accesses via TSAN. - - - - - d97aa311 by Ben Gamari at 2022-12-15T03:54:02-05:00 Hadrian: Drop TSAN_ENABLED define from flavour This is redundant since the TSANUtils.h already defines it. - - - - - 86974ef1 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Enable Cmm instrumentation in TSAN flavour - - - - - 93723290 by Ben Gamari at 2022-12-15T03:54:02-05:00 rts: Ensure that global regs are never passed as fun call args This is in general unsafe as they may be clobbered if they are mapped to caller-saved machine registers. See Note [Register parameter passing]. - - - - - 2eb0fb87 by Matthew Pickering at 2022-12-15T03:54:39-05:00 Package Imports: Get candidate packages also from re-exported modules Previously we were just looking at the direct imports to try and work out what a package qualifier could apply to but #22333 pointed out we also needed to look for reexported modules. Fixes #22333 - - - - - 552b7908 by Ben Gamari at 2022-12-15T03:55:15-05:00 compiler: Ensure that MutVar operations have necessary barriers Here we add acquire and release barriers in readMutVar# and writeMutVar#, which are necessary for soundness. Fixes #22468. - - - - - 933d61a4 by Simon Peyton Jones at 2022-12-15T03:55:51-05:00 Fix bogus test in Lint The Lint check for branch compatiblity within an axiom, in GHC.Core.Lint.compatible_branches was subtly different to the check made when contructing an axiom, in GHC.Core.FamInstEnv.compatibleBranches. The latter is correct, so I killed the former and am now using the latter. On the way I did some improvements to pretty-printing and documentation. - - - - - 03ed0b95 by Ryan Scott at 2022-12-15T03:56:26-05:00 checkValidInst: Don't expand synonyms when splitting sigma types Previously, the `checkValidInst` function (used when checking that an instance declaration is headed by an actual type class, not a type synonym) was using `tcSplitSigmaTy` to split apart the `forall`s and instance context. This is incorrect, however, as `tcSplitSigmaTy` expands type synonyms, which can cause instances headed by quantified constraint type synonyms to be accepted erroneously. This patch introduces `splitInstTyForValidity`, a variant of `tcSplitSigmaTy` specialized for validity checking that does _not_ expand type synonyms, and uses it in `checkValidInst`. Fixes #22570. - - - - - ed056bc3 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/Messages: Refactor This doesn't change behavior but makes the code a bit easier to follow. - - - - - 7356f8e0 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/ThreadPaused: Ordering fixes - - - - - 914f0025 by Ben Gamari at 2022-12-16T16:12:44-05:00 eventlog: Silence spurious data race - - - - - fbc84244 by Ben Gamari at 2022-12-16T16:12:44-05:00 Introduce SET_INFO_RELEASE for Cmm - - - - - 821b5472 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Use fences instead of explicit barriers - - - - - 2228c999 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/stm: Fix memory ordering in readTVarIO# See #22421. - - - - - 99269b9f by Ben Gamari at 2022-12-16T16:12:44-05:00 Improve heap memory barrier Note Also introduce MUT_FIELD marker in Closures.h to document mutable fields. - - - - - 70999283 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. - - - - - 98689f77 by Ben Gamari at 2022-12-16T16:12:44-05:00 ghc: Fix data race in dump file handling Previously the dump filename cache would use a non-atomic update which could potentially result in lost dump contents. Note that this is still a bit racy since the first writer may lag behind a later appending writer. - - - - - 605d9547 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. - - - - - 86f20258 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. - - - - - f8e901dc by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. - - - - - e0affaa9 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate access to capabilities array - - - - - 7ca683e4 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate sched_state - - - - - 1cf13bd0 by Ben Gamari at 2022-12-16T16:12:45-05:00 PrimOps: Fix benign MutVar race Relaxed ordering is fine here since the later CAS implies a release. - - - - - 3d2a7e08 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Style fix - - - - - 82c62074 by Ben Gamari at 2022-12-16T16:12:45-05:00 compiler: Use release store in eager blackholing - - - - - eb1a0136 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Fix ordering of makeStableName - - - - - ad0e260a by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Use ordered accesses instead of explicit barriers - - - - - a3eccf06 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Statically allocate capabilities This is a rather simplistic way of solving #17289. - - - - - 287fa3fb by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Ensure that all accesses to pending_sync are atomic - - - - - 351eae58 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Note race with wakeBlockingQueue - - - - - 5acf33dd by Bodigrim at 2022-12-16T16:13:22-05:00 Bump submodule directory to 1.3.8.0 and hpc to HEAD - - - - - 0dd95421 by Bodigrim at 2022-12-16T16:13:22-05:00 Accept allocations increase on Windows This is because of `filepath-1.4.100.0` and AFPP, causing increasing round-trips between lists and ByteArray. See #22625 for discussion. Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T10547 T12150 T12227 T12234 T12425 T13035 T13253 T13253-spj T13701 T13719 T15703 T16875 T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T21839r T5837 T6048 T9198 T9961 TcPlugin_RewritePerf hard_hole_fits - - - - - ef9ac9d2 by Cheng Shao at 2022-12-16T16:13:59-05:00 testsuite: Mark T9405 as fragile instead of broken on Windows It's starting to pass again, and the unexpected pass blocks CI. - - - - - 1f3abd85 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: remove obsolete commented code in wasm NCG It was just a temporary hack to workaround a bug in the relooper, that bug has been fixed long before the wasm backend is merged. - - - - - e3104eab by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add missing export list of GHC.CmmToAsm.Wasm.FromCmm Also removes some unreachable code here. - - - - - 1c6930bf by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: change fallback function signature to Cmm function signature in wasm NCG In the wasm NCG, when handling a `CLabel` of undefined function without knowing its function signature, we used to fallback to `() -> ()` which is accepted by `wasm-ld`. This patch changes it to the signature of Cmm functions, which equally works, but would be required when we emit tail call instructions. - - - - - 8a81d9d9 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add optional tail-call support in wasm NCG When the `-mtail-call` clang flag is passed at configure time, wasm tail-call extension is enabled, and the wasm NCG will emit `return_call`/`return_call_indirect` instructions to take advantage of it and avoid the `StgRun` trampoline overhead. Closes #22461. - - - - - d1431cc0 by Cheng Shao at 2022-12-17T08:07:15-05:00 base: add missing autoconf checks for waitpid/umask These are not present in wasi-libc. Required for fixing #22589 - - - - - da3f1e91 by Cheng Shao at 2022-12-17T08:07:51-05:00 compiler: make .wasm the default executable extension on wasm32 Following convention as in other wasm toolchains. Fixes #22594. - - - - - ad21f4ef by Cheng Shao at 2022-12-17T08:07:51-05:00 ci: support hello.wasm in ci.sh cross testing logic - - - - - 6fe2d778 by amesgen at 2022-12-18T19:33:49-05:00 Correct `exitWith` Haddocks The `IOError`-specific `catch` in the Prelude is long gone. - - - - - b3eacd64 by Ben Gamari at 2022-12-18T19:34:24-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 761c1f49 by Ben Gamari at 2022-12-18T19:35:00-05:00 rts/libdw: Silence uninitialized usage warnings As noted in #22538, previously some GCC versions warned that various locals in Libdw.c may be used uninitialized. Although this wasn't strictly true (since they were initialized in an inline assembler block) we fix this by providing explicit empty initializers. Fixes #22538 - - - - - 5e047eff by Matthew Pickering at 2022-12-20T15:12:04+00:00 testsuite: Mark T16392 as fragile on windows See #22649 - - - - - 703a4665 by M Farkas-Dyck at 2022-12-20T21:14:46-05:00 Scrub some partiality in `GHC.Cmm.Info.Build`: `doSRTs` takes a `[(CAFSet, CmmDecl)]` but truly wants a `[(CAFSet, CmmStatics)]`. - - - - - 9736ab74 by Matthew Pickering at 2022-12-20T21:15:22-05:00 packaging: Fix upload_ghc_libs.py script This change reflects the changes where .cabal files are now generated by hadrian rather than ./configure. Fixes #22518 - - - - - 7c6de18d by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Drop uses of AC_PROG_CC_C99 As noted in #22566, this macro is deprecated as of autoconf-2.70 `AC_PROG_CC` now sets `ac_cv_prog_cc_c99` itself. Closes #22566. - - - - - 36c5d98e by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Use AS_HELP_STRING instead of AC_HELP_STRING The latter has been deprecated. See #22566. - - - - - befe6ff8 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: fix various usages of head and tail - - - - - 666d0ba7 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: avoid head and tail in parseCallEscape and around - - - - - 5d96fd50 by Bodigrim at 2022-12-20T21:16:37-05:00 Make GHC.Driver.Main.hscTcRnLookupRdrName to return NonEmpty - - - - - 3ce2ab94 by Bodigrim at 2022-12-21T06:17:56-05:00 Allow transformers-0.6 in ghc, ghci, ghc-bin and hadrian - - - - - 954de93a by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule haskeline to HEAD (to allow transformers-0.6) - - - - - cefbeec3 by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule transformers to 0.6.0.4 - - - - - b4730b62 by Bodigrim at 2022-12-21T06:17:56-05:00 Fix tests T13253 imports MonadTrans, which acquired a quantified constraint in transformers-0.6, thus increase in allocations Metric Increase: T13253 - - - - - 0be75261 by Simon Peyton Jones at 2022-12-21T06:18:32-05:00 Abstract over the right free vars Fix #22459, in two ways: (1) Make the Specialiser not create a bogus specialisation if it is presented by strangely polymorphic dictionary. See Note [Weird special case in SpecDict] in GHC.Core.Opt.Specialise (2) Be more careful in abstractFloats See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. So (2) stops creating the excessively polymorphic dictionary in abstractFloats, while (1) stops crashing if some other pass should nevertheless create a weirdly polymorphic dictionary. - - - - - df7bc6b3 by Ying-Ruei Liang (TheKK) at 2022-12-21T14:31:54-05:00 rts: explicitly store return value of ccall checkClosure to prevent type error (#22617) - - - - - e193e537 by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. - - - - - 3d55d8ab by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 - - - - - ceb2e9b9 by Ben Gamari at 2022-12-21T15:26:08-05:00 configure: Bump version to 9.6 - - - - - fb4d36c4 by Ben Gamari at 2022-12-21T15:27:49-05:00 base: Bump version to 4.18 Requires various submodule bumps. - - - - - 93ee7e90 by Ben Gamari at 2022-12-21T15:27:49-05:00 ghc-boot: Fix bootstrapping - - - - - fc3a2232 by Ben Gamari at 2022-12-22T13:45:06-05:00 Bump GHC version to 9.7 - - - - - 914f7fe3 by Andreas Klebinger at 2022-12-22T23:36:10-05:00 Don't consider large byte arrays/compact regions pinned. Workaround for #22255 which showed how treating large/compact regions as pinned could cause segfaults. - - - - - 32b32d7f by Matthew Pickering at 2022-12-22T23:36:46-05:00 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 - - - - - b3ddf803 by Ben Gamari at 2022-12-22T23:37:23-05:00 rts: Drop paths from configure from cabal file A long time ago we would rely on substitutions from the configure script to inject paths of the include and library directories of libffi and libdw. However, now these are instead handled inside Hadrian when calling Cabal's `configure` (see the uses of `cabalExtraDirs` in Hadrian's `Settings.Packages.packageArgs`). While the occurrences in the cabal file were redundant, they did no harm. However, since b5c714545abc5f75a1ffdcc39b4bfdc7cd5e64b4 they have no longer been interpolated. @mpickering noticed the suspicious uninterpolated occurrence of `@FFIIncludeDir@` in #22595, prompting this commit to finally remove them. - - - - - b2c7523d by Ben Gamari at 2022-12-22T23:37:59-05:00 Bump libffi-tarballs submodule We will now use libffi-3.4.4. - - - - - 3699a554 by Alan Zimmerman at 2022-12-22T23:38:35-05:00 EPA: Make EOF position part of AnnsModule Closes #20951 Closes #19697 - - - - - 99757ce8 by Sylvain Henry at 2022-12-22T23:39:13-05:00 JS: fix support for -outputdir (#22641) The `-outputdir` option wasn't correctly handled with the JS backend because the same code path was used to handle both objects produced by the JS backend and foreign .js files. Now we clearly distinguish the two in the pipeline, fixing the bug. - - - - - 02ed7d78 by Simon Peyton Jones at 2022-12-22T23:39:49-05:00 Refactor mkRuntimeError This patch fixes #22634. Because we don't have TYPE/CONSTRAINT polymorphism, we need two error functions rather than one. I took the opportunity to rname runtimeError to impossibleError, to line up with mkImpossibleExpr, and avoid confusion with the genuine runtime-error-constructing functions. - - - - - 35267f07 by Ben Gamari at 2022-12-22T23:40:32-05:00 base: Fix event manager shutdown race on non-Linux platforms During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this. - - - - - 317f45c1 by Simon Peyton Jones at 2022-12-22T23:41:07-05:00 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 - - - - - 14b2e3d3 by Ben Gamari at 2022-12-22T23:41:42-05:00 rts/m32: Fix sanity checking Previously we would attempt to clear pages which were marked as read-only. Fix this. - - - - - 16a1bcd1 by Matthew Pickering at 2022-12-23T09:15:24+00:00 ci: Move wasm pipelines into nightly rather than master See #22664 for the changes which need to be made to bring one of these back to the validate pipeline. - - - - - 18d2acd2 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. - - - - - 11241efa by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix segment list races - - - - - 602455c9 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. - - - - - 9d63b160 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. - - - - - 26837523 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that mutable fields have acquire barrier - - - - - 8093264a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. - - - - - 387d4fcc by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make segment state updates atomic - - - - - 543cae00 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. - - - - - c9936718 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. - - - - - 0cd31f7d by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. - - - - - d3fe110a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. - - - - - ab6cf893 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. - - - - - 36c9f23c by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). - - - - - aebef31c by doyougnu at 2022-12-23T19:10:09-05:00 add GHC.Utils.Binary.foldGet' and use for Iface A minor optimization to remove lazy IO and a lazy accumulator strictify foldGet' IFace.Binary: use strict foldGet' remove superfluous bang - - - - - 5eb357d9 by Ben Gamari at 2022-12-24T00:41:05-05:00 compiler: Ensure that GHC toolchain is first in search path As noted in #22561, it is important that GHC's toolchain look first for its own headers and libraries to ensure that the system's are not found instead. If this happens things can break in surprising ways (e.g. see #22561). - - - - - cbaebfb9 by Matthew Pickering at 2022-12-24T00:41:40-05:00 head.hackage: Use slow-validate bindist for linting jobs This enables the SLOW_VALIDATE env var for the linting head.hackage jobs, namely the jobs enabled manually, by the label or on the nightly build now use the deb10-numa-slow-validate bindist which has assertions enabled. See #22623 for a ticket which was found by using this configuration already! The head.hackage jobs triggered by upstream CI are now thusly: hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. Runs head.hackage with -dlint and a slow-validate bindist hackage-label-lint: Trigged on MRs with "user-facing" label, runs the slow-validate head.hackage build with -dlint. nightly-hackage-lint: Runs automatically on nightly pipelines with slow-validate + dlint config. nightly-hackage-perf: Runs automaticaly on nightly pipelines with release build and eventlogging enabled. release-hackage-lint: Runs automatically on release pipelines with -dlint on a release bindist. - - - - - f4850f36 by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Don't run abi-test-nightly on release jobs The test is not configured to get the correct dependencies for the release pipelines (and indeed stops the release pipeline being run at all) - - - - - c264b06b by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Run head.hackage jobs on upstream-testing branch rather than master This change allows less priviledged users to trigger head.hackage jobs because less permissions are needed to trigger jobs on the upstream-testing branch, which is not protected. There is a CI job which updates upstream-testing each hour to the state of the master branch so it should always be relatively up-to-date. - - - - - 63b97430 by Ben Gamari at 2022-12-24T00:42:16-05:00 llvmGen: Fix relaxed ordering Previously I used LLVM's `unordered` ordering for the C11 `relaxed` ordering. However, this is wrong and should rather use the LLVM `monotonic` ordering. Fixes #22640 - - - - - f42ba88f by Ben Gamari at 2022-12-24T00:42:16-05:00 gitlab-ci: Introduce aarch64-linux-llvm job This nightly job will ensure that we don't break the LLVM backend on AArch64/Linux by bootstrapping GHC. This would have caught #22640. - - - - - 6d62f6bf by Matthew Pickering at 2022-12-24T00:42:51-05:00 Store RdrName rather than OccName in Holes In #20472 it was pointed out that you couldn't defer out of scope but the implementation collapsed a RdrName into an OccName to stuff it into a Hole. This leads to the error message for a deferred qualified name dropping the qualification which affects the quality of the error message. This commit adds a bit more structure to a hole, so a hole can replace a RdrName without losing information about what that RdrName was. This is important when printing error messages. I also added a test which checks the Template Haskell deferral of out of scope qualified names works properly. Fixes #22130 - - - - - 3c3060e4 by Richard Eisenberg at 2022-12-24T17:34:19+00:00 Drop support for kind constraints. This implements proposal 547 and closes ticket #22298. See the proposal and ticket for motivation. Compiler perf improves a bit Metrics: compile_time/bytes allocated ------------------------------------- CoOpt_Singletons(normal) -2.4% GOOD T12545(normal) +1.0% T13035(normal) -13.5% GOOD T18478(normal) +0.9% T9872d(normal) -2.2% GOOD geo. mean -0.2% minimum -13.5% maximum +1.0% Metric Decrease: CoOpt_Singletons T13035 T9872d - - - - - 6d7d4393 by Ben Gamari at 2022-12-24T21:09:56-05:00 hadrian: Ensure that linker scripts are used when merging objects In #22527 @rui314 inadvertantly pointed out a glaring bug in Hadrian's implementation of the object merging rules: unlike the old `make` build system we utterly failed to pass the needed linker scripts. Fix this. - - - - - a5bd0eb8 by Bodigrim at 2022-12-24T21:10:34-05:00 Document infelicities of instance Ord Double and workarounds - - - - - 62b9a7b2 by Zubin Duggal at 2023-01-03T12:22:11+00:00 Force the Docs structure to prevent leaks in GHCi with -haddock without -fwrite-interface Involves adding many new NFData instances. Without forcing Docs, references to the TcGblEnv for each module are retained by the Docs structure. Usually these are forced when the ModIface is serialised but not when we aren't writing the interface. - - - - - 21bedd84 by Facundo Domínguez at 2023-01-03T23:27:30-05:00 Explain the auxiliary functions of permutations - - - - - 32255d05 by Matthew Pickering at 2023-01-04T11:58:42+00:00 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. - - - - - e640940c by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Fix computation of tables_next_to_code for outOfTreeCompiler This copy-pasto was introduced in de5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b - - - - - 15bee123 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 - - - - - fec6638e by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. - - - - - 3dc05726 by Matthew Pickering at 2023-01-04T11:58:42+00:00 check-exact: Fix build with -Werror - - - - - 53a6ae7a by Matthew Pickering at 2023-01-04T11:58:42+00:00 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 - - - - - 32e264c1 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 - - - - - be9dd9b0 by Matthew Pickering at 2023-01-04T11:58:42+00:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 - - - - - 00dc5106 by Matthew Pickering at 2023-01-04T14:32:45-05:00 sphinx: Use modern syntax for extlinks This fixes the following build error: ``` Command line: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build -b man -d /private/tmp/extra-dir-55768274273/.doctrees-man -n -w /private/tmp/extra-dir-55768274273/.log docs/users_guide /private/tmp/extra-dir-55768274273 ===> Command failed with error code: 2 Exception occurred: File "/opt/homebrew/Cellar/sphinx-doc/6.0.0/libexec/lib/python3.11/site-packages/sphinx/ext/extlinks.py", line 101, in role title = caption % part ~~~~~~~~^~~~~~ TypeError: not all arguments converted during string formatting ``` I tested on Sphinx-5.1.1 and Sphinx-6.0.0 Thanks for sterni for providing instructions about how to test using sphinx-6.0.0. Fixes #22690 - - - - - 541aedcd by Krzysztof Gogolewski at 2023-01-05T10:48:34-05:00 Misc cleanup - Remove unused uniques and hs-boot declarations - Fix types of seq and unsafeCoerce# - Remove FastString/String roundtrip in JS - Use TTG to enforce totality - Remove enumeration in Heap/Inspect; the 'otherwise' clause serves the primitive types well. - - - - - 22bb8998 by Alan Zimmerman at 2023-01-05T10:49:09-05:00 EPA: Do not collect comments from end of file In Parser.y semis1 production triggers for the virtual semi at the end of the file. This is detected by it being zero length. In this case, do not extend the span being used to gather comments, so any final comments are allocated at the module level instead. - - - - - 9e077999 by Vladislav Zavialov at 2023-01-05T23:01:55-05:00 HsToken in TypeArg (#19623) Updates the haddock submodule. - - - - - b2a2db04 by Matthew Pickering at 2023-01-05T23:02:30-05:00 Revert "configure: Drop uses of AC_PROG_CC_C99" This reverts commit 7c6de18dd3151ead954c210336728e8686c91de6. Centos7 using a very old version of the toolchain (autotools-2.69) where the behaviour of these macros has not yet changed. I am reverting this without haste as it is blocking the 9.6 branch. Fixes #22704 - - - - - 28f8c0eb by Luite Stegeman at 2023-01-06T18:16:24+09:00 Add support for sized literals in the bytecode interpreter. The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945 - - - - - ac39e8e9 by Matthew Pickering at 2023-01-06T13:47:00-05:00 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 - - - - - c306d939 by Matthew Pickering at 2023-01-06T22:08:53-05:00 ci: Upgrade darwin, windows and freebsd CI to use GHC-9.4.3 Fixes #22599 - - - - - 0db496ff by Matthew Pickering at 2023-01-06T22:08:53-05:00 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 2459c358 by Ben Gamari at 2023-01-06T22:09:29-05:00 rts: MUT_VAR is not a StgMutArrPtrs There was previously a comment claiming that the MUT_VAR closure type had the layout of StgMutArrPtrs. - - - - - 6206cb92 by Simon Peyton Jones at 2023-01-07T12:14:40-05:00 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 - - - - - a960ca81 by Matthew Pickering at 2023-01-07T12:15:15-05:00 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s - - - - - 73484710 by Matthew Pickering at 2023-01-07T12:15:15-05:00 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. - - - - - 8c0ea25f by Matthew Pickering at 2023-01-07T12:15:15-05:00 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes - - - - - 365b3045 by Matthew Pickering at 2023-01-09T02:36:20-05:00 Disable split sections on aarch64-deb10 build See #22722 Failure on this job: https://gitlab.haskell.org/ghc/ghc/-/jobs/1287852 ``` Unexpected failures: /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T10828.run T10828 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T13123.run T13123 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T20590.run T20590 [exit code non-0] (ext-interp) Appending 232 stats to file: /builds/ghc/ghc/performance-metrics.tsv ``` ``` Compile failed (exit code 1) errors were: data family D_0 a_1 :: * -> * data instance D_0 GHC.Types.Int GHC.Types.Bool :: * where DInt_2 :: D_0 GHC.Types.Int GHC.Types.Bool data E_3 where MkE_4 :: a_5 -> E_3 data Foo_6 a_7 b_8 where MkFoo_9, MkFoo'_10 :: a_11 -> Foo_6 a_11 b_12 newtype Bar_13 :: * -> GHC.Types.Bool -> * where MkBar_14 :: a_15 -> Bar_13 a_15 b_16 data T10828.T (a_0 :: *) where T10828.MkT :: forall (a_1 :: *) . a_1 -> a_1 -> T10828.T a_1 T10828.MkC :: forall (a_2 :: *) (b_3 :: *) . (GHC.Types.~) a_2 GHC.Types.Int => {T10828.foo :: a_2, T10828.bar :: b_3} -> T10828.T GHC.Types.Int T10828.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: (do TyConI dec <- runQ $ reify (mkName "T") runIO $ putStrLn (pprint dec) >> hFlush stdout d <- runQ $ [d| data T' a :: Type where MkT' :: a -> a -> T' a MkC' :: forall a b. (a ~ Int) => {foo :: a, bar :: b} -> T' Int |] runIO $ putStrLn (pprint d) >> hFlush stdout ....) *** unexpected failure for T10828(ext-interp) =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] Compile failed (exit code 1) errors were: T13123.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data GADT where MkGADT :: forall k proxy (a :: k). proxy a -> GADT |]) *** unexpected failure for T13123(ext-interp) =====> 7100 of 9215 [0, 2, 0] =====> 7100 of 9215 [0, 2, 0] =====> 7200 of 9215 [0, 2, 0] Compile failed (exit code 1) errors were: T20590.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data T where MkT :: forall a. a -> T |]) *** unexpected failure for T20590(ext-interp) ``` Looks fairly worrying to me. - - - - - 965a2735 by Alan Zimmerman at 2023-01-09T02:36:20-05:00 EPA: exact print HsDocTy To match ghc-exactprint https://github.com/alanz/ghc-exactprint/pull/121 - - - - - 5d65773e by John Ericson at 2023-01-09T20:39:27-05:00 Remove RTS hack for configuring See the brand new Note [Undefined symbols in the RTS] for additional details. - - - - - e3fff751 by Sebastian Graf at 2023-01-09T20:40:02-05:00 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite - - - - - d53f6f4d by Oleg Grenrus at 2023-01-09T21:11:02-05:00 Add safe list indexing operator: !? With Joachim's amendments. Implements https://github.com/haskell/core-libraries-committee/issues/110 - - - - - cfaf1ad7 by Nicolas Trangez at 2023-01-09T21:11:03-05:00 rts, tests: limit thread name length to 15 bytes On Linux, `pthread_setname_np` (or rather, the kernel) only allows for thread names up to 16 bytes, including the terminating null byte. This commit adds a note pointing this out in `createOSThread`, and fixes up two instances where a thread name of more than 15 characters long was used (in the RTS, and in a test-case). Fixes: #22366 Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/22366 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22366#note_460796 - - - - - 64286132 by Matthew Pickering at 2023-01-09T21:11:03-05:00 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 - - - - - 4724e8d1 by Matthew Pickering at 2023-01-09T21:11:04-05:00 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 - - - - - 2e926b88 by Georgi Lyubenov at 2023-01-09T21:11:07-05:00 Fix outdated link to Happy section on sequences - - - - - 146a1458 by Matthew Pickering at 2023-01-09T21:11:07-05:00 Revert "NCG(x86): Compile add+shift as lea if possible." This reverts commit 20457d775885d6c3df020d204da9a7acfb3c2e5a. See #22666 and #21777 - - - - - 6e6adbe3 by Jade Lovelace at 2023-01-11T00:55:30-05:00 Fix tcPluginRewrite example - - - - - faa57138 by Jade Lovelace at 2023-01-11T00:55:31-05:00 fix missing haddock pipe - - - - - 0470ea7c by Florian Weimer at 2023-01-11T00:56:10-05:00 m4/fp_leading_underscore.m4: Avoid implicit exit function declaration And switch to a new-style function definition. Fixes build issues with compilers that do not accept implicit function declarations. - - - - - b2857df4 by HaskellMouse at 2023-01-11T00:56:52-05:00 Added a new warning about compatibility with RequiredTypeArguments This commit introduces a new warning that indicates code incompatible with future extension: RequiredTypeArguments. Enabling this extension may break some code and the warning will help to make it compatible in advance. - - - - - 5f17e21a by Ben Gamari at 2023-01-11T00:57:27-05:00 testsuite: Drop testheapalloced.c As noted in #22414, this file (which appears to be a benchmark for characterising the one-step allocator's MBlock cache) is currently unreferenced. Remove it. Closes #22414. - - - - - bc125775 by Vladislav Zavialov at 2023-01-11T00:58:03-05:00 Introduce the TypeAbstractions language flag GHC Proposals #448 "Modern scoped type variables" and #425 "Invisible binders in type declarations" introduce a new language extension flag: TypeAbstractions. Part of the functionality guarded by this flag has already been implemented, namely type abstractions in constructor patterns, but it was guarded by a combination of TypeApplications and ScopedTypeVariables instead of a dedicated language extension flag. This patch does the following: * introduces a new language extension flag TypeAbstractions * requires TypeAbstractions for @a-syntax in constructor patterns instead of TypeApplications and ScopedTypeVariables * creates a User's Guide page for TypeAbstractions and moves the "Type Applications in Patterns" section there To avoid a breaking change, the new flag is implied by ScopedTypeVariables and is retroactively added to GHC2021. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 083f7015 by Krzysztof Gogolewski at 2023-01-11T00:58:38-05:00 Misc cleanup - Remove unused mkWildEvBinder - Use typeTypeOrConstraint - more symmetric and asserts that that the type is Type or Constraint - Fix escape sequences in Python; they raise a deprecation warning with -Wdefault - - - - - aed1974e by Richard Eisenberg at 2023-01-11T08:30:42+00:00 Refactor the treatment of loopy superclass dicts This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows. - - - - - 300bcc15 by HaskellMouse at 2023-01-11T13:43:36-05:00 Parse qualified terms in type signatures This commit allows qualified terms in type signatures to pass the parser and to be cathced by renamer with more informative error message. Adds a few tests. Fixes #21605 - - - - - 964284fc by Simon Peyton Jones at 2023-01-11T13:44:12-05:00 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. - - - - - f7ceafc9 by Krzysztof Gogolewski at 2023-01-11T22:36:59-05:00 Add 'docWithStyle' to improve codegen This new combinator docWithStyle :: IsOutput doc => doc -> (PprStyle -> SDoc) -> doc let us remove the need for code to be polymorphic in HDoc when not used in code style. Metric Decrease: ManyConstructors T13035 T1969 - - - - - b3be0d18 by Simon Peyton Jones at 2023-01-11T22:37:35-05:00 Fix finaliseArgBoxities for OPAQUE function We never do worker wrapper for OPAQUE functions, so we must zap the unboxing info during strictness analysis. This patch fixes #22502 - - - - - db11f358 by Ben Gamari at 2023-01-12T07:49:04-05:00 Revert "rts: Drop racy assertion" The logic here was inverted. Reverting the commit to avoid confusion when examining the commit history. This reverts commit b3eacd64fb36724ed6c5d2d24a81211a161abef1. - - - - - 3242139f by Ben Gamari at 2023-01-12T07:49:04-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 9ffd5d57 by Ben Gamari at 2023-01-12T07:49:41-05:00 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. - - - - - 905d0b6e by Sebastian Graf at 2023-01-12T15:51:47-05:00 Fix contification with stable unfoldings (#22428) Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with a `JoinArity` that reflects the number of join point binders around the body for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by `occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`. I adjusted `Note [Join points and unfoldings/rules]` and `Note [Adjusting right-hand sides]` to account for the new machinery. I also wrote a new `Note [Join arity prediction based on joinRhsArity]` and refer to it when we combine `TailUsageDetails` for a recursive RHS. I also renamed * `occAnalLam` to `occAnalLamTail` * `adjustRhsUsage` to `adjustTailUsage` * a few other less important functions and properly documented the that each call of `occAnalLamTail` must pair up with `adjustTailUsage`. I removed `Note [Unfoldings and join points]` because it was redundant with `Note [Occurrences in stable unfoldings]`. While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed `NodeDetails` called `SimpleNodeDetails`. Fixes #22428. The refactoring seems to have quite beneficial effect on ghc/alloc performance: ``` CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2% T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6% T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2% T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0% T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5% T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6% T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9% T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD geo. mean -0.6% minimum -2.4% maximum -0.0% ``` Metric Decrease: CoOpt_Read T10421 T12150 T12425 T13056 T18698a T18698b T21839c T21839r T9961 - - - - - a1491c87 by Andreas Klebinger at 2023-01-12T15:52:23-05:00 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. - - - - - 8acfe930 by Cheng Shao at 2023-01-12T15:53:00-05:00 Change MSYSTEM to CLANG64 uniformly - - - - - 73bc162b by M Farkas-Dyck at 2023-01-12T15:53:42-05:00 Make `GHC.Tc.Errors.Reporter` take `NonEmpty ErrorItem` rather than `[ErrorItem]`, which lets us drop some panics. Also use the `BasicMismatch` constructor rather than `mkBasicMismatchMsg`, which lets us drop the "-Wno-incomplete-record-updates" flag. - - - - - 1b812b69 by Oleg Grenrus at 2023-01-12T15:54:21-05:00 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general - - - - - c79b2b65 by Matthew Pickering at 2023-01-12T15:54:58-05:00 Don't run hadrian-multi on fast-ci label Fixes #22667 - - - - - 9a3d6add by Bodigrim at 2023-01-13T00:46:36-05:00 Bump submodule bytestring to 0.11.4.0 Metric Decrease: T21839c T21839r - - - - - df33c13c by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Bump Darwin bootstrap toolchain This updates the bootstrap compiler on Darwin from 8.10.7 to 9.2.5, ensuring that we have the fix for #21964. - - - - - 756a66ec by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Pass -w to cabal update Due to cabal#8447, cabal-install 3.8.1.0 requires a compiler to run `cabal update`. - - - - - 1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump hsc2hs submodule - - - - - d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump process submodule - - - - - 84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: Bump DOCKER_REV - - - - - d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: enable xz parallel compression for x64 jobs - - - - - d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: use in-image emsdk for js jobs - - - - - 93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings - Add a ghc environment including prebuilt dependencies to the nix-shell. Get rid of the ad hoc cabal cache and all dependencies are now downloaded from the nixos binary cache. - Make gen_ci.hs a cabal package with HLS integration, to make future hacking of gen_ci.hs easier. - Fix some ghc/hlint warnings after I got HLS to work. - For the lint-ci-config job, do a shallow clone to save a few minutes of unnecessary git checkout time. - - - - - 8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: source the toolchain env file in wasm jobs - - - - - 87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: add wasm ci jobs via gen_ci.hs - There is one regular wasm job run in validate pipelines - Additionally, int-native/unreg wasm jobs run in nightly/release pipelines Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml. - - - - - b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00 wasm ci: Remove wasm release jobs This removes the wasm release jobs, as we do not yet intend to distribute these binaries. - - - - - 496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. - - - - - 7a9a1042 by Andreas Klebinger at 2023-01-16T20:48:19-05:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 33b58f77 by sheaf at 2023-01-16T20:48:57-05:00 Hadrian: generalise &%> to avoid warnings This patch introduces a more general version of &%> that works with general traversable shapes, instead of lists. This allows us to pass along the information that the length of the list of filepaths passed to the function exactly matches the length of the input list of filepath patterns, avoiding pattern match warnings. Fixes #22430 - - - - - 8c7a991c by Andreas Klebinger at 2023-01-16T20:49:34-05:00 Add regression test for #22611. A case were a function used to fail to specialize, but now does. - - - - - 6abea760 by Andreas Klebinger at 2023-01-16T20:50:10-05:00 Mark maximumBy/minimumBy as INLINE. The RHS was too large to inline which often prevented the overhead of the Maybe from being optimized away. By marking it as INLINE we can eliminate the overhead of both the maybe and are able to unpack the accumulator when possible. Fixes #22609 - - - - - 99d151bb by Matthew Pickering at 2023-01-16T20:50:50-05:00 ci: Bump CACHE_REV so that ghc-9.6 branch and HEAD have different caches Having the same CACHE_REV on both branches leads to issues where the darwin toolchain is different on ghc-9.6 and HEAD which leads to long darwin build times. In general we should ensure that each branch has a different CACHE_REV. - - - - - 6a5845fb by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in source-tarball job This fixes errors of the form: ``` fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc inferred 9.7.20230113 checking for GHC Git commit id... fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc ``` - - - - - 4afb952c by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't build aarch64-deb10-llvm job on release pipelines Closes #22721 - - - - - 8039feb9 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in test-bootstrap job - - - - - 0b358d0c by Matthew Pickering at 2023-01-16T20:51:25-05:00 rel_eng: Add release engineering scripts into ghc tree It is better to keep these scripts in the tree as they depend on the CI configuration and so on. By keeping them in tree we can keep them up-to-date as the CI config changes and also makes it easier to backport changes to the release script between release branches in future. The final motivation is that it makes generating GHCUp metadata possible. - - - - - 28cb2ed0 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't use complicated image or clone in not-interruptible job This job exists only for the meta-reason of not allowing nightly pipelines to be cancelled. It was taking two minutes to run as in order to run "true" we would also clone the whole GHC repo. - - - - - eeea59bb by Matthew Pickering at 2023-01-16T20:51:26-05:00 Add scripts to generate ghcup metadata on nightly and release pipelines 1. A python script in .gitlab/rel_eng/mk-ghcup-metadata which generates suitable metadata for consumption by GHCUp for the relevant pipelines. - The script generates the metadata just as the ghcup maintainers want, without taking into account platform/library combinations. It is updated manually when the mapping changes. - The script downloads the bindists which ghcup wants to distribute, calculates the hash and generates the yaml in the correct structure. - The script is documented in the .gitlab/rel_eng/mk-ghcup-metadata/README.mk file 1a. The script requires us to understand the mapping from platform -> job. To choose the preferred bindist for each platform the .gitlab/gen_ci.hs script is modified to allow outputting a metadata file which answers the question about which job produces the bindist which we want to distribute to users for a specific platform. 2. Pipelines to run on nightly and release jobs to generate metadata - ghcup-metadata-nightly: Generates metadata which points directly to artifacts in the nightly job. - ghcup-metadata-release: Generates metadata suitable for inclusion directly in ghcup by pointing to the downloads folder where the bindist will be uploaded to. 2a. Trigger jobs which test the generated metadata in the downstream `ghccup-ci` repo. See that repo for documentation about what is tested and how but essentially we test in a variety of clean images that ghcup can download and install the bindists we say exist in our metadata. - - - - - 97bd4d8c by Bodigrim at 2023-01-16T20:52:04-05:00 Bump submodule parsec to 3.1.16.1 - - - - - 97ac8230 by Alan Zimmerman at 2023-01-16T20:52:39-05:00 EPA: Add annotation for 'type' in DataDecl Closes #22765 - - - - - dbbab95d by Ben Gamari at 2023-01-17T06:36:06-05:00 compiler: Small optimisation of assertM In #22739 @AndreasK noticed that assertM performed the action to compute the asserted predicate regardless of whether DEBUG is enabled. This is inconsistent with the other assertion operations and general convention. Fix this. Closes #22739. - - - - - fc02f3bb by Viktor Dukhovni at 2023-01-17T06:36:47-05:00 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 - - - - - 003b6d44 by Simon Peyton Jones at 2023-01-17T16:33:05-05:00 Document the semantics of pattern bindings a bit better This MR is in response to the discussion on #22719 - - - - - f4d50baf by Vladislav Zavialov at 2023-01-17T16:33:41-05:00 Hadrian: fix warnings (#22783) This change fixes the following warnings when building Hadrian: src/Hadrian/Expression.hs:38:10: warning: [-Wredundant-constraints] src/Hadrian/Expression.hs:84:13: warning: [-Wtype-equality-requires-operators] src/Hadrian/Expression.hs:84:21: warning: [-Wtype-equality-requires-operators] src/Hadrian/Haskell/Cabal/Parse.hs:67:1: warning: [-Wunused-imports] - - - - - 06036d93 by Sylvain Henry at 2023-01-18T01:55:10-05:00 testsuite: req_smp --> req_target_smp, req_ghc_smp See #22630 and !9552 This commit: - splits req_smp into req_target_smp and req_ghc_smp - changes the testsuite driver to calculate req_ghc_smp - changes a handful of tests to use req_target_smp instead of req_smp - changes a handful of tests to use req_host_smp when needed The problem: - the problem this solves is the ambiguity surrounding req_smp - on master req_smp was used to express the constraint that the program being compiled supports smp _and_ that the host RTS (i.e., the RTS used to compile the program) supported smp. Normally that is fine, but in cross compilation this is not always the case as was discovered in #22630. The solution: - Differentiate the two constraints: - use req_target_smp to say the RTS the compiled program is linked with (and the platform) supports smp - use req_host_smp to say the RTS the host is linked with supports smp WIP: fix req_smp (target vs ghc) add flag to separate bootstrapper split req_smp -> req_target_smp and req_ghc_smp update tests smp flags cleanup and add some docstrings only set ghc_with_smp to bootstrapper on S1 or CC Only set ghc_with_smp to bootstrapperWithSMP of when testing stage 1 and cross compiling test the RTS in config/ghc not hadrian re-add ghc_with_smp fix and align req names fix T11760 to use req_host_smp test the rts directly, avoid python 3.5 limitation test the compiler in a try block align out of tree and in tree withSMP flags mark failing tests as host req smp testsuite: req_host_smp --> req_ghc_smp Fix ghc vs host, fix ghc_with_smp leftover - - - - - ee9b78aa by Krzysztof Gogolewski at 2023-01-18T01:55:45-05:00 Use -Wdefault when running Python testdriver (#22727) - - - - - e9c0537c by Vladislav Zavialov at 2023-01-18T01:56:22-05:00 Enable -Wstar-is-type by default (#22759) Following the plan in GHC Proposal #143 "Remove the * kind syntax", which states: In the next release (or 3 years in), enable -fwarn-star-is-type by default. The "next release" happens to be 9.6.1 I also moved the T21583 test case from should_fail to should_compile, because the only reason it was failing was -Werror=compat in our test suite configuration. - - - - - 4efee43d by Ryan Scott at 2023-01-18T01:56:59-05:00 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. - - - - - f891a442 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. - - - - - b13c6ea5 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. - - - - - c45a5fff by Cheng Shao at 2023-01-18T07:28:37-05:00 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. - - - - - b4c14c4b by Luite Stegeman at 2023-01-18T14:21:42-05:00 Add PrimCallConv support to GHCi This adds support for calling Cmm code from bytecode using the native calling convention, allowing modules that use `foreign import prim` to be loaded and debugged in GHCi. This patch introduces a new `PRIMCALL` bytecode instruction and a helper stack frame `stg_primcall`. The code is based on the existing functionality for dealing with unboxed tuples in bytecode, which has been generalised to handle arbitrary calls. Fixes #22051 - - - - - d0a63ef8 by Adam Gundry at 2023-01-18T14:22:26-05:00 Refactor warning flag parsing to add missing flags This adds `-Werror=<group>` and `-fwarn-<group>` flags for warning groups as well as individual warnings. Previously these were defined on an ad hoc basis so for example we had `-Werror=compat` but not `-Werror=unused-binds`, whereas we had `-fwarn-unused-binds` but not `-fwarn-compat`. Fixes #22182. - - - - - 7ed1b8ef by Adam Gundry at 2023-01-18T14:22:26-05:00 Minor corrections to comments - - - - - 5389681e by Adam Gundry at 2023-01-18T14:22:26-05:00 Revise warnings documentation in user's guide - - - - - ab0d5cda by Adam Gundry at 2023-01-18T14:22:26-05:00 Move documentation of deferred type error flags out of warnings section - - - - - eb5a6b91 by John Ericson at 2023-01-18T22:24:10-05:00 Give the RTS it's own configure script Currently it doesn't do much anything, we are just trying to introduce it without breaking the build. Later, we will move functionality from the top-level configure script over to it. We need to bump Cabal for https://github.com/haskell/cabal/pull/8649; to facilitate and existing hack of skipping some configure checks for the RTS we now need to skip just *part* not *all* of the "post configure" hook, as running the configure script (which we definitely want to do) is also implemented as part of the "post configure" hook. But doing this requires exposing functionality that wasn't exposed before. - - - - - 32ab07bf by Bodigrim at 2023-01-18T22:24:51-05:00 ghc package does not have to depend on terminfo - - - - - 981ff7c4 by Bodigrim at 2023-01-18T22:24:51-05:00 ghc-pkg does not have to depend on terminfo - - - - - f058e367 by Ben Gamari at 2023-01-18T22:25:27-05:00 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. - - - - - 154889db by Ryan Scott at 2023-01-18T22:26:03-05:00 Add regression test for #22151 Issue #22151 was coincidentally fixed in commit aed1974e92366ab8e117734f308505684f70cddf (`Refactor the treatment of loopy superclass dicts`). This adds a regression test to ensure that the issue remains fixed. Fixes #22151. - - - - - 14b5982a by Andrei Borzenkov at 2023-01-18T22:26:43-05:00 Fix printing of promoted MkSolo datacon (#22785) Problem: In 2463df2f, the Solo data constructor was renamed to MkSolo, and Solo was turned into a pattern synonym for backwards compatibility. Since pattern synonyms can not be promoted, the old code that pretty-printed promoted single-element tuples started producing ill-typed code: t :: Proxy ('Solo Int) This fails with "Pattern synonym ‘Solo’ used as a type" The solution is to track the distinction between type constructors and data constructors more carefully when printing single-element tuples. - - - - - 1fe806d3 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add hi_core flavour transformer The hi_core flavour transformer enables -fwrite-if-simplified-core for stage1 libraries, which emit core into interface files to make it possible to restart code generation. Building boot libs with it makes it easier to use GHC API to prototype experimental backends that needs core/stg at link time. - - - - - 317cad26 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add missing docs for recently added flavour transformers - - - - - 658f4446 by Ben Gamari at 2023-01-23T04:49:23-05:00 gitlab-ci: Add Rocky8 jobs Addresses #22268. - - - - - a83ec778 by Vladislav Zavialov at 2023-01-23T04:49:58-05:00 Set "since: 9.8" for TypeAbstractions and -Wterm-variable-capture These flags did not make it into the 9.6 release series, so the "since" annotations must be corrected. - - - - - fec7c2ea by Alan Zimmerman at 2023-01-23T04:50:33-05:00 EPA: Add SourceText to HsOverLabel To be able to capture string literals with possible escape codes as labels. Close #22771 - - - - - 3efd1e99 by Ben Gamari at 2023-01-23T04:51:08-05:00 template-haskell: Bump version to 2.20.0.0 Updates `text` and `exceptions` submodules for bounds bumps. Addresses #22767. - - - - - 0900b584 by Cheng Shao at 2023-01-23T04:51:45-05:00 hadrian: disable alloca for in-tree GMP on wasm32 When building in-tree GMP for wasm32, disable its alloca usage, since it may potentially cause stack overflow (e.g. #22602). - - - - - db0f1bfd by Cheng Shao at 2023-01-23T04:52:21-05:00 Bump process submodule Includes a critical fix for wasm32, see https://github.com/haskell/process/pull/272 for details. Also changes the existing cross test to include process stuff and avoid future regression here. - - - - - 9222b167 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Fix subdir for windows bindist - - - - - 9a9bec57 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Remove viPostRemove field from generated metadata This has been removed from the downstream metadata. - - - - - 82884ce0 by Simon Peyton Jones at 2023-01-23T04:53:32-05:00 Fix #22742 runtimeRepLevity_maybe was panicing unnecessarily; and the error printing code made use of the case when it should return Nothing rather than panicing. For some bizarre reason perf/compiler/T21839r shows a 10% bump in runtime peak-megagbytes-used, on a single architecture (alpine). See !9753 for commentary, but I'm going to accept it. Metric Increase: T21839r - - - - - 2c6deb18 by Bryan Richter at 2023-01-23T14:12:22+02:00 codeowners: Add Ben, Matt, and Bryan to CI - - - - - eee3bf05 by Matthew Craven at 2023-01-23T21:46:41-05:00 Do not collect compile-time metrics for T21839r ...the testsuite doesn't handle this properly since it also collects run-time metrics. Compile-time metrics for this test are already tracked via T21839c. Metric Decrease: T21839r - - - - - 1d1dd3fb by Matthew Pickering at 2023-01-24T05:37:52-05:00 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 - - - - - 7bfb30f9 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 - - - - - 69500dd4 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 - - - - - 336b2b1c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 - - - - - 6469fea7 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 - - - - - 06cc0a95 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 - - - - - 4fe9eaff by Matthew Pickering at 2023-01-24T05:37:52-05:00 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 - - - - - ada29f5c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p - - - - - be701cc6 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. - - - - - 34d2d463 by Krzysztof Gogolewski at 2023-01-24T05:38:32-05:00 Fix Lint check for duplicate external names Lint was checking for duplicate external names by calling removeDups, which needs a comparison function that is passed to Data.List.sortBy. But the comparison was not a valid ordering - it returned LT if one of the names was not external. For example, the previous implementation won't find a duplicate in [M.x, y, M.x]. Instead, we filter out non-external names before looking for duplicates. - - - - - 1c050ed2 by Matthew Pickering at 2023-01-24T05:39:08-05:00 Add test for T22671 This was fixed by b13c6ea5 Closes #22671 - - - - - 05e6a2d9 by Tom Ellis at 2023-01-24T12:10:52-05:00 Clarify where `f` is defined - - - - - d151546e by Cheng Shao at 2023-01-24T12:11:29-05:00 CmmToC: fix CmmRegOff for 64-bit register on a 32-bit target We used to print the offset value to a platform word sized integer. This is incorrect when the offset is negative (e.g. output of cmm constant folding) and the register is 64-bit but on a 32-bit target, and may lead to incorrect runtime result (e.g. #22607). The fix is simple: just treat it as a proper MO_Add, with the correct width info inferred from the register itself. Metric Increase: T12707 T13379 T4801 T5321FD T5321Fun - - - - - e5383a29 by Wander Hillen at 2023-01-24T20:02:26-05:00 Allow waiting for timerfd to be interrupted during rts shutdown - - - - - 1957eda1 by Ryan Scott at 2023-01-24T20:03:01-05:00 Restore Compose's Read/Show behavior to match Read1/Show1 instances Fixes #22816. - - - - - 30972827 by Matthew Pickering at 2023-01-25T03:54:14-05:00 docs: Update INSTALL.md Removes references to make. Fixes #22480 - - - - - bc038c3b by Cheng Shao at 2023-01-25T03:54:50-05:00 compiler: fix handling of MO_F_Neg in wasm NCG In the wasm NCG, we used to compile MO_F_Neg to 0.0-x. It was an oversight, there actually exists f32.neg/f64.neg opcodes in the wasm spec and those should be used instead! The old behavior almost works, expect when GHC compiles the -0.0 literal, which will incorrectly become 0.0. - - - - - e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. - - - - - 48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. - - - - - 288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. - - - - - 2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00 configure: support "windows" as an OS - - - - - 13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00 Fix in-scope set in specImports Nothing deep here; I had failed to bring some floated dictionary binders into scope. Exposed by -fspecialise-aggressively Fixes #22715. - - - - - b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00 ci: Disable HLint job due to excessive runtime The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91 Now the CI job will build the stage0 compiler before it generates the necessary RTS headers. We either need to: * Fix the linting rules so they take much less time * Revert the commit * Remove the linting of base from the hlint job * Remove the hlint job This is highest priority as it is affecting all CI pipelines. For now I am just disabling the job because there are many more pressing matters at hand. Ticket #22830 - - - - - 1bd32a35 by Sylvain Henry at 2023-01-26T12:34:21-05:00 Factorize hptModulesBelow Create and use moduleGraphModulesBelow in GHC.Unit.Module.Graph that doesn't need anything from the driver to be used. - - - - - 1262d3f8 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 - - - - - e27eb80c by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 - - - - - 3d004d5a by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 - - - - - f2a0fea0 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 - - - - - 5640cb1d by Sylvain Henry at 2023-01-26T12:35:36-05:00 Hadrian: fix doc generation Was missing dependencies on files generated by templates (e.g. ghc.cabal) - - - - - 3e827c3f by Richard Eisenberg at 2023-01-26T20:06:53-05:00 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. Close #22519. - - - - - b3ef5c89 by doyougnu at 2023-01-26T20:07:48-05:00 tryFillBuffer: strictify more speculative bangs - - - - - d0d7ba0f by Vladislav Zavialov at 2023-01-26T20:08:25-05:00 base: NoImplicitPrelude in Data.Void and Data.Kind This change removes an unnecessary dependency on Prelude from two modules in the base package. - - - - - fa1db923 by Matthew Pickering at 2023-01-26T20:09:00-05:00 ci: Add ubuntu18_04 nightly and release jobs This adds release jobs for ubuntu18_04 which uses glibc 2.27 which is older than the 2.28 which is used by Rocky8 bindists. Ticket #22268 - - - - - 807310a1 by Matthew Pickering at 2023-01-26T20:09:00-05:00 rel-eng: Add missing rocky8 bindist We intend to release rocky8 bindist so the fetching script needs to know about them. - - - - - c7116b10 by Ben Gamari at 2023-01-26T20:09:35-05:00 base: Make changelog proposal references more consistent Addresses #22773. - - - - - 6932cfc7 by Sylvain Henry at 2023-01-26T20:10:27-05:00 Fix spurious change from !9568 - - - - - e480fbc2 by Ben Gamari at 2023-01-27T05:01:24-05:00 rts: Use C11-compliant static assertion syntax Previously we used `static_assert` which is only available in C23. By contrast, C11 only provides `_Static_assert`. Fixes #22777 - - - - - 2648c09c by Andrei Borzenkov at 2023-01-27T05:02:07-05:00 Replace errors from badOrigBinding with new one (#22839) Problem: in 02279a9c the type-level [] syntax was changed from a built-in name to an alias for the GHC.Types.List constructor. badOrigBinding assumes that if a name is not built-in then it must have come from TH quotation, but this is not necessarily the case with []. The outdated assumption in badOrigBinding leads to incorrect error messages. This code: data [] Fails with "Cannot redefine a Name retrieved by a Template Haskell quote: []" Unfortunately, there is not enough information in RdrName to directly determine if the name was constructed via TH or by the parser, so this patch changes the error message instead. It unifies TcRnIllegalBindingOfBuiltIn and TcRnNameByTemplateHaskellQuote into a new error TcRnBindingOfExistingName and changes its wording to avoid guessing the origin of the name. - - - - - 545bf8cf by Matthew Pickering at 2023-01-27T14:58:53+00:00 Revert "base: NoImplicitPrelude in Data.Void and Data.Kind" Fixes CI errors of the form. ``` ===> Command failed with error code: 1 ghc: panic! (the 'impossible' happened) GHC version 9.7.20230127: lookupGlobal Failed to load interface for ‘GHC.Num.BigNat’ There are files missing in the ‘ghc-bignum’ package, try running 'ghc-pkg check'. Use -v (or `:set -v` in ghci) to see a list of the files searched for. Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Tc/Utils/Env.hs:154:32 in ghc:GHC.Tc.Utils.Env CallStack (from HasCallStack): panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` This reverts commit d0d7ba0fb053ebe7f919a5932066fbc776301ccd. The module now lacks a dependency on GHC.Num.BigNat which it implicitly depends on. It is causing all CI jobs to fail so we revert without haste whilst the patch can be fixed. Fixes #22848 - - - - - 638277ba by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Detect family instance orphans correctly We were treating a type-family instance as a non-orphan if there was a type constructor on its /right-hand side/ that was local. Boo! Utterly wrong. With this patch, we correctly check the /left-hand side/ instead! Fixes #22717 - - - - - 46a53bb2 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Report family instance orphans correctly This fixes the fact that we were not reporting orphan family instances at all. The fix here is easy, but touches a bit of code. I refactored the code to be much more similar to the way that class instances are done: - Add a fi_orphan field to FamInst, like the is_orphan field in ClsInst - Make newFamInst initialise this field, just like newClsInst - And make newFamInst report a warning for an orphan, just like newClsInst - I moved newFamInst from GHC.Tc.Instance.Family to GHC.Tc.Utils.Instantiate, just like newClsInst. - I added mkLocalFamInst to FamInstEnv, just like mkLocalClsInst in InstEnv - TcRnOrphanInstance and SuggestFixOrphanInstance are now parametrised over class instances vs type/data family instances. Fixes #19773 - - - - - faa300fb by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in STG This patch removes some orphan instances in the STG namespace by introducing the GHC.Stg.Lift.Types module, which allows various type family instances to be moved to GHC.Stg.Syntax, avoiding orphan instances. - - - - - 0f25a13b by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in the parser This moves Anno instances for PatBuilder from GHC.Parser.PostProcess to GHC.Parser.Types to avoid orphans. - - - - - 15750d33 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Accept an orphan declaration (sadly) This accepts the orphan type family instance type instance DsForeignHook = ... in GHC.HsToCore.Types. See Note [The Decoupling Abstract Data Hack] in GHC.Driver.Hooks - - - - - c9967d13 by Zubin Duggal at 2023-01-27T23:55:31-05:00 bindist configure: Fail if find not found (#22691) - - - - - ad8cfed4 by John Ericson at 2023-01-27T23:56:06-05:00 Put hadrian bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. - - - - - d0ddc01b by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Introduce threaded2_sanity way Incredibly, we previously did not have a single way which would test the threaded RTS with multiple capabilities and the sanity-checker enabled. - - - - - 38ad8351 by Ben Gamari at 2023-01-27T23:56:42-05:00 rts: Relax Messages assertion `doneWithMsgThrowTo` was previously too strict in asserting that the `Message` is locked. Specifically, it failed to consider that the `Message` may not be locked if we are deleting all threads during RTS shutdown. - - - - - a9fe81af by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Fix race in UnliftedTVar2 Previously UnliftedTVar2 would fail when run with multiple capabilities (and possibly even with one capability) as it would assume that `killThread#` would immediately kill the "increment" thread. Also, refactor the the executable to now succeed with no output and fails with an exit code. - - - - - 8519af60 by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Make listThreads more robust Previously it was sensitive to the labels of threads which it did not create (e.g. the IO manager event loop threads). Fix this. - - - - - 55a81995 by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix non-atomic mutation of enabled_capabilities - - - - - b5c75f1d by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix C++ compilation issues Make the RTS compilable with a C++ compiler by inserting necessary casts. - - - - - c261b62f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix typo "tracingAddCapabilities" was mis-named - - - - - 77fdbd3f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Drop long-dead fallback definitions for INFINITY & NAN These are no longer necessary since we now compile as C99. - - - - - 56c1bd98 by Ben Gamari at 2023-01-28T02:57:59-05:00 Revert "CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043)" This reverts commit 99aca26b652603bc62953157a48e419f737d352d. - - - - - b3a3534b by nineonine at 2023-01-28T02:57:59-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043. - - - - - 082b7d43 by Oleg Grenrus at 2023-01-28T02:58:38-05:00 Add Foldable1 Solo instance - - - - - 50b1e2e8 by Andrei Borzenkov at 2023-01-28T02:59:18-05:00 Convert diagnostics in GHC.Rename.Bind to proper TcRnMessage (#20115) I removed all occurrences of TcRnUnknownMessage in GHC.Rename.Bind module. Instead, these TcRnMessage messages were introduced: TcRnMultipleFixityDecls TcRnIllegalPatternSynonymDecl TcRnIllegalClassBiding TcRnOrphanCompletePragma TcRnEmptyCase TcRnNonStdGuards TcRnDuplicateSigDecl TcRnMisplacedSigDecl TcRnUnexpectedDefaultSig TcRnBindInBootFile TcRnDuplicateMinimalSig - - - - - 3330b819 by Matthew Pickering at 2023-01-28T02:59:54-05:00 hadrian: Fix library-dirs, dynamic-library-dirs and static-library-dirs in inplace .conf files Previously we were just throwing away the contents of the library-dirs fields but really we have to do the same thing as for include-dirs, relativise the paths into the current working directory and maintain any extra libraries the user has specified. Now the relevant section of the rts.conf file looks like: ``` library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib library-dirs-static: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib dynamic-library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib ``` Fixes #22209 - - - - - c9ad8852 by Bodigrim at 2023-01-28T03:00:33-05:00 Document differences between Data.{Monoid,Semigroup}.{First,Last} - - - - - 7e11c6dc by Cheng Shao at 2023-01-28T03:01:09-05:00 compiler: fix subword literal narrowing logic in the wasm NCG This patch fixes the W8/W16 literal narrowing logic in the wasm NCG, which used to lower it to something like i32.const -1, without properly zeroing-out the unused higher bits. Fixes #22608. - - - - - 6ea2aa02 by Cheng Shao at 2023-01-28T03:01:46-05:00 compiler: fix lowering of CmmBlock in the wasm NCG The CmmBlock datacon was not handled in lower_CmmLit, since I thought it would have been eliminated after proc-point splitting. Turns out it still occurs in very rare occasions, and this patch is needed to fix T9329 for wasm. - - - - - 2b62739d by Bodigrim at 2023-01-28T17:16:11-05:00 Assorted changes to avoid Data.List.{head,tail} - - - - - 78c07219 by Cheng Shao at 2023-01-28T17:16:48-05:00 compiler: properly handle ForeignHints in the wasm NCG Properly handle ForeignHints of ccall arguments/return value, insert sign extends and truncations when handling signed subwords. Fixes #22852. - - - - - 8bed166b by Ben Gamari at 2023-01-30T05:06:26-05:00 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. - - - - - da468391 by Cheng Shao at 2023-01-30T05:07:03-05:00 compiler: fix data section alignment in the wasm NCG Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size. - - - - - 08ba8720 by Andreas Klebinger at 2023-01-30T21:18:45-05:00 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- - - - - - 20598ef6 by Ryan Scott at 2023-01-30T21:19:20-05:00 Handle `type data` properly in tyThingParent_maybe Unlike most other data constructors, data constructors declared with `type data` are represented in `TyThing`s as `ATyCon` rather than `ADataCon`. The `ATyCon` case in `tyThingParent_maybe` previously did not consider the possibility of the underlying `TyCon` being a promoted data constructor, which led to the oddities observed in #22817. This patch adds a dedicated special case in `tyThingParent_maybe`'s `ATyCon` case for `type data` data constructors to fix these oddities. Fixes #22817. - - - - - 2f145052 by Ryan Scott at 2023-01-30T21:19:56-05:00 Fix two bugs in TypeData TH reification This patch fixes two issues in the way that `type data` declarations were reified with Template Haskell: * `type data` data constructors are now properly reified using `DataConI`. This is accomplished with a special case in `reifyTyCon`. Fixes #22818. * `type data` type constructors are now reified in `reifyTyCon` using `TypeDataD` instead of `DataD`. Fixes #22819. - - - - - d0f34f25 by Simon Peyton Jones at 2023-01-30T21:20:35-05:00 Take account of loop breakers in specLookupRule The key change is that in GHC.Core.Opt.Specialise.specLookupRule we were using realIdUnfolding, which ignores the loop-breaker flag. When given a loop breaker, rule matching therefore looped infinitely -- #22802. In fixing this I refactored a bit. * Define GHC.Core.InScopeEnv as a data type, and use it. (Previously it was a pair: hard to grep for.) * Put several functions returning an IdUnfoldingFun into GHC.Types.Id, namely idUnfolding alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun and use them. (The are all loop-breaker aware.) - - - - - de963cb6 by Matthew Pickering at 2023-01-30T21:21:11-05:00 ci: Remove FreeBSD job from release pipelines We no longer attempt to build or distribute this release - - - - - f26d27ec by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Add check to make sure that release jobs are downloaded by fetch-gitlab This check makes sure that if a job is a prefixed by "release-" then the script downloads it and understands how to map the job name to the platform. - - - - - 7619c0b4 by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Fix the name of the ubuntu-* jobs These were not uploaded for alpha1 Fixes #22844 - - - - - 68eb8877 by Matthew Pickering at 2023-01-30T21:21:11-05:00 gen_ci: Only consider release jobs for job metadata In particular we do not have a release job for FreeBSD so the generation of the platform mapping was failing. - - - - - b69461a0 by Jason Shipman at 2023-01-30T21:21:50-05:00 User's guide: Clarify overlapping instance candidate elimination This commit updates the user's guide section on overlapping instance candidate elimination to use "or" verbiage instead of "either/or" in regards to the current pair of candidates' being overlappable or overlapping. "Either IX is overlappable, or IY is overlapping" can cause confusion as it suggests "Either IX is overlappable, or IY is overlapping, but not both". This was initially discussed on this Discourse topic: https://discourse.haskell.org/t/clarification-on-overlapping-instance-candidate-elimination/5677 - - - - - 7cbdaad0 by Matthew Pickering at 2023-01-31T07:53:53-05:00 Fixes for cabal-reinstall CI job * Allow filepath to be reinstalled * Bump some version bounds to allow newer versions of libraries * Rework testing logic to avoid "install --lib" and package env files Fixes #22344 - - - - - fd8f32bf by Cheng Shao at 2023-01-31T07:54:29-05:00 rts: prevent potential divide-by-zero when tickInterval=0 This patch fixes a few places in RtsFlags.c that may result in divide-by-zero error when tickInterval=0, which is the default on wasm. Fixes #22603. - - - - - 085a6db6 by Joachim Breitner at 2023-01-31T07:55:05-05:00 Update note at beginning of GHC.Builtin.NAmes some things have been renamed since it was written, it seems. - - - - - 7716cbe6 by Cheng Shao at 2023-01-31T07:55:41-05:00 testsuite: use tgamma for cg007 gamma is a glibc-only deprecated function, use tgamma instead. It's required for fixing cg007 when testing the wasm unregisterised codegen. - - - - - 19c1fbcd by doyougnu at 2023-01-31T13:08:03-05:00 InfoTableProv: ShortText --> ShortByteString - - - - - 765fab98 by doyougnu at 2023-01-31T13:08:03-05:00 FastString: add fastStringToShorText - - - - - a83c810d by Simon Peyton Jones at 2023-01-31T13:08:38-05:00 Improve exprOkForSpeculation for classops This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord - - - - - f83374f8 by Krzysztof Gogolewski at 2023-01-31T13:09:14-05:00 Support "unusable UNPACK pragma" warning with -O0 Fixes #11270 - - - - - a2d814dc by Ben Gamari at 2023-01-31T13:09:50-05:00 configure: Always create the VERSION file Teach the `configure` script to create the `VERSION` file. This will serve as the stable interface to allow the user to determine the version number of a working tree. Fixes #22322. - - - - - 5618fc21 by sheaf at 2023-01-31T15:51:06-05:00 Cmm: track the type of global registers This patch tracks the type of Cmm global registers. This is needed in order to lint uses of polymorphic registers, such as SIMD vector registers that can be used both for floating-point and integer values. This changes allows us to refactor VanillaReg to not store VGcPtr, as that information is instead stored in the type of the usage of the register. Fixes #22297 - - - - - 78b99430 by sheaf at 2023-01-31T15:51:06-05:00 Revert "Cmm Lint: relax SIMD register assignment check" This reverts commit 3be48877, which weakened a Cmm Lint check involving SIMD vectors. Now that we keep track of the type a global register is used at, we can restore the original stronger check. - - - - - be417a47 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. - - - - - 30989d13 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. - - - - - 7566fd9d by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. - - - - - 2cb500a5 by Ben Gamari at 2023-01-31T15:51:45-05:00 testsuite: Add regression test for #22798 - - - - - 03d693b2 by Ben Gamari at 2023-01-31T15:52:32-05:00 Revert "Hadrian: fix doc generation" This is too large of a hammer. This reverts commit 5640cb1d84d3cce4ce0a9e90d29b2b20d2b38c2f. - - - - - f838815c by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Sphinx docs require templated cabal files The package-version discovery logic in `doc/users_guide/package_versions.py` uses packages' cabal files to determine package versions. Teach Sphinx about these dependencies in cases where the cabal files are generated by templates. - - - - - 2e48c19a by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Refactor templating logic This refactors Hadrian's autoconf-style templating logic to be explicit about which interpolation variables should be substituted in which files. This clears the way to fix #22714 without incurring rule cycles. - - - - - 93f0e3c4 by Ben Gamari at 2023-01-31T15:52:33-05:00 hadrian: Substitute LIBRARY_*_VERSION variables This teaches Hadrian to substitute the `LIBRARY_*_VERSION` variables in `libraries/prologue.txt`, fixing #22714. Fixes #22714. - - - - - 22089f69 by Ben Gamari at 2023-01-31T20:46:27-05:00 Bump transformers submodule to 0.6.0.6 Fixes #22862. - - - - - f0eefa3c by Cheng Shao at 2023-01-31T20:47:03-05:00 compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCG Currently, the wasm NCG has an implicit assumption: all CmmSwitch scrutinees are 32-bit integers. This is not always true; #22864 is one counter-example with a 64-bit scrutinee. This patch fixes the logic by explicitly converting the scrutinee to a word that can be used as a br_table operand. Fixes #22871. Also includes a regression test. - - - - - 9f95db54 by Simon Peyton Jones at 2023-02-01T08:55:08+00:00 Improve treatment of type applications in patterns This patch fixes a subtle bug in the typechecking of type applications in patterns, e.g. f (MkT @Int @a x y) = ... See Note [Type applications in patterns] in GHC.Tc.Gen.Pat. This fixes #19847, #22383, #19577, #21501 - - - - - 955a99ea by Simon Peyton Jones at 2023-02-01T12:31:23-05:00 Treat existentials correctly in dubiousDataConInstArgTys Consider (#22849) data T a where MkT :: forall k (t::k->*) (ix::k). t ix -> T @k a Then dubiousDataConInstArgTys MkT [Type, Foo] should return [Foo (ix::Type)] NOT [Foo (ix::k)] A bit of an obscure case, but it's an outright bug, and the fix is easy. - - - - - 0cc16aaf by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump supported LLVM range from 10 through 15 to 11 through 16 LLVM 15 turns on the new pass manager by default, which we have yet to migrate to so for new we pass the `-enable-new-pm-0` flag in our llvm-passes flag. LLVM 11 was the first version to support the `-enable-new-pm` flag so we bump the lowest supported version to 11. Our CI jobs are using LLVM 12 so they should continue to work despite this bump to the lower bound. Fixes #21936 - - - - - f94f1450 by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump DOCKER_REV to use alpine image without LLVM installed alpine_3_12 only supports LLVM 10, which is now outside the supported version range. - - - - - 083e26ed by Matthew Pickering at 2023-02-01T17:43:21-05:00 Remove tracing OPTIONS_GHC These were accidentally left over from !9542 - - - - - 354aa47d by Teo Camarasu at 2023-02-01T17:44:00-05:00 doc: fix gcdetails_block_fragmentation_bytes since annotation - - - - - 61ce5bf6 by Jaro Reinders at 2023-02-02T00:15:30-05:00 compiler: Implement higher order patterns in the rule matcher This implements proposal 555 and closes ticket #22465. See the proposal and ticket for motivation. The core changes of this patch are in the GHC.Core.Rules.match function and they are explained in the Note [Matching higher order patterns]. - - - - - 394b91ce by doyougnu at 2023-02-02T00:16:10-05:00 CI: JavaScript backend runs testsuite This MR runs the testsuite for the JS backend. Note that this is a temporary solution until !9515 is merged. Key point: The CI runs hadrian on the built cross compiler _but not_ on the bindist. Other Highlights: - stm submodule gets a bump to mark tests as broken - several tests are marked as broken or are fixed by adding more - conditions to their test runner instance. List of working commit messages: CI: test cross target _and_ emulator CI: JS: Try run testsuite with hadrian JS.CI: cleanup and simplify hadrian invocation use single bracket, print info JS CI: remove call to test_compiler from hadrian don't build haddock JS: mark more tests as broken Tracked in https://gitlab.haskell.org/ghc/ghc/-/issues/22576 JS testsuite: don't skip sum_mod test Its expected to fail, yet we skipped it which automatically makes it succeed leading to an unexpected success, JS testsuite: don't mark T12035j as skip leads to an unexpected pass JS testsuite: remove broken on T14075 leads to unexpected pass JS testsuite: mark more tests as broken JS testsuite: mark T11760 in base as broken JS testsuite: mark ManyUnbSums broken submodules: bump process and hpc for JS tests Both submodules has needed tests skipped or marked broken for th JS backend. This commit now adds these changes to GHC. See: HPC: https://gitlab.haskell.org/hpc/hpc/-/merge_requests/21 Process: https://github.com/haskell/process/pull/268 remove js_broken on now passing tests separate wasm and js backend ci test: T11760: add threaded, non-moving only_ways test: T10296a add req_c T13894: skip for JS backend tests: jspace, T22333: mark as js_broken(22573) test: T22513i mark as req_th stm submodule: mark stm055, T16707 broken for JS tests: js_broken(22374) on unpack_sums_6, T12010 dont run diff on JS CI, cleanup fixup: More CI cleanup fix: align text to master fix: align exceptions submodule to master CI: Bump DOCKER_REV Bump to ci-images commit that has a deb11 build with node. Required for !9552 testsuite: mark T22669 as js_skip See #22669 This test tests that .o-boot files aren't created when run in using the interpreter backend. Thus this is not relevant for the JS backend. testsuite: mark T22671 as broken on JS See #22835 base.testsuite: mark Chan002 fragile for JS see #22836 revert: submodule process bump bump stm submodule New hash includes skips for the JS backend. testsuite: mark RnPatternSynonymFail broken on JS Requires TH: - see !9779 - and #22261 compiler: GHC.hs ifdef import Utils.Panic.Plain - - - - - 1ffe770c by Cheng Shao at 2023-02-02T09:40:38+00:00 docs: 9.6 release notes for wasm backend - - - - - 0ada4547 by Matthew Pickering at 2023-02-02T11:39:44-05:00 Disable unfolding sharing for interface files with core definitions Ticket #22807 pointed out that the RHS sharing was not compatible with -fignore-interface-pragmas because the flag would remove unfoldings from identifiers before the `extra-decls` field was populated. For the 9.6 timescale the only solution is to disable this sharing, which will make interface files bigger but this is acceptable for the first release of `-fwrite-if-simplified-core`. For 9.8 it would be good to fix this by implementing #20056 due to the large number of other bugs that would fix. I also improved the error message in tc_iface_binding to avoid the "no match in record selector" error but it should never happen now as the entire sharing logic is disabled. Also added the currently broken test for #22807 which could be fixed by !6080 Fixes #22807 - - - - - 7e2d3eb5 by lrzlin at 2023-02-03T05:23:27-05:00 Enable tables next to code for LoongArch64 - - - - - 2931712a by Wander Hillen at 2023-02-03T05:24:06-05:00 Move pthread and timerfd ticker implementations to separate files - - - - - 41c4baf8 by Ben Gamari at 2023-02-03T05:24:44-05:00 base: Fix Note references in GHC.IO.Handle.Types - - - - - 31358198 by Bodigrim at 2023-02-03T05:25:22-05:00 Bump submodule containers to 0.6.7 Metric Decrease: ManyConstructors T10421 T12425 T12707 T13035 T13379 T15164 T1969 T783 T9198 T9961 WWRec - - - - - 8feb9301 by Ben Gamari at 2023-02-03T05:25:59-05:00 gitlab-ci: Eliminate redundant ghc --info output Previously ci.sh would emit the output of `ghc --info` every time it ran when using the nix toolchain. This produced a significant amount of noise. See #22861. - - - - - de1d1512 by Ryan Scott at 2023-02-03T14:07:30-05:00 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` - - - - - 48e39195 by Tamar Christina at 2023-02-03T14:07:30-05:00 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. - - - - - b2bb3e62 by Ben Gamari at 2023-02-03T14:07:30-05:00 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - bf3f88a1 by Andreas Klebinger at 2023-02-03T14:08:07-05:00 Fix CallerCC potentially shadowing other cost centres. Add a CallerCC cost centre flavour for cost centres added by the CallerCC pass. This avoids potential accidental shadowing between CCs added by user annotations and ones added by CallerCC. - - - - - faea4bcd by j at 2023-02-03T14:08:47-05:00 Disable several ignore-warning flags in genapply. - - - - - 25537dfd by Ben Gamari at 2023-02-04T04:12:57-05:00 Revert "Use fix-sized bit-fiddling primops for fixed size boxed types" This reverts commit 4512ad2d6a8e65ea43c86c816411cb13b822f674. This was never applied to master/9.6 originally. (cherry picked from commit a44bdc2720015c03d57f470b759ece7fab29a57a) - - - - - 7612dc71 by Krzysztof Gogolewski at 2023-02-04T04:13:34-05:00 Minor refactor * Introduce refactorDupsOn f = refactorDups (comparing f) * Make mkBigTupleCase and coreCaseTuple monadic. Every call to those functions was preceded by calling newUniqueSupply. * Use mkUserLocalOrCoVar, which is equivalent to combining mkLocalIdOrCoVar with mkInternalName. - - - - - 5a54ac0b by Bodigrim at 2023-02-04T18:48:32-05:00 Fix colors in emacs terminal - - - - - 3c0f0c6d by Bodigrim at 2023-02-04T18:49:11-05:00 base changelog: move entries which were not backported to ghc-9.6 to base-4.19 section - - - - - b18fbf52 by Josh Meredith at 2023-02-06T07:47:57+00:00 Update JavaScript fileStat to match Emscripten layout - - - - - 6636b670 by Sylvain Henry at 2023-02-06T09:43:21-05:00 JS: replace "js" architecture with "javascript" Despite Cabal supporting any architecture name, `cabal --check` only supports a few built-in ones. Sadly `cabal --check` is used by Hackage hence using any non built-in name in a package (e.g. `arch(js)`) is rejected and the package is prevented from being uploaded on Hackage. Luckily built-in support for the `javascript` architecture was added for GHCJS a while ago. In order to allow newer `base` to be uploaded on Hackage we make the switch from `js` to `javascript` architecture. Fixes #22740. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 77a8234c by Luite Stegeman at 2023-02-06T09:43:59-05:00 Fix marking async exceptions in the JS backend Async exceptions are posted as a pair of the exception and the thread object. This fixes the marking pass to correctly follow the two elements of the pair. Potentially fixes #22836 - - - - - 3e09cf82 by Jan Hrček at 2023-02-06T09:44:38-05:00 Remove extraneous word in Roles user guide - - - - - b17fb3d9 by sheaf at 2023-02-07T10:51:33-05:00 Don't allow . in overloaded labels This patch removes . from the list of allowed characters in a non-quoted overloaded label, as it was realised this steals syntax, e.g. (#.). Users who want this functionality will have to add quotes around the label, e.g. `#"17.28"`. Fixes #22821 - - - - - 5dce04ee by romes at 2023-02-07T10:52:10-05:00 Update kinds in comments in GHC.Core.TyCon Use `Type` instead of star kind (*) Fix comment with incorrect kind * to have kind `Constraint` - - - - - 92916194 by Ben Gamari at 2023-02-07T10:52:48-05:00 Revert "Use fix-sized equality primops for fixed size boxed types" This reverts commit 024020c38126f3ce326ff56906d53525bc71690c. This was never applied to master/9.6 originally. See #20405 for why using these primops is a bad idea. (cherry picked from commit b1d109ad542e4c37ae5af6ace71baf2cb509d865) - - - - - c1670c6b by Sylvain Henry at 2023-02-07T21:25:18-05:00 JS: avoid head/tail and unpackFS - - - - - a9912de7 by Krzysztof Gogolewski at 2023-02-07T21:25:53-05:00 testsuite: Fix Python warnings (#22856) - - - - - 9ee761bf by sheaf at 2023-02-08T14:40:40-05:00 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 - - - - - 7eac2468 by Matthew Pickering at 2023-02-08T14:41:17-05:00 Revert "Don't keep exit join points so much" This reverts commit caced75765472a1a94453f2e5a439dba0d04a265. It seems the patch "Don't keep exit join points so much" is causing wide-spread regressions in the bytestring library benchmarks. If I revert it then the 9.6 numbers are better on average than 9.4. See https://gitlab.haskell.org/ghc/ghc/-/issues/22893#note_479525 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T12150 T13386 T13719 T21839c T3294 parsing001 ------------------------- - - - - - 633f2799 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: remove config.use_threads This patch simplifies the testsuite driver by removing the use_threads config field. It's just a degenerate case of threads=1. - - - - - ca6673e3 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: use concurrent.futures.ThreadPoolExecutor in the driver The testsuite driver used to create one thread per test case, and explicitly use semaphore and locks for rate limiting and synchronization. This is a bad practice in any language, and occasionally may result in livelock conditions (e.g. #22889). This patch uses concurrent.futures.ThreadPoolExecutor for scheduling test case runs, which is simpler and more robust. - - - - - f22cce70 by Alan Zimmerman at 2023-02-08T18:42:51-05:00 EPA: Comment between module and where should be in header comments Do not apply the heuristic to associate a comment with a prior declaration for the first declaration in the file. Closes #22919 - - - - - d69ecac2 by Josh Meredith at 2023-02-09T03:24:05-05:00 JS generated refs: update testsuite conditions - - - - - 2ea1a6bc by sheaf at 2023-02-09T03:24:44-05:00 Bump transformers to 0.6.1.0 This allows us to avoid orphans for Foldable1 instances, fixing #22898. Updates transformers submodule. - - - - - d9d0c28d by konsumlamm at 2023-02-09T14:07:48-05:00 Update `Data.List.singleton` doc comment - - - - - fe9cd6ef by Ben Gamari at 2023-02-09T14:08:23-05:00 gitlab-template: Emphasize `user facing` label My sense is that the current mention of the ~"user facing" label is overlooked by many MR authors. Let's move this point up in the list to make it more likely that it is seen. Also rephrase some of the points. - - - - - e45eb828 by Simon Peyton Jones at 2023-02-10T06:51:28-05:00 Refactor the simplifier a bit to fix #22761 The core change in this commit, which fixes #22761, is that * In a Core rule, ru_rhs is always occ-analysed. This means adding a couple of calls to occurAnalyseExpr when building a Rule, in * GHC.Core.Rules.mkRule * GHC.Core.Opt.Simplify.Iteration.simplRules But diagosing the bug made me stare carefully at the code of the Simplifier, and I ended up doing some only-loosely-related refactoring. * I think that RULES could be lost because not every code path did addBndrRules * The code around lambdas was very convoluted It's mainly moving deck chairs around, but I like it more now. - - - - - 11e0cacb by Rebecca Turner at 2023-02-10T06:52:09-05:00 Detect the `mold` linker Enables support for the `mold` linker by rui314. - - - - - 59556235 by parsonsmatt at 2023-02-10T09:53:11-05:00 Add Lift instance for Fixed - - - - - c44e5f30 by Sylvain Henry at 2023-02-10T09:53:51-05:00 Testsuite: decrease length001 timeout for JS (#22921) - - - - - 133516af by Zubin Duggal at 2023-02-10T09:54:27-05:00 compiler: Use NamedFieldPuns for `ModIface_` and `ModIfaceBackend` `NFData` instances This is a minor refactor that makes it easy to add and remove fields from `ModIface_` and `ModIfaceBackend`. Also change the formatting to make it clear exactly which fields are fully forced with `rnf` - - - - - 1e9eac1c by Matthew Pickering at 2023-02-13T11:36:41+01:00 Refresh profiling docs I went through the whole of the profiling docs and tried to amend them to reflect current best practices and tooling. In particular I removed some old references to tools such as hp2any and replaced them with references to eventlog2html. - - - - - da208b9a by Matthew Pickering at 2023-02-13T11:36:41+01:00 docs: Add section about profiling and foreign calls Previously there was no documentation for how foreign calls interacted with the profiler. This can be quite confusing for users so getting it into the user guide is the first step to a potentially better solution. See the ticket for more insightful discussion. Fixes #21764 - - - - - 081640f1 by Bodigrim at 2023-02-13T12:51:52-05:00 Document that -fproc-alignment was introduced only in GHC 8.6 - - - - - 16adc349 by Sven Tennie at 2023-02-14T11:26:31-05:00 Add clangd flag to include generated header files This enables clangd to correctly check C files that import Rts.h. (The added include directory contains ghcautoconf.h et. al.) - - - - - c399ccd9 by amesgen at 2023-02-14T11:27:14-05:00 Mention new `Foreign.Marshal.Pool` implementation in User's Guide - - - - - b9282cf7 by Ben Gamari at 2023-02-14T11:27:50-05:00 upload_ghc_libs: More control over which packages to operate on Here we add a `--skip` flag to `upload_ghc_libs`, making it easier to limit which packages to upload. This is often necessary when one package is not uploadable (e.g. see #22740). - - - - - aa3a262d by PHO at 2023-02-14T11:28:29-05:00 Assume platforms support rpaths if they use either ELF or Mach-O Not only Linux, Darwin, and FreeBSD support rpaths. Determine the usability of rpaths based on the object format, not on OS. - - - - - 47716024 by PHO at 2023-02-14T11:29:09-05:00 RTS linker: Improve compatibility with NetBSD 1. Hint address to NetBSD mmap(2) has a different semantics from that of Linux. When a hint address is provided, mmap(2) searches for a free region at or below the hint but *never* above it. This means we can't reliably search for free regions incrementally on the userland, especially when ASLR is enabled. Let the kernel do it for us if we don't care where the mapped address is going to be. 2. NetBSD not only hates to map pages as rwx, but also disallows to switch pages from rw- to r-x unless the intention is declared when pages are initially requested. This means we need a new MemoryAccess mode for pages that are going to be changed to r-x. - - - - - 11de324a by Li-yao Xia at 2023-02-14T11:29:49-05:00 base: Move changelog entry to its place - - - - - 75930424 by Ben Gamari at 2023-02-14T11:30:27-05:00 nativeGen/AArch64: Emit Atomic{Read,Write} inline Previously the AtomicRead and AtomicWrite operations were emitted as out-of-line calls. However, these tend to be very important for performance, especially the RELAXED case (which only exists for ThreadSanitizer checking). Fixes #22115. - - - - - d6411d6c by Andreas Klebinger at 2023-02-14T11:31:04-05:00 Fix some correctness issues around tag inference when targeting the bytecode generator. * Let binders are now always assumed untagged for bytecode. * Imported referenced are now always assumed to be untagged for bytecode. Fixes #22840 - - - - - 9fb4ca89 by sheaf at 2023-02-14T11:31:49-05:00 Introduce warning for loopy superclass solve Commit aed1974e completely re-engineered the treatment of loopy superclass dictionaries in instance declarations. Unfortunately, it has the potential to break (albeit in a rather minor way) user code. To alleviate migration concerns, this commit re-introduces the old behaviour. Any reliance on this old behaviour triggers a warning, controlled by `-Wloopy-superclass-solve`. The warning text explains that GHC might produce bottoming evidence, and provides a migration strategy. This allows us to provide a graceful migration period, alerting users when they are relying on this unsound behaviour. Fixes #22912 #22891 #20666 #22894 #22905 - - - - - 1928c7f3 by Cheng Shao at 2023-02-14T11:32:26-05:00 rts: make it possible to change mblock size on 32-bit targets The MBLOCK_SHIFT macro must be the single source of truth for defining the mblock size, and changing it should only affect performance, not correctness. This patch makes it truly possible to reconfigure mblock size, at least on 32-bit targets, by fixing places which implicitly relied on the previous MBLOCK_SHIFT constant. Fixes #22901. - - - - - 78aa3b39 by Simon Hengel at 2023-02-14T11:33:06-05:00 Update outdated references to notes - - - - - e8baecd2 by meooow25 at 2023-02-14T11:33:49-05:00 Documentation: Improve Foldable1 documentation * Explain foldrMap1, foldlMap1, foldlMap1', and foldrMap1' in greater detail, the text is mostly adapted from documentation of Foldable. * Describe foldr1, foldl1, foldl1' and foldr1' in terms of the above functions instead of redoing the full explanation. * Small updates to documentation of fold1, foldMap1 and toNonEmpty, again adapting from Foldable. * Update the foldMap1 example to lists instead of Sum since this is recommended for lazy right-associative folds. Fixes #22847 - - - - - 85a1a575 by romes at 2023-02-14T11:34:25-05:00 fix: Mark ghci Prelude import as implicit Fixes #22829 In GHCi, we were creating an import declaration for Prelude but we were not setting it as an implicit declaration. Therefore, ghci's import of Prelude triggered -Wmissing-import-lists. Adds regression test T22829 to testsuite - - - - - 3b019a7a by Cheng Shao at 2023-02-14T11:35:03-05:00 compiler: fix generateCgIPEStub for no-tables-next-to-code builds generateCgIPEStub already correctly implements the CmmTick finding logic for when tables-next-to-code is on/off, but it used the wrong predicate to decide when to switch between the two. Previously it switches based on whether the codegen is unregisterised, but there do exist registerised builds that disable tables-next-to-code! This patch corrects that problem. Fixes #22896. - - - - - 08c0822c by doyougnu at 2023-02-15T00:16:39-05:00 docs: release notes, user guide: add js backend Follow up from #21078 - - - - - 79d8fd65 by Bryan Richter at 2023-02-15T00:17:15-05:00 Allow failure in nightly-x86_64-linux-deb10-no_tntc-validate See #22343 - - - - - 9ca51f9e by Cheng Shao at 2023-02-15T00:17:53-05:00 rts: add the rts_clearMemory function This patch adds the rts_clearMemory function that does its best to zero out unused RTS memory for a wasm backend use case. See the comment above rts_clearMemory() prototype declaration for more detailed explanation. Closes #22920. - - - - - 26df73fb by Oleg Grenrus at 2023-02-15T22:20:57-05:00 Add -single-threaded flag to force single threaded rts This is the small part of implementing https://github.com/ghc-proposals/ghc-proposals/pull/240 - - - - - 631c6c72 by Cheng Shao at 2023-02-16T06:43:09-05:00 docs: add a section for the wasm backend Fixes #22658 - - - - - 1878e0bd by Bryan Richter at 2023-02-16T06:43:47-05:00 tests: Mark T12903 fragile everywhere See #21184 - - - - - b9420eac by Bryan Richter at 2023-02-16T06:43:47-05:00 Mark all T5435 variants as fragile See #22970. - - - - - df3d94bd by Sylvain Henry at 2023-02-16T06:44:33-05:00 Testsuite: mark T13167 as fragile for JS (#22921) - - - - - 324e925b by Sylvain Henry at 2023-02-16T06:45:15-05:00 JS: disable debugging info for heap objects - - - - - 518af814 by Josh Meredith at 2023-02-16T10:16:32-05:00 Factor JS Rts generation for h$c{_,0,1,2} into h$c{n} and improve name caching - - - - - 34cd308e by Ben Gamari at 2023-02-16T10:17:08-05:00 base: Note move of GHC.Stack.CCS.whereFrom to GHC.InfoProv in changelog Fixes #22883. - - - - - 12965aba by Simon Peyton Jones at 2023-02-16T10:17:46-05:00 Narrow the dont-decompose-newtype test Following #22924 this patch narrows the test that stops us decomposing newtypes. The key change is the use of noGivenNewtypeReprEqs in GHC.Tc.Solver.Canonical.canTyConApp. We went to and fro on the solution, as you can see in #22924. The result is carefully documented in Note [Decomoposing newtype equalities] On the way I had revert most of commit 3e827c3f74ef76d90d79ab6c4e71aa954a1a6b90 Author: Richard Eisenberg <rae at cs.brynmawr.edu> Date: Mon Dec 5 10:14:02 2022 -0500 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. It turns out that (a) 3e827c3f makes GHC behave worse on some recursive newtypes (see one of the tests on this commit) (b) the finer-grained test (namely noGivenNewtypeReprEqs) renders 3e827c3f unnecessary - - - - - 5b038888 by Bodigrim at 2023-02-16T10:18:24-05:00 Documentation: add an example of SPEC usage - - - - - 681e0e8c by sheaf at 2023-02-16T14:09:56-05:00 No default finalizer exception handler Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680 - - - - - b3ac17ad by Matthew Pickering at 2023-02-16T14:10:31-05:00 unicode: Don't inline bitmap in generalCategory generalCategory contains a huge literal string but is marked INLINE, this will duplicate the string into any use site of generalCategory. In particular generalCategory is used in functions like isSpace and the literal gets inlined into this function which makes it massive. https://github.com/haskell/core-libraries-committee/issues/130 Fixes #22949 ------------------------- Metric Decrease: T4029 T18304 ------------------------- - - - - - 8988eeef by sheaf at 2023-02-16T20:32:27-05:00 Expand synonyms in RoughMap We were failing to expand type synonyms in the function GHC.Core.RoughMap.typeToRoughMatchLookupTc, even though the RoughMap infrastructure crucially relies on type synonym expansion to work. This patch adds the missing type-synonym expansion. Fixes #22985 - - - - - 3dd50e2f by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Add test artifact Add the released testsuite tarball to the generated ghcup metadata. - - - - - c6a967d9 by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Use Ubuntu and Rocky bindists Prefer to use the Ubuntu 20.04 and 18.04 binary distributions on Ubuntu and Linux Mint. Prefer to use the Rocky 8 binary distribution on unknown distributions. - - - - - be0b7209 by Matthew Pickering at 2023-02-17T09:37:16+00:00 Add INLINABLE pragmas to `generic*` functions in Data.OldList These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129 - - - - - a203ad85 by Sylvain Henry at 2023-02-17T15:59:16-05:00 Merge libiserv with ghci `libiserv` serves no purpose. As it depends on `ghci` and doesn't have more dependencies than the `ghci` package, its code could live in the `ghci` package too. This commit also moves most of the code from the `iserv` program into the `ghci` package as well so that it can be reused. This is especially useful for the implementation of TH for the JS backend (#22261, !9779). - - - - - 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Bodigrim at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Bodigrim at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - f5987aa5 by Ben Gamari at 2023-04-14T06:34:57-04:00 Use SArr in demand analysis Add `SArr`, a wrapper around `Exts.SmallArray#`, and use it in the `Prod` constructor of `SubDemand`. This is #18927. - - - - - ef5b932b by Sebastian Graf at 2023-04-14T06:50:02-04:00 More changes, committing so that we see a segfault - - - - - 3aaad21b by Ben Gamari at 2023-04-14T07:57:46-04:00 hihi - - - - - 5eee0645 by Ben Gamari at 2023-04-14T08:16:08-04:00 SArr: Add zipWithEqual - - - - - 91f9f1de by Ben Gamari at 2023-04-14T08:16:18-04:00 SArr: Fix fmap Slice - - - - - 7b808f4c by Ben Gamari at 2023-04-14T08:53:31-04:00 SArr: Rework zipWith - - - - - 42048b53 by Ben Gamari at 2023-04-14T08:53:41-04:00 SArr: Fix toList - - - - - 13 changed files: - − .appveyor.sh - .editorconfig - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - + .gitlab/gen-ci.cabal - + .gitlab/gen_ci.hs - + .gitlab/generate_job_metadata - + .gitlab/generate_jobs - + .gitlab/hello.hs - + .gitlab/hie.yaml The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/07a4f966a58d35fae29431448af7accc2b969a10...42048b5317b2a31ffc14905f9206b3068282e491 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/07a4f966a58d35fae29431448af7accc2b969a10...42048b5317b2a31ffc14905f9206b3068282e491 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 13:28:35 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 14 Apr 2023 09:28:35 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <643955037ba9a_10a80d34f635405803be@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: ed7dc92a by Rodrigo Mesquita at 2023-04-14T14:17:49+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 14 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,97 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One thing worth considering is giving *workers* with only zero-width-args the +`LFCon` LambdaFormInfo, e.g. giving `LFCon` to the worker of `TCon` and +`TCon3`. Currently, they are being marked `LFReEntrant`. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,10 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | The RepArity of an Id. +-- +-- This arity counts all arguments relevant in Core, which includes arguments +-- with no runtime representation idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed7dc92a3ac07ef6097734fcb14043a0709e3366 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed7dc92a3ac07ef6097734fcb14043a0709e3366 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 13:29:43 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 14 Apr 2023 09:29:43 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64395547b80b5_10a80d34f2b5645821fe@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 36794d13 by Rodrigo Mesquita at 2023-04-14T14:29:34+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 14 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,97 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One thing worth considering is giving *workers* with only zero-width-args the +`LFCon` LambdaFormInfo, e.g. giving `LFCon` to the worker of `TCon` and +`TCon3`. Currently, they are being marked `LFReEntrant`. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,10 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | The RepArity of an Id. +-- +-- This arity counts all arguments relevant in Core, which includes arguments +-- with no runtime representation idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36794d13ea55cbdac6f107bb1691551525ada313 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36794d13ea55cbdac6f107bb1691551525ada313 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 13:30:40 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 14 Apr 2023 09:30:40 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64395580e385d_10a80d350e49f05823a@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 36794d13 by Rodrigo Mesquita at 2023-04-14T14:29:34+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 14 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,97 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One thing worth considering is giving *workers* with only zero-width-args the +`LFCon` LambdaFormInfo, e.g. giving `LFCon` to the worker of `TCon` and +`TCon3`. Currently, they are being marked `LFReEntrant`. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,10 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | The RepArity of an Id. +-- +-- This arity counts all arguments relevant in Core, which includes arguments +-- with no runtime representation idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36794d13ea55cbdac6f107bb1691551525ada313 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/36794d13ea55cbdac6f107bb1691551525ada313 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 14:02:55 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 14 Apr 2023 10:02:55 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T22549a Message-ID: <64395d0f83c8b_10a80d35881cf85908c7@gitlab.mail> Simon Peyton Jones pushed new branch wip/T22549a at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T22549a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 14:45:15 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 14 Apr 2023 10:45:15 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <643966fb1d67e_10a80d366c4a9061727d@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 834ea06c by Rodrigo Mesquita at 2023-04-14T15:44:40+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 15 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,97 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One thing worth considering is giving *workers* with only zero-width-args the +`LFCon` LambdaFormInfo, e.g. giving `LFCon` to the worker of `TCon` and +`TCon3`. Currently, they are being marked `LFReEntrant`. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,10 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | The RepArity of an Id. +-- +-- This arity counts all arguments relevant in Core, which includes arguments +-- with no runtime representation idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/834ea06c7d673774cbf961d7f7a3a59c5582b527 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/834ea06c7d673774cbf961d7f7a3a59c5582b527 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 14:46:11 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 14 Apr 2023 10:46:11 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64396733b349e_10a80d364688506174da@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 834ea06c by Rodrigo Mesquita at 2023-04-14T15:44:40+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 15 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -981,7 +981,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1395,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the Core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are existentially quantified dictionaries and coercion arguments, lifted and +-- unlifted (despite the unlifted coercion arguments being zero-width). dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1407,12 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether there are any argument types for this 'DataCon's Core +-- representation type. See Note [DataCon arities]. +-- +-- In particular, Core's representation type considers coercion arguments to be +-- arguments -- both lifted and unlifted coercions, despite the latter having +-- zero-width runtime representation. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,97 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T a where + TCon :: {-# UNPACK #-} !(a :~: True) -> T a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One thing worth considering is giving *workers* with only zero-width-args the +`LFCon` LambdaFormInfo, e.g. giving `LFCon` to the worker of `TCon` and +`TCon3`. Currently, they are being marked `LFReEntrant`. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,10 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | The RepArity of an Id. +-- +-- This arity counts all arguments relevant in Core, which includes arguments +-- with no runtime representation idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/834ea06c7d673774cbf961d7f7a3a59c5582b527 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/834ea06c7d673774cbf961d7f7a3a59c5582b527 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 15:18:45 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 11:18:45 -0400 Subject: [Git][ghc/ghc][wip/t22549] 4 commits: rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <64396ed5495cf_10a80d3700bd6062102@gitlab.mail> Matthew Pickering pushed to branch wip/t22549 at Glasgow Haskell Compiler / GHC Commits: a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 7068ed9b by Simon Peyton Jones at 2023-04-14T16:18:11+01:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - 11 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Tc/TyCl.hs - docs/index.html → docs/index.html.in - hadrian/src/Rules/Documentation.hs - hadrian/src/Rules/Generate.hs - rts/StablePtr.c - testsuite/tests/dependent/should_fail/T15743c.hs - testsuite/tests/dependent/should_fail/T15743c.stderr - + testsuite/tests/roles/should_fail/T23252.hs - + testsuite/tests/roles/should_fail/T23252.stderr - testsuite/tests/roles/should_fail/all.T Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -248,7 +248,13 @@ tcTyClDecls tyclds kisig_env role_annots = do { -- Step 1: kind-check this group and returns the final -- (possibly-polymorphic) kind of each TyCon and Class -- See Note [Kind checking for type and class decls] - (tc_tycons, kindless) <- kcTyClGroup kisig_env tyclds + (tc_tycons, kindless) <- checkNoErrs $ + kcTyClGroup kisig_env tyclds + -- checkNoErrs: If the TyCons are ill-kinded, stop now. Else we + -- can get follow-on errors. Example: #23252, where the TyCon + -- had an ill-scoped kind forall (d::k) k (a::k). blah + -- and that ill-scoped kind made role inference fall over. + ; traceTc "tcTyAndCl generalized kinds" (vcat (map ppr_tc_tycon tc_tycons)) -- Step 2: type-check all groups together, returning ===================================== docs/index.html → docs/index.html.in ===================================== @@ -39,7 +39,7 @@

  • - GHC API + GHC API

    Documentation for the GHC API. ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -193,7 +193,7 @@ buildHtmlDocumentation = do | SphinxHTML `Set.member` doctargets ] need $ map ((root -/-) . pathIndex) targets - copyFileUntracked "docs/index.html" file + copyFile "docs/index.html" file -- | Compile a Sphinx ReStructured Text package to HTML. buildSphinxHtml :: FilePath -> Rules () ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -305,10 +305,10 @@ rtsCabalFlags = mconcat flag = interpolateCabalFlag packageVersions :: Interpolations -packageVersions = foldMap f [ base, ghcPrim, ghc, cabal, templateHaskell, ghcCompact, array ] +packageVersions = foldMap f [ base, ghcPrim, compiler, ghc, cabal, templateHaskell, ghcCompact, array ] where f :: Package -> Interpolations - f pkg = interpolateVar var $ show . version <$> readPackageData pkg + f pkg = interpolateVar var $ version <$> readPackageData pkg where var = "LIBRARY_" <> pkgName pkg <> "_VERSION" templateRule :: FilePath -> Interpolations -> Rules () @@ -335,6 +335,7 @@ templateRules = do templateRule "utils/ghc-pkg/ghc-pkg.cabal" $ projectVersion templateRule "libraries/template-haskell/template-haskell.cabal" $ projectVersion templateRule "libraries/prologue.txt" $ packageVersions + templateRule "docs/index.html" $ packageVersions -- Generators ===================================== rts/StablePtr.c ===================================== @@ -98,8 +98,13 @@ */ +// the global stable pointer entry table spEntry *stable_ptr_table = NULL; + +// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after static spEntry *stable_ptr_free = NULL; + +// current stable pointer table size static unsigned int SPT_size = 0; #define INIT_SPT_SIZE 64 @@ -117,6 +122,7 @@ static unsigned int SPT_size = 0; #error unknown SIZEOF_VOID_P #endif +// old stable pointer tables static spEntry *old_SPTs[MAX_N_OLD_SPTS]; static uint32_t n_old_SPTs = 0; @@ -149,8 +155,9 @@ stablePtrUnlock(void) * -------------------------------------------------------------------------- */ STATIC_INLINE void -initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free) +initSpEntryFreeList(spEntry *table, uint32_t n) { + spEntry* free = NULL; spEntry *p; for (p = table + n - 1; p >= table; p--) { p->addr = (P_)free; @@ -166,7 +173,7 @@ initStablePtrTable(void) SPT_size = INIT_SPT_SIZE; stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry), "initStablePtrTable"); - initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL); + initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE); #if defined(THREADED_RTS) initMutex(&stable_ptr_mutex); @@ -181,6 +188,8 @@ initStablePtrTable(void) static void enlargeStablePtrTable(void) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + uint32_t old_SPT_size = SPT_size; spEntry *new_stable_ptr_table; @@ -206,7 +215,8 @@ enlargeStablePtrTable(void) */ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table); - initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); + // add the new entries to the free list + initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size); } /* Note [Enlarging the stable pointer table] @@ -245,6 +255,7 @@ exitStablePtrTable(void) { if (stable_ptr_table) stgFree(stable_ptr_table); + stable_ptr_table = NULL; SPT_size = 0; @@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp) void freeStablePtrUnsafe(StgStablePtr sp) { + ASSERT_LOCK_HELD(&stable_ptr_mutex); + // see Note [NULL StgStablePtr] if (sp == NULL) { return; } + StgWord spw = (StgWord)sp - 1; + ASSERT(spw < SPT_size); + freeSpEntry(&stable_ptr_table[spw]); } @@ -278,25 +294,35 @@ void freeStablePtr(StgStablePtr sp) { stablePtrLock(); + freeStablePtrUnsafe(sp); + stablePtrUnlock(); } /* ----------------------------------------------------------------------------- - * Looking up + * Allocating stable pointers * -------------------------------------------------------------------------- */ StgStablePtr getStablePtr(StgPtr p) { - StgWord sp; - stablePtrLock(); - if (!stable_ptr_free) enlargeStablePtrTable(); - sp = stable_ptr_free - stable_ptr_table; - stable_ptr_free = (spEntry*)(stable_ptr_free->addr); - RELAXED_STORE(&stable_ptr_table[sp].addr, p); + + if (!stable_ptr_free) + enlargeStablePtrTable(); + + // find the index of free stable ptr + StgWord sp = stable_ptr_free - stable_ptr_table; + + // unlink the table entry we grabbed from the free list + stable_ptr_free = (spEntry*)(stable_ptr_free->addr); + + // release store to pair with acquire load in deRefStablePtr + RELEASE_STORE(&stable_ptr_table[sp].addr, p); + stablePtrUnlock(); + // see Note [NULL StgStablePtr] sp = sp + 1; return (StgStablePtr)(sp); ===================================== testsuite/tests/dependent/should_fail/T15743c.hs ===================================== @@ -8,4 +8,4 @@ import Data.Proxy data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type data T k (c :: k) (a :: Proxy c) b (x :: SimilarKind a b) -data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) + ===================================== testsuite/tests/dependent/should_fail/T15743c.stderr ===================================== @@ -13,18 +13,3 @@ T15743c.hs:10:1: error: (b :: Proxy d) (x :: SimilarKind a b) • In the data type declaration for ‘T’ - -T15743c.hs:11:1: error: - • The kind of ‘T2’ is ill-scoped - Inferred kind: T2 :: forall (d :: k). - forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> - SimilarKind a b -> * - NB: Specified variables (namely: (d :: k)) always come first - Perhaps try this order instead: - k - (d :: k) - (c :: k) - (a :: Proxy c) - (b :: Proxy d) - (x :: SimilarKind a b) - • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/T23252.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE PolyKinds, DataKinds, ExplicitForAll #-} +{-# LANGUAGE RoleAnnotations #-} + +module T15743 where + +import Data.Kind +import Data.Proxy + +data SimilarKind :: forall (c :: k) (d :: k). Proxy c -> Proxy d -> Type + +data T2 k (c :: k) (a :: Proxy c) (b :: Proxy d) (x :: SimilarKind a b) +type role T2 nominal nominal nominal nominal -- Too few! ===================================== testsuite/tests/roles/should_fail/T23252.stderr ===================================== @@ -0,0 +1,14 @@ +T23252.hs:11:1: error: + • The kind of ‘T2’ is ill-scoped + Inferred kind: T2 :: forall (d :: k). + forall k (c :: k) (a :: Proxy c) (b :: Proxy d) -> + SimilarKind a b -> * + NB: Specified variables (namely: (d :: k)) always come first + Perhaps try this order instead: + k + (d :: k) + (c :: k) + (a :: Proxy c) + (b :: Proxy d) + (x :: SimilarKind a b) + • In the data type declaration for ‘T2’ ===================================== testsuite/tests/roles/should_fail/all.T ===================================== @@ -8,3 +8,4 @@ test('Roles12', [], makefile_test, []) test('T8773', normal, compile_fail, ['']) test('T9204', [], makefile_test, []) test('RolesIArray', normal, compile_fail, ['']) +test('T23252', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1efcc6e47c24796f5779573247dd23ff4bcb3178...7068ed9ba68ca8723f781412bd38eb76c9d7d9d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1efcc6e47c24796f5779573247dd23ff4bcb3178...7068ed9ba68ca8723f781412bd38eb76c9d7d9d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 15:29:06 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 14 Apr 2023 11:29:06 -0400 Subject: [Git][ghc/ghc][wip/t23148] 108 commits: Refactor the constraint solver pipeline Message-ID: <64397142a6071_10a80d373ded5c6252fb@gitlab.mail> Matthew Pickering pushed to branch wip/t23148 at Glasgow Haskell Compiler / GHC Commits: e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 72142ebe by Matthew Pickering at 2023-04-14T16:28:50+01:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/SimpleOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56f075c1736fb32fc011e9fa736a049f61b4dfc9...72142ebe62121669def1ec3c28dc081ab733b32e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/56f075c1736fb32fc011e9fa736a049f61b4dfc9...72142ebe62121669def1ec3c28dc081ab733b32e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 15:44:11 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Fri, 14 Apr 2023 11:44:11 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] cut-though: ppr existing instructions Message-ID: <643974cb9218c_10a80d3773e768630597@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: 7ff2d814 by Sven Tennie at 2023-04-14T15:43:11+00:00 cut-though: ppr existing instructions - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RISCV64.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64.hs ===================================== @@ -29,8 +29,8 @@ ncgRISCV64 no_empty_asm config = NcgImpl , canShortcut = RISCV64.canShortcut , shortcutStatics = RISCV64.shortcutStatics , shortcutJump = RISCV64.shortcutJump - , pprNatCmmDeclH = RISCV64.pprNatCmmDecl - , pprNatCmmDeclS = RISCV64.pprNatCmmDeclS + , pprNatCmmDeclH = RISCV64.pprNatCmmDecl config + , pprNatCmmDeclS = RISCV64.pprNatCmmDecl config , maxSpillSlots = RISCV64.maxSpillSlots config , allocatableRegs = RISCV64.allocatableRegs platform , ncgAllocMoreStack = RISCV64.allocMoreStack ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -7,7 +7,6 @@ import GHC.Cmm.Dataflow.Label import GHC.CmmToAsm.Config import GHC.CmmToAsm.Instr hiding (patchRegsOfInstr, takeDeltaInstr, regUsageOfInstr, isMetaInstr, jumpDestsOfInstr) import GHC.CmmToAsm.Types -import GHC.Data.FastString import GHC.Platform import GHC.Platform.Reg import GHC.Types.Unique.Supply @@ -39,9 +38,6 @@ data Instr | -- jump pseudo-instruction J BlockId -instance Outputable Instr where - ppr instr = text "TODO: Outputable Instr ppr" - allocMoreStack :: Int -> NatCmmDecl statics GHC.CmmToAsm.RISCV64.Instr.Instr -> @@ -250,11 +246,3 @@ mkStackDeallocInstr :: Int -> [instr] mkStackDeallocInstr _ _ = error "TODO: mkStackDeallocInstr" - --- | Pretty-print an instruction -pprInstr :: Platform -> instr -> SDoc -pprInstr _ _ = error "TODO: pprInstr" - --- Create a comment instruction -mkComment :: FastString -> [instr] -mkComment _ = error "mkComment" ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -1,5 +1,5 @@ {-# OPTIONS_GHC -Wno-unused-matches #-} - +{-# LANGUAGE MultiParamTypeClasses #-} module GHC.CmmToAsm.RISCV64.Ppr where import GHC.Cmm hiding (topInfoTable) @@ -16,9 +16,13 @@ import GHC.Types.Basic import GHC.Utils.Outputable import Prelude hiding ((<>)) import GHC.CmmToAsm.Utils +import GHC.Platform.Reg +import GHC.Utils.Panic +import GHC.Types.Unique pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc -pprNatCmmDecl _ cmmData@(CmmData _ _) = error $ "TODO: pprNatCmmDecl : " ++ showPprUnsafe cmmData +pprNatCmmDecl config (CmmData _ _) = error "TODO: pprNatCmmDecl " + pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = let platform = ncgPlatform config in pprProcAlignment config @@ -34,7 +38,7 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = $$ -- TODO: Is this call to pprSizeDecl needed? (Doc states this .size is only for source compatibility.) pprSizeDecl platform lbl - Just cmmStaticsRaw@(CmmStaticsRaw info_lbl _) -> error $ "TODO: pprNatCmmDecl : " ++ show cmmStaticsRaw + Just (CmmStaticsRaw info_lbl _) -> error "TODO: pprNatCmmDecl : " pprProcAlignment :: IsDoc doc => NCGConfig -> doc pprProcAlignment config = maybe empty (pprAlign platform . mkAlignment) (ncgProcAlignment config) @@ -110,7 +114,7 @@ pprBasicBlock config info_env (BasicBlock blockid instrs) = platform = ncgPlatform config maybe_infotable c = case mapLookup blockid info_env of Nothing -> c - Just cmm@(CmmStaticsRaw info_lbl info) -> error $ "pprBasicBlock " ++ showPprUnsafe cmm + Just (CmmStaticsRaw info_lbl info) -> error "pprBasicBlock" pprInstr :: IsDoc doc => Platform -> Instr -> doc pprInstr platform instr = case instr of @@ -123,8 +127,22 @@ pprInstr platform instr = case instr of -- see Note [dualLine and dualDoc] in GHC.Utils.Outputable NEWBLOCK _ -> error "pprInstr: NEWBLOCK" LDATA _ _ -> error "pprInstr: LDATA" - J t -> error "pprInstr: LDATA" - LI reg i -> error "pprInstr: LDATA" + J label -> line $ pprJ label + LI reg immediate -> line $ pprLI reg immediate + where + pprLI :: IsLine doc => Reg -> Integer -> doc + pprLI reg immediate = text "\tli" <+> pprReg reg <> char ',' <+> (text.show) immediate + + pprReg :: IsLine doc => Reg -> doc + pprReg (RegReal (RealRegSingle r)) = text "x" <> (text.show) r + pprReg (RegVirtual r) = panic $ "RISCV64.Ppr.ppr: Unexpected virtual register " ++ show r + + pprJ :: IsLine doc => BlockId -> doc + pprJ label = text "\tj" <+> pprBlockId label + + pprBlockId:: IsLine doc => BlockId -> doc + pprBlockId blockId = pprAsmLabel platform (mkLocalBlockLabel (getUnique blockId)) + -- aarch64 GNU as uses // for comments. asmComment :: SDoc -> SDoc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ff2d814aadf95ed7d56bd83fdc7da52c8a9e55d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ff2d814aadf95ed7d56bd83fdc7da52c8a9e55d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 14 18:01:24 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Fri, 14 Apr 2023 14:01:24 -0400 Subject: [Git][ghc/ghc][wip/T22194-flags] 7 commits: rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <643994f4241d_10a80d39d08d1864116c@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T22194-flags at Glasgow Haskell Compiler / GHC Commits: a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 18 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/TyCl.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8579b80b7610be6f11cae1586857c0b59bd3e43...23e2a8a0d7e626bcc327baab029e8d3ee2c5729b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f8579b80b7610be6f11cae1586857c0b59bd3e43...23e2a8a0d7e626bcc327baab029e8d3ee2c5729b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 00:26:34 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 14 Apr 2023 20:26:34 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: rts: improve memory ordering and add some comments in the StablePtr implementation Message-ID: <6439ef3aa3f96_10a80d402758e06836d0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - d6fd7f46 by Matthew Pickering at 2023-04-14T20:26:30-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 18 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/TyCl.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a1b9b016a86a5a31b9c01e29060973c348fab07...d6fd7f46f92337c4a48062d0890d617ca06b3c32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a1b9b016a86a5a31b9c01e29060973c348fab07...d6fd7f46f92337c4a48062d0890d617ca06b3c32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 04:57:03 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 15 Apr 2023 00:57:03 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Major refactor in the handling of equality constraints Message-ID: <643a2e9f87081_10a80d4489b1e47063fc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 17 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d48fbfea5f7b760ec3d13dd2947257986c095b75...23e2a8a0d7e626bcc327baab029e8d3ee2c5729b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d48fbfea5f7b760ec3d13dd2947257986c095b75...23e2a8a0d7e626bcc327baab029e8d3ee2c5729b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 04:57:31 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 15 Apr 2023 00:57:31 -0400 Subject: [Git][ghc/ghc][master] docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Message-ID: <643a2ebb57179_10a80d44895bf471207d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 1 changed file: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs Changes: ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -335,39 +335,9 @@ type role TExp nominal -- See Note [Role of TExp] newtype TExp (a :: TYPE (r :: RuntimeRep)) = TExp { unType :: Exp -- ^ Underlying untyped Template Haskell expression } --- ^ Represents an expression which has type @a at . Built on top of 'Exp', typed --- expressions allow for type-safe splicing via: --- --- - typed quotes, written as @[|| ... ||]@ where @...@ is an expression; if --- that expression has type @a@, then the quotation has type --- @'Q' ('TExp' a)@ --- --- - typed splices inside of typed quotes, written as @$$(...)@ where @...@ --- is an arbitrary expression of type @'Q' ('TExp' a)@ --- --- Traditional expression quotes and splices let us construct ill-typed --- expressions: --- --- >>> fmap ppr $ runQ [| True == $( [| "foo" |] ) |] --- GHC.Types.True GHC.Classes.== "foo" --- >>> GHC.Types.True GHC.Classes.== "foo" --- error: --- • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ --- • In the second argument of ‘(==)’, namely ‘"foo"’ --- In the expression: True == "foo" --- In an equation for ‘it’: it = True == "foo" +-- ^ Typed wrapper around an 'Exp'. -- --- With typed expressions, the type error occurs when /constructing/ the --- Template Haskell expression: --- --- >>> fmap ppr $ runQ [|| True == $$( [|| "foo" ||] ) ||] --- error: --- • Couldn't match type ‘[Char]’ with ‘Bool’ --- Expected type: Q (TExp Bool) --- Actual type: Q (TExp [Char]) --- • In the Template Haskell quotation [|| "foo" ||] --- In the expression: [|| "foo" ||] --- In the Template Haskell splice $$([|| "foo" ||]) +-- This is the typed representation of terms produced by typed quotes. -- -- Representation-polymorphic since /template-haskell-2.16.0.0/. @@ -395,13 +365,13 @@ unsafeTExpCoerce m = do { e <- m TExp's argument must have a nominal role, not phantom as would be inferred (#8459). Consider - e :: TExp Age - e = MkAge 3 + e :: Code Q Age + e = [|| MkAge 3 ||] foo = $(coerce e) + 4::Int The splice will evaluate to (MkAge 3) and you can't add that to -4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +4::Int. So you can't coerce a (Code Q Age) to a (Code Q Int). -} -- Code constructor @@ -409,6 +379,40 @@ type role Code representational nominal -- See Note [Role of TExp] newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code { examineCode :: m (TExp a) -- ^ Underlying monadic value } +-- ^ Represents an expression which has type @a@, built in monadic context @m at . Built on top of 'TExp', typed +-- expressions allow for type-safe splicing via: +-- +-- - typed quotes, written as @[|| ... ||]@ where @...@ is an expression; if +-- that expression has type @a@, then the quotation has type +-- @Quote m => Code m a@ +-- +-- - typed splices inside of typed quotes, written as @$$(...)@ where @...@ +-- is an arbitrary expression of type @Quote m => Code m a@ +-- +-- Traditional expression quotes and splices let us construct ill-typed +-- expressions: +-- +-- >>> fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |]) +-- GHC.Types.True GHC.Classes.== "foo" +-- >>> GHC.Types.True GHC.Classes.== "foo" +-- error: +-- • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ +-- • In the second argument of ‘(==)’, namely ‘"foo"’ +-- In the expression: True == "foo" +-- In an equation for ‘it’: it = True == "foo" +-- +-- With typed expressions, the type error occurs when /constructing/ the +-- Template Haskell expression: +-- +-- >>> fmap ppr $ runQ (unTypeCode [|| True == $$( [|| "foo" ||] ) ||]) +-- error: +-- • Couldn't match type ‘[Char]’ with ‘Bool’ +-- Expected type: Code Q Bool +-- Actual type: Code Q [Char] +-- • In the Template Haskell quotation [|| "foo" ||] +-- In the expression: [|| "foo" ||] +-- In the Template Haskell splice $$([|| "foo" ||]) + -- | Unsafely convert an untyped code representation into a typed code -- representation. @@ -958,7 +962,7 @@ sequenceQ = sequence -- Haskell quotation is bound outside the Oxford brackets (@[| ... |]@ or -- @[|| ... ||]@) but not at the top level. As an example: -- --- > add1 :: Int -> Q (TExp Int) +-- > add1 :: Int -> Code Q Int -- > add1 x = [|| x + 1 ||] -- -- Template Haskell has no way of knowing what value @x@ will take on at @@ -966,7 +970,7 @@ sequenceQ = sequence -- -- A 'Lift' instance must satisfy @$(lift x) ≡ x@ and @$$(liftTyped x) ≡ x@ -- for all @x@, where @$(...)@ and @$$(...)@ are Template Haskell splices. --- It is additionally expected that @'lift' x ≡ 'unTypeQ' ('liftTyped' x)@. +-- It is additionally expected that @'lift' x ≡ 'unTypeCode' ('liftTyped' x)@. -- -- 'Lift' instances can be derived automatically by use of the @-XDeriveLift@ -- GHC language extension: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c04024617f1ee4c76844cfe0a886bab87c23bd0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c04024617f1ee4c76844cfe0a886bab87c23bd0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 08:22:25 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Sat, 15 Apr 2023 04:22:25 -0400 Subject: [Git][ghc/ghc] Pushed new tag angerman/preserve-history/aarch64-ncg Message-ID: <643a5ec1e6018_10a80d4804b15c717262@gitlab.mail> Moritz Angermann pushed new tag angerman/preserve-history/aarch64-ncg at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/angerman/preserve-history/aarch64-ncg You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 08:26:48 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Sat, 15 Apr 2023 04:26:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/angerman/aarch64-ncg-origin Message-ID: <643a5fc87c003_10a80d48308a707176c9@gitlab.mail> Moritz Angermann pushed new branch wip/angerman/aarch64-ncg-origin at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/angerman/aarch64-ncg-origin You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 08:34:43 2023 From: gitlab at gitlab.haskell.org (Moritz Angermann (@angerman)) Date: Sat, 15 Apr 2023 04:34:43 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/angerman/x Message-ID: <643a61a3d6d0f_10a80d484cfae8719826@gitlab.mail> Moritz Angermann pushed new branch wip/angerman/x at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/angerman/x You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 11:42:34 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Sat, 15 Apr 2023 07:42:34 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] 4 commits: darwin ci: Explicitly pass desired build triple to configure Message-ID: <643a8daa167c2_10a80d4b461c847331b5@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: 8b5d4df0 by Matthew Pickering at 2023-04-15T17:12:01+05:30 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 8608657c by Matthew Pickering at 2023-04-15T17:12:01+05:30 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 (cherry picked from commit 64286132cc0db4e227637887f98f5a3ecf7d326a) (cherry picked from commit 48a9e688331fbc2ac91392c654bb7457c5f8a876) - - - - - 768caef1 by Matthew Pickering at 2023-04-15T17:12:02+05:30 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 (cherry picked from commit 926cd4ee097106cf9c6d1ae1fc32375e7fc45ff2) - - - - - 403470cf by Zubin Duggal at 2023-04-15T17:12:02+05:30 Prepare release 9.4.5 Metric Decrease: T13035 T15164 T1969 T9961 WWRec T12707 T13379 Metric Increase: T17123 - - - - - 8 changed files: - .gitlab/darwin/toolchain.nix - configure.ac - distrib/configure.ac.in - + docs/users_guide/9.4.5-notes.rst - docs/users_guide/release-notes.rst - libraries/base/changelog.md - m4/ghc_llvm_target.m4 - testsuite/tests/rts/all.T Changes: ===================================== .gitlab/darwin/toolchain.nix ===================================== @@ -98,6 +98,6 @@ pkgs.writeTextFile { export CABAL="$CABAL_INSTALL" sdk_path="$(xcrun --sdk macosx --show-sdk-path)" - export CONFIGURE_ARGS="$CONFIGURE_ARGS --with-ffi-libraries=$sdk_path/usr/lib --with-ffi-includes=$sdk_path/usr/include/ffi" + export CONFIGURE_ARGS="$CONFIGURE_ARGS --with-ffi-libraries=$sdk_path/usr/lib --with-ffi-includes=$sdk_path/usr/include/ffi --build=${targetTriple}" ''; } ===================================== configure.ac ===================================== @@ -13,7 +13,7 @@ dnl # see what flags are available. (Better yet, read the documentation!) # -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) +AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.5], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable # to be useful (cf #19058). However, the version must have three components # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are @@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.4], [glasgow-has AC_CONFIG_MACRO_DIRS([m4]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=NO} +: ${RELEASE=YES} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the @@ -694,6 +694,8 @@ GHC_LLVM_TARGET_SET_VAR # we intend to pass trough --targets to llvm as is. LLVMTarget_CPP=` echo "$LlvmTarget"` AC_SUBST(LLVMTarget_CPP) +# The target is substituted into the distrib/configure.ac file +AC_SUBST(LlvmTarget) dnl ** See whether cc supports --target= and set dnl CONF_CC_OPTS_STAGE[012] accordingly. ===================================== distrib/configure.ac.in ===================================== @@ -18,6 +18,8 @@ dnl-------------------------------------------------------------------- dnl Various things from the source distribution configure bootstrap_target=@TargetPlatform@ +bootstrap_llvm_target=@LlvmTarget@ + TargetHasRTSLinker=@TargetHasRTSLinker@ AC_SUBST(TargetHasRTSLinker) @@ -165,6 +167,11 @@ FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAG # Stage 3 won't be supported by cross-compilation FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE2],[CONF_GCC_LINKER_OPTS_STAGE2],[CONF_LD_LINKER_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2]) +FP_LD_NO_FIXUP_CHAINS([target], [LDFLAGS]) +FP_LD_NO_FIXUP_CHAINS([build], [CONF_GCC_LINKER_OPTS_STAGE0]) +FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE1]) +FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE2]) + AC_SUBST(CONF_CC_OPTS_STAGE0) AC_SUBST(CONF_CC_OPTS_STAGE1) AC_SUBST(CONF_CC_OPTS_STAGE2) ===================================== docs/users_guide/9.4.5-notes.rst ===================================== @@ -0,0 +1,220 @@ +.. _release-9-4-5: + +Version 9.4.5 +============== + +The significant changes to the various parts of the compiler are listed in the +following sections. + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +10, 11, 12, 13, or 14. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Fix a compiler bug where programs using Template Haskell involving Constant + Applicative forms could be garbage collected too early (:ghc-ticket:`22417`). + +- Fix a shadowing related bug in the occurence analysis phase of the simplifier + (:ghc-ticket:`22623`). + +- Fix a regression in the typechecker where certain typeclass instances + involving type and data familes would fail to resolve (:ghc-ticket:`22647`, + :ghc-ticket:`23134`). + +- Fix a regression in the constrain solver which resulted in a loop when trying + to expand superclasses (:ghc-ticket:`22516`). + +- Fix the linker warning about chained fixups on Darwin platforms for programs + compiled with GHC (:ghc-ticket:`22429`). + +- Fix a compiler panic in the demand analyser due to a bug involving shadowing + (:ghc-ticket:`22718`). + +- Fix a driver bug where certain non-fatal Safe Haskell related warnings were + being marked as fatal (:ghc-ticket:`22728`). + +- Fix a bug to do with missing parenthesis while printing splices with + ``-ddump-splices`` (:ghc-ticket:`22784`). + +- Fix a bug with the graph-colouring register allocater leading to compiler + panics when compiling with ``-fregs-graph`` (:ghc-ticket:`22798`, + :ghc-ticket:`23002`). + +- Fix a bug to do with code emitted on Darwin platforms using + relocations not supported on the platform (:ghc-ticket:`21972`). + +- Improve performance for code generated by the native code generator on + x86 for programs involving atomic counters (:ghc-ticket:`22764`). + +- Fix core lint errors arising from incorrect scoping of type variables + within ``SPECIALISE`` pragmas occuring in ``instance`` definitions + (:ghc-ticket:`22913`). + +- Fix core lint errors arising from an incorrect type given to the + ``decodeDouble_Int64`` rule (:ghc-ticket:`23019`). + +- Improve code generation for bitmasks on AArch64 with the native code + generator (:ghc-ticket:`23030`). + +- Many improvements to recompilation checking with multiple home units + (:ghc-ticket:`22675`, :ghc-ticket:`22677`, :ghc-ticket:`22669`, :ghc-ticket:`22678`, + :ghc-ticket:`22679`, :ghc-ticket:`22680`). + +- Fix a spurious warning with ``-Wmissing-home-modules`` (:ghc-ticket:`22676`). + +- Fix a typechecker panic on certain programs involving representation polymorphism + (:ghc-ticket:`22743`). + +- Fix bugs to do with GHCi and compiler loops pariticularly when using ``-dppr-debug`` + (:ghc-ticket:`22695`). + +- Fix memory leak in the compiler and in GHCi, including a bug where old + environments would persist on reloading (:ghc-ticket:`22530`, :ghc-ticket:`22833`). + +- Fix a miscompilation due to a simplifier bug (:ghc-ticket:`23184`). + +- Fix a miscompilation to do with unlifted bindings due to a bug in the specialiser + (:ghc-ticket:`22998`). + +- Fix a compiler panic during the "Float In" optimsation pass due to improper + handling of shadowing (:ghc-ticket:`22662`). + +- Fix a compiler panic when compiling certain programs involving representation + polymoprhism with optimisation (:ghc-ticet:`22725`). + +Runtime system +-------------- + +- Fix a GC bug where a race condition in the parallel GC could cause it to + garbage collect live sparks (:ghc-ticket:`22528`). + +- Truncate eventlog events with a large payload (:ghc-ticket:`20221`). + +- Fix a bug with the alignment of RTS data structures that could result in + segfaults when compiled with high optimisation settings on certain platforms + (:ghc-ticket:`22975` , :ghc-ticket:`22965`). + +- Take section alignment into account in the RTS linker (:ghc-ticket:`23066`). + +- Fix a bug causing segfaults where certain sections of the RTS would assume + that the number of capabilites was equal to the number passed via the command + line, even though the number of capabilites can be dynamically changed + (:ghc-ticket:`23088`). + +- Fix a race with the nonmoving GC (:ghc-ticket:`23170`). + +- A bug in the nonmoving garbage collector regarding the treatment of + zero-length ``SmallArray#``\ s has been fixed (:ghc-ticket:`22264`). + +- A number of bugs regarding the non-moving garbage collector's treatment of + ``Weak#`` pointers have been fixed (:ghc-ticket:`22327`). + +- A few race conditions between the non-moving collector and + ``setNumCapabilities`` which could result in undefined behavior have been + fixed (:ghc-ticket:`22926`, :ghc-ticket:`22927`). + +- The non-moving collector is now able to better schedule marking work during + the post-mark synchronization phase of collection, significantly reducing + pause times in some workloads (:ghc-ticket:`22929`). + +- Various bugs in the non-moving collector's implementation of the selector + optimisation have been fixed (:ghc-ticket:`22930`). + +- Accounting for live bytes is now performed accurately when using the + non-moving GC (:ghc-ticket:`17574`). + +- Allow performing memory inventory with the non-moving GC (:ghc-ticket:`21840`). + +Build system and packaging +-------------------------- + +- Bump ``gmp-tarballs`` to a version which doesn't use the reserved ``x18`` + register on AArch64/Darwin systems, and also has fixes for CVE-2021-43618 + (:ghc-ticket:`22497`, :ghc-ticket:`22789`). + +- Remove quarantine attribute when installing binary distribution on MacOS + (:ghc-ticket:`21506`, :ghc-ticket:`23009`). + +- Fail in the binary distribution ``configure`` script if ``find`` is not + available (:ghc-ticket:`22691`). + +- Install manpages with the binary distribution (:ghc-ticket:`22371`). + +- Fix a bug to do with merging of archives causing GHC to fail to bootstrap + on Windows (:ghc-ticket:`21990`). + +- Hadrian bug fixes to do with building a Windows cross compiler + (:ghc-ticket:`20697`, :ghc-ticket:`22805`). + +- Fix escaping of ``$tooldir`` in the ``configure`` script (:ghc-ticket:`22561`). + +- Allow LLVM 14 and use it for the Windows toolchain (:ghc-ticket:`21964`). + +Core libraries +-------------- + +- Bump ``base`` to 4.17.1.0 + +- base: Remove ``mingwex`` dependency on Windows (:ghc-ticket:`22166`). + +- base: Fix inconsistency with decoding terminal input on Windows (:ghc-ticket:`21488`). + +- Bump ``bytestring`` to 0.11.4.0 + +- Bump``parsec`` to 3.1.16.1 + +- Bump ``text`` to 2.0.2 + +- Bump ``containers`` to 0.6.7 + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/release-notes.rst ===================================== @@ -4,6 +4,7 @@ Release notes .. toctree:: :maxdepth: 1 + 9.4.5-notes 9.4.4-notes 9.4.3-notes 9.4.2-notes ===================================== libraries/base/changelog.md ===================================== @@ -4,7 +4,7 @@ * Remove `mingwex` dependency on Windows (#22166). - * Fix inconcistency with decoding terminal input on Windows (#21488). + * Fix inconsistency with decoding terminal input on Windows (#21488). ## 4.17.0.0 *August 2022* ===================================== m4/ghc_llvm_target.m4 ===================================== @@ -50,5 +50,10 @@ AC_DEFUN([GHC_LLVM_TARGET], [ # require it. AC_DEFUN([GHC_LLVM_TARGET_SET_VAR], [ AC_REQUIRE([FPTOOLS_SET_PLATFORMS_VARS]) - GHC_LLVM_TARGET([$target],[$target_cpu],[$target_vendor],[$target_os],[LlvmTarget]) + if test "$bootstrap_llvm_target" != "" + then + LlvmTarget=$bootstrap_llvm_target + else + GHC_LLVM_TARGET([$target],[$target_cpu],[$target_vendor],[$target_os],[LlvmTarget]) + fi ]) ===================================== testsuite/tests/rts/all.T ===================================== @@ -356,7 +356,7 @@ test('T10904', [ omit_ways(['ghci']), extra_run_opts('20000') ], test('T10728', [extra_run_opts('+RTS -maxN3 -RTS'), only_ways(['threaded2'])], compile_and_run, ['']) -test('T9405', [when(opsys('mingw32'), expect_broken(21361))], makefile_test, ['T9405']) +test('T9405', normal, makefile_test, ['T9405']) test('T11788', when(ghc_dynamic(), skip), makefile_test, ['T11788']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08a41807a17e5060f24a2a1e4dcd56aec9800fea...403470cf056b24fb9e7a82f42fe35afb0e60d9a6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/08a41807a17e5060f24a2a1e4dcd56aec9800fea...403470cf056b24fb9e7a82f42fe35afb0e60d9a6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 12:21:08 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 15 Apr 2023 08:21:08 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/supersven/aarch64_stackFrameSize Message-ID: <643a96b4229c1_10a80d4bf3f2f0735795@gitlab.mail> Sven Tennie pushed new branch wip/supersven/aarch64_stackFrameSize at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/supersven/aarch64_stackFrameSize You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 13:01:39 2023 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Sat, 15 Apr 2023 09:01:39 -0400 Subject: [Git][ghc/ghc][wip/T22696] 76 commits: Add {-# WARNING #-} to Data.List.{head,tail} Message-ID: <643aa0335e395_10a80d4ca5d3d07379e6@gitlab.mail> Ryan Scott pushed to branch wip/T22696 at Glasgow Haskell Compiler / GHC Commits: 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 22bf9c7b by Ryan Scott at 2023-04-15T13:01:35+00:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2b7c4b092eb55bfc2443bf5388ead312c39e5f0...22bf9c7b05f824f9eafa0ad7d436cc6b1790bd87 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2b7c4b092eb55bfc2443bf5388ead312c39e5f0...22bf9c7b05f824f9eafa0ad7d436cc6b1790bd87 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 13:16:44 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 15 Apr 2023 09:16:44 -0400 Subject: [Git][ghc/ghc][wip/supersven/aarch64_stackFrameSize] Adjust AArch64 stackFrameHeaderSize Message-ID: <643aa3bc902d2_10a80d4cee70f4738543@gitlab.mail> Sven Tennie pushed to branch wip/supersven/aarch64_stackFrameSize at Glasgow Haskell Compiler / GHC Commits: 2dc3e7fc by Sven Tennie at 2023-04-15T13:16:22+00:00 Adjust AArch64 stackFrameHeaderSize The prologue of each stack frame are the saved LR and FP registers, 8 byte each. I.e. the size of the stack frame header is 2 * 8 byte. - - - - - 1 changed file: - compiler/GHC/CmmToAsm/AArch64/Instr.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -32,9 +32,9 @@ import Data.Maybe (fromMaybe) import GHC.Stack --- | TODO: verify this! -stackFrameHeaderSize :: Platform -> Int -stackFrameHeaderSize _ = 64 +-- | LR and FP (8 byte each) are the prologue of each stack frame +stackFrameHeaderSize :: Int +stackFrameHeaderSize = 2 * 8 -- | All registers are 8 byte wide. spillSlotSize :: Int @@ -50,13 +50,13 @@ maxSpillSlots :: NCGConfig -> Int maxSpillSlots config -- = 0 -- set to zero, to see when allocMoreStack has to fire. = let platform = ncgPlatform config - in ((ncgSpillPreallocSize config - stackFrameHeaderSize platform) + in ((ncgSpillPreallocSize config - stackFrameHeaderSize) `div` spillSlotSize) - 1 -- | Convert a spill slot number to a *byte* offset, with no sign. spillSlotToOffset :: NCGConfig -> Int -> Int spillSlotToOffset config slot - = stackFrameHeaderSize (ncgPlatform config) + spillSlotSize * slot + = stackFrameHeaderSize + spillSlotSize * slot -- | Get the registers that are being used by this instruction. -- regUsage doesn't need to do any trickery for jumps and such. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2dc3e7fc7cb33ea374ca4bcb6f48515fa5a081c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2dc3e7fc7cb33ea374ca4bcb6f48515fa5a081c4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 13:17:02 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Sat, 15 Apr 2023 09:17:02 -0400 Subject: [Git][ghc/ghc][wip/T23153] 70 commits: ci: make lint-ci-config job fast again Message-ID: <643aa3cef29f6_10a80d4cee83c8738820@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23153 at Glasgow Haskell Compiler / GHC Commits: 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Doc.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e8aab88084d63b81995430a88b787f8748f56a0...bad2f8b8aa84241e523577062e2b69090efccb32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e8aab88084d63b81995430a88b787f8748f56a0...bad2f8b8aa84241e523577062e2b69090efccb32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 14:51:18 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 15 Apr 2023 10:51:18 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Simpify bitmap decoding Message-ID: <643ab9e6c67d5_10a80d4e91154c74275e@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 8848c884 by Sven Tennie at 2023-04-15T14:50:33+00:00 Simpify bitmap decoding - - - - - 3 changed files: - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -6,6 +6,7 @@ {-# LANGUAGE GHCForeignImportPrim #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE RankNTypes #-} +{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeInType #-} @@ -17,7 +18,6 @@ module GHC.Exts.Stack.Decode ) where -import Data.Array.Byte import Data.Bits import Data.Maybe import Foreign @@ -32,6 +32,7 @@ import GHC.IO (IO (..)) import GHC.Stack.CloneStack import GHC.Word import Prelude +import Debug.Trace {- Note [Decoding the stack] ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -145,7 +146,7 @@ getRetFunType stackSnapshot# index = (# s1, rft# #) -> (# s1, W# rft# #) ) -type LargeBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, ByteArray#, Word# #) +type LargeBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Addr#, Word# #) foreign import prim "getLargeBitmapzh" getLargeBitmap# :: LargeBitmapGetter @@ -229,29 +230,60 @@ data StackFrameIter | -- | Represents a primitive word on the stack SfiPrimitive !StackSnapshot# !WordOffset +data LargeBitmap = LargeBitmap + { largeBitmapSize :: Word + , largebitmapWords :: Ptr Word + } + +-- | Is a bitmap entry a closure pointer or a primitive non-pointer? +data Pointerness = Pointer | NonPointer + deriving Show + decodeLargeBitmap :: LargeBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do - (bitmapArray, size) <- IO $ \s -> + largeBitmap <- IO $ \s -> case getterFun# stackSnapshot# (wordOffsetToWord# index) s of - (# s1, ba#, s# #) -> (# s1, (ByteArray ba#, W# s#) #) - let bitmapWords :: [Word] = byteArrayToList bitmapArray - decodeBitmaps stackSnapshot# (index + relativePayloadOffset) bitmapWords size + (# s1, wordsAddr#, size# #) -> (# s1, LargeBitmap (W# size#) (Ptr wordsAddr#) #) + bitmapWords <-largeBitmapToList largeBitmap + decodeBitmaps stackSnapshot# + (index + relativePayloadOffset) + (bitmapWordsPointerness (largeBitmapSize largeBitmap) bitmapWords) where - byteArrayToList :: ByteArray -> [Word] - byteArrayToList (ByteArray bArray) = go 0 - where - go i - | i < maxIndex = W# (indexWordArray# bArray (toInt# i)) : go (i + 1) - | otherwise = [] - maxIndex = sizeofByteArray bArray `quot` sizeOf (undefined :: Word) - - sizeofByteArray :: ByteArray# -> Int - sizeofByteArray arr# = I# (sizeofByteArray# arr#) - -decodeBitmaps :: StackSnapshot# -> WordOffset -> [Word] -> Word -> IO [Closure] -decodeBitmaps stackSnapshot# index bitmapWords size = - let bes = wordsToBitmapEntries index bitmapWords size - in mapM toBitmapPayload bes + largeBitmapToList :: LargeBitmap -> IO [Word] + largeBitmapToList LargeBitmap {..} = cWordArrayToList largebitmapWords $ + (usedBitmapWords.fromIntegral) largeBitmapSize + + cWordArrayToList :: Ptr Word -> Int -> IO [Word] + cWordArrayToList ptr size = mapM (peekElemOff ptr) [0..(size-1)] + + usedBitmapWords :: Int -> Int + usedBitmapWords 0 = error "Invalid large bitmap size 0." + usedBitmapWords size = (size `div` (fromIntegral wORD_SIZE_IN_BITS)) + 1 + + bitmapWordsPointerness :: Word -> [Word] -> [Pointerness] + bitmapWordsPointerness size _ | size <= 0 = [] + bitmapWordsPointerness _ [] = [] + bitmapWordsPointerness size (w:wds) = + bitmapWordPointerness (min size (fromIntegral wORD_SIZE_IN_BITS)) w ++ + bitmapWordsPointerness (size - (fromIntegral wORD_SIZE_IN_BITS)) wds + +bitmapWordPointerness :: Word -> Word -> [Pointerness] +bitmapWordPointerness 0 _ = [] +bitmapWordPointerness bSize bitmapWord = + ( if (bitmapWord .&. 1) /= 0 + then NonPointer + else Pointer + ) + : bitmapWordPointerness + (bSize - 1) + (bitmapWord `shiftR` 1) + +decodeBitmaps :: StackSnapshot# -> WordOffset -> [Pointerness] -> IO [Closure] +decodeBitmaps stackSnapshot# index bitmapWords = + let bes = toEntries index bitmapWords + in do + traceM $ "decodeBitmaps - index: " ++ show index ++ " words: " ++ show bitmapWords + mapM toBitmapPayload bes where toBitmapPayload :: StackFrameIter -> IO Closure toBitmapPayload (SfiPrimitive stack# i) = do @@ -259,42 +291,14 @@ decodeBitmaps stackSnapshot# index bitmapWords size = pure $ UnknownTypeWordSizedPrimitive w toBitmapPayload (SfiClosure stack# i) = getClosure stack# i - wordsToBitmapEntries :: WordOffset -> [Word] -> Word -> [StackFrameIter] - wordsToBitmapEntries _ [] 0 = [] - wordsToBitmapEntries _ [] i = error $ "Invalid state: Empty list, size " ++ show i - wordsToBitmapEntries _ l 0 = error $ "Invalid state: Size 0, list " ++ show l - wordsToBitmapEntries index' (b : bs) bitmapSize = - let entries = toBitmapEntries index' b (min bitmapSize (fromIntegral wORD_SIZE_IN_BITS)) - mbLastFrame = (listToMaybe . reverse) entries - in case mbLastFrame of - Just sfi' -> - entries - ++ wordsToBitmapEntries - (getIndex sfi' + 1) - bs - subtractDecodedBitmapWord - _ -> error "This should never happen! Recursion ended not in base case." - where - subtractDecodedBitmapWord :: Word - subtractDecodedBitmapWord = - fromIntegral $ - max 0 (fromIntegral bitmapSize - wORD_SIZE_IN_BITS) - - toBitmapEntries :: WordOffset -> Word -> Word -> [StackFrameIter] - toBitmapEntries _ _ 0 = [] - toBitmapEntries i bitmapWord bSize = - ( if (bitmapWord .&. 1) /= 0 - then SfiPrimitive stackSnapshot# i - else SfiClosure stackSnapshot# i - ) - : toBitmapEntries - (i + 1) - (bitmapWord `shiftR` 1) - (bSize - 1) - - getIndex :: StackFrameIter -> WordOffset - getIndex (SfiClosure _ i) = i - getIndex (SfiPrimitive _ i) = i + toEntries :: WordOffset -> [Pointerness] -> [StackFrameIter] + toEntries _ [] = [] + toEntries i (p:ps) = + let sn = case p of + NonPointer -> SfiPrimitive stackSnapshot# i + Pointer -> SfiClosure stackSnapshot# i + in + sn : toEntries (i + 1) ps decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = @@ -302,8 +306,7 @@ decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = (bitmap, size) <- IO $ \s -> case getterFun# stackSnapshot# (wordOffsetToWord# index) s of (# s1, b#, s# #) -> (# s1, (W# b#, W# s#) #) - let bitmapWords = [bitmap | size > 0] - decodeBitmaps stackSnapshot# (index + relativePayloadOffset) bitmapWords size + decodeBitmaps stackSnapshot# (index + relativePayloadOffset) (bitmapWordPointerness size bitmap) unpackStackFrame :: StackFrameLocation -> IO StackFrame unpackStackFrame (StackSnapshot stackSnapshot#, index) = do ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -110,52 +110,30 @@ StgWord getBCOLargeBitmapSize(StgClosure *c) { return BCO_BITMAP_SIZE(bco); } -#define ROUNDUP_BITS_TO_WDS(n) \ - (((n) + WORD_SIZE_IN_BITS - 1) / WORD_SIZE_IN_BITS) - -// Copied from Cmm.h -#define SIZEOF_W SIZEOF_VOID_P -#define WDS(n) ((n)*SIZEOF_W) - -static StgArrBytes *largeBitmapToStgArrBytes(Capability *cap, - StgLargeBitmap *bitmap) { - StgWord neededWords = ROUNDUP_BITS_TO_WDS(bitmap->size); - StgArrBytes *array = - (StgArrBytes *)allocate(cap, sizeofW(StgArrBytes) + neededWords); - SET_HDR(array, &stg_ARR_WORDS_info, CCS_SYSTEM); - array->bytes = WDS(ROUNDUP_BITS_TO_WDS(bitmap->size)); - - for (int i = 0; i < neededWords; i++) { - array->payload[i] = bitmap->bitmap[i]; - } - - return array; -} - -StgArrBytes *getLargeBitmap(Capability *cap, StgClosure *c) { +StgWord *getLargeBitmap(Capability *cap, StgClosure *c) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); const StgInfoTable *info = get_itbl(c); StgLargeBitmap *bitmap = GET_LARGE_BITMAP(info); - return largeBitmapToStgArrBytes(cap, bitmap); + return bitmap->bitmap; } -StgArrBytes *getRetFunLargeBitmap(Capability *cap, StgRetFun *ret_fun) { +StgWord *getRetFunLargeBitmap(Capability *cap, StgRetFun *ret_fun) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(ret_fun)); const StgFunInfoTable *fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun)); StgLargeBitmap *bitmap = GET_FUN_LARGE_BITMAP(fun_info); - return largeBitmapToStgArrBytes(cap, bitmap); + return bitmap->bitmap; } -StgArrBytes *getBCOLargeBitmap(Capability *cap, StgClosure *c) { +StgWord *getBCOLargeBitmap(Capability *cap, StgClosure *c) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); StgBCO *bco = (StgBCO *)*c->payload; StgLargeBitmap *bitmap = BCO_BITMAP(bco); - return largeBitmapToStgArrBytes(cap, bitmap); + return bitmap->bitmap; } StgStack *getUnderflowFrameNextChunk(StgUnderflowFrame *frame) { ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -77,41 +77,41 @@ getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) { // getLargeBitmapzh(StgStack* stack, StgWord offsetWords) getLargeBitmapzh(P_ stack, W_ offsetWords) { - P_ c, stgArrBytes; + P_ c, words; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - (stgArrBytes) = ccall getLargeBitmap(MyCapability(), c); + (words) = ccall getLargeBitmap(MyCapability(), c); (size) = ccall getLargeBitmapSize(c); - return (stgArrBytes, size); + return (words, size); } // getBCOLargeBitmapzh(StgStack* stack, StgWord offsetWords) getBCOLargeBitmapzh(P_ stack, W_ offsetWords) { - P_ c, stgArrBytes; + P_ c, words; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - (stgArrBytes) = ccall getBCOLargeBitmap(MyCapability(), c); + (words) = ccall getBCOLargeBitmap(MyCapability(), c); (size) = ccall getBCOLargeBitmapSize(c); - return (stgArrBytes, size); + return (words, size); } // getRetFunLargeBitmapzh(StgStack* stack, StgWord offsetWords) getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) { - P_ c, stgArrBytes; + P_ c, words; W_ size; c = StgStack_sp(stack) + WDS(offsetWords); ASSERT(LOOKS_LIKE_CLOSURE_PTR(c)); - (stgArrBytes) = ccall getRetFunLargeBitmap(MyCapability(), c); + (words) = ccall getRetFunLargeBitmap(MyCapability(), c); (size) = ccall getRetFunSize(c); - return (stgArrBytes, size); + return (words, size); } // getWordzh(StgStack* stack, StgWord offsetWords) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8848c8842f573b700a3594c901382e9375969616 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8848c8842f573b700a3594c901382e9375969616 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 15:22:38 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 15 Apr 2023 11:22:38 -0400 Subject: [Git][ghc/ghc][wip/supersven/aarch64_stackFrameSize] Adjust AArch64 stackFrameHeaderSize Message-ID: <643ac13ed654c_10a80d4f1c23f87499b@gitlab.mail> Sven Tennie pushed to branch wip/supersven/aarch64_stackFrameSize at Glasgow Haskell Compiler / GHC Commits: 4d192e94 by Sven Tennie at 2023-04-15T15:22:17+00:00 Adjust AArch64 stackFrameHeaderSize The prologue of each stack frame are the saved LR and FP registers, 8 byte each. I.e. the size of the stack frame header is 2 * 8 byte. - - - - - 1 changed file: - compiler/GHC/CmmToAsm/AArch64/Instr.hs Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -32,9 +32,9 @@ import Data.Maybe (fromMaybe) import GHC.Stack --- | TODO: verify this! -stackFrameHeaderSize :: Platform -> Int -stackFrameHeaderSize _ = 64 +-- | LR and FP (8 byte each) are the prologue of each stack frame +stackFrameHeaderSize :: Int +stackFrameHeaderSize = 2 * 8 -- | All registers are 8 byte wide. spillSlotSize :: Int @@ -49,14 +49,13 @@ stackAlign = 16 maxSpillSlots :: NCGConfig -> Int maxSpillSlots config -- = 0 -- set to zero, to see when allocMoreStack has to fire. - = let platform = ncgPlatform config - in ((ncgSpillPreallocSize config - stackFrameHeaderSize platform) + = ((ncgSpillPreallocSize config - stackFrameHeaderSize) `div` spillSlotSize) - 1 -- | Convert a spill slot number to a *byte* offset, with no sign. spillSlotToOffset :: NCGConfig -> Int -> Int -spillSlotToOffset config slot - = stackFrameHeaderSize (ncgPlatform config) + spillSlotSize * slot +spillSlotToOffset _ slot + = stackFrameHeaderSize + spillSlotSize * slot -- | Get the registers that are being used by this instruction. -- regUsage doesn't need to do any trickery for jumps and such. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d192e9413544f45d164e896b2f736f65f3de965 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d192e9413544f45d164e896b2f736f65f3de965 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 15 15:44:09 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 15 Apr 2023 11:44:09 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 3 commits: Get rid of StackFrameIter Message-ID: <643ac649cccb9_10a80d4f643d147502a6@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 1a05765e by Sven Tennie at 2023-04-15T15:01:34+00:00 Get rid of StackFrameIter - - - - - bfc556e1 by Sven Tennie at 2023-04-15T15:07:44+00:00 Formatting - - - - - 46e8e371 by Sven Tennie at 2023-04-15T15:42:47+00:00 Add docs / rename - - - - - 2 changed files: - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -18,21 +18,27 @@ module GHC.Exts.Stack.Decode ) where +import Control.Monad import Data.Bits import Data.Maybe import Foreign import GHC.Exts +import GHC.Exts.Heap (Box (..), getBoxedClosureData) import GHC.Exts.Heap.ClosureTypes -import GHC.Exts.Heap.Closures (RetFunType(..), Closure, GenClosure(UnknownTypeWordSizedPrimitive), StackFrame(..), StgStackClosure(..)) +import GHC.Exts.Heap.Closures + ( Closure, + GenClosure (UnknownTypeWordSizedPrimitive), + RetFunType (..), + StackFrame (..), + StgStackClosure (..), + ) import GHC.Exts.Heap.Constants (wORD_SIZE_IN_BITS) -import GHC.Exts.Heap (Box(..), getBoxedClosureData) import GHC.Exts.Heap.InfoTable import GHC.Exts.Stack.Constants import GHC.IO (IO (..)) import GHC.Stack.CloneStack import GHC.Word import Prelude -import Debug.Trace {- Note [Decoding the stack] ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -146,6 +152,11 @@ getRetFunType stackSnapshot# index = (# s1, rft# #) -> (# s1, W# rft# #) ) +-- | Gets contents of a `LargeBitmap` (@StgLargeBitmap@) +-- +-- The first two arguments identify the location of the frame on the stack. +-- Returned is the `Addr#` of the @StgWord[]@ (bitmap) and it's size. The +-- `RealWorld` token is used to run this in an `IO` context. type LargeBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Addr#, Word# #) foreign import prim "getLargeBitmapzh" getLargeBitmap# :: LargeBitmapGetter @@ -154,6 +165,11 @@ foreign import prim "getBCOLargeBitmapzh" getBCOLargeBitmap# :: LargeBitmapGette foreign import prim "getRetFunLargeBitmapzh" getRetFunLargeBitmap# :: LargeBitmapGetter +-- | Gets contents of a small bitmap (fitting in one @StgWord@) +-- +-- The first two arguments identify the location of the frame on the stack. +-- Returned is the bitmap and it's size. The `RealWorld` token is used to run +-- this in an `IO` context. type SmallBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Word#, Word# #) foreign import prim "getSmallBitmapzh" getSmallBitmap# :: SmallBitmapGetter @@ -188,24 +204,24 @@ getStackFields stackSnapshot# = IO $ \s -> (# s1, sSize#, sDirty#, sMarking# #) -> (# s1, (W32# sSize#, W8# sDirty#, W8# sMarking#) #) --- | Get an interator starting with the top-most stack frame -stackHead :: StackSnapshot -> (StackSnapshot, WordOffset) +-- | `StackFrameLocation` of the top-most stack frame +stackHead :: StackSnapshot -> StackFrameLocation stackHead (StackSnapshot s#) = (StackSnapshot s#, 0) -- GHC stacks are never empty -- | Advance to the next stack frame (if any) -- -- The last `Int#` in the result tuple is meant to be treated as bool -- (has_next). -foreign import prim "advanceStackFrameIterzh" - advanceStackFrameIter# :: +foreign import prim "advanceStackFrameLocationzh" + advanceStackFrameLocation# :: StackSnapshot# -> Word# -> (# StackSnapshot#, Word#, Int# #) --- | Advance iterator to the next stack frame (if any) -advanceStackFrameIter :: StackSnapshot -> WordOffset -> Maybe (StackSnapshot, WordOffset) -advanceStackFrameIter (StackSnapshot stackSnapshot#) index = - let !(# s', i', hasNext #) = advanceStackFrameIter# stackSnapshot# (wordOffsetToWord# index) +-- | Advance to the next stack frame (if any) +advanceStackFrameLocation :: StackFrameLocation -> Maybe StackFrameLocation +advanceStackFrameLocation ((StackSnapshot stackSnapshot#), index) = + let !(# s', i', hasNext #) = advanceStackFrameLocation# stackSnapshot# (wordOffsetToWord# index) in if I# hasNext > 0 - then Just $ (StackSnapshot s', (primWordToWordOffset i')) + then Just (StackSnapshot s', primWordToWordOffset i') else Nothing where primWordToWordOffset :: Word# -> WordOffset @@ -223,49 +239,45 @@ getClosure stackSnapshot# index = ) >>= getBoxedClosureData --- | Iterator state for stack decoding -data StackFrameIter - = -- | Represents a closure on the stack - SfiClosure !StackSnapshot# !WordOffset - | -- | Represents a primitive word on the stack - SfiPrimitive !StackSnapshot# !WordOffset - +-- | Representation of @StgLargeBitmap@ (RTS) data LargeBitmap = LargeBitmap - { largeBitmapSize :: Word - , largebitmapWords :: Ptr Word - } + { largeBitmapSize :: Word, + largebitmapWords :: Ptr Word + } -- | Is a bitmap entry a closure pointer or a primitive non-pointer? data Pointerness = Pointer | NonPointer - deriving Show + deriving (Show) decodeLargeBitmap :: LargeBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do largeBitmap <- IO $ \s -> case getterFun# stackSnapshot# (wordOffsetToWord# index) s of (# s1, wordsAddr#, size# #) -> (# s1, LargeBitmap (W# size#) (Ptr wordsAddr#) #) - bitmapWords <-largeBitmapToList largeBitmap - decodeBitmaps stackSnapshot# + bitmapWords <- largeBitmapToList largeBitmap + decodeBitmaps + stackSnapshot# (index + relativePayloadOffset) (bitmapWordsPointerness (largeBitmapSize largeBitmap) bitmapWords) where largeBitmapToList :: LargeBitmap -> IO [Word] - largeBitmapToList LargeBitmap {..} = cWordArrayToList largebitmapWords $ - (usedBitmapWords.fromIntegral) largeBitmapSize + largeBitmapToList LargeBitmap {..} = + cWordArrayToList largebitmapWords $ + (usedBitmapWords . fromIntegral) largeBitmapSize cWordArrayToList :: Ptr Word -> Int -> IO [Word] - cWordArrayToList ptr size = mapM (peekElemOff ptr) [0..(size-1)] + cWordArrayToList ptr size = mapM (peekElemOff ptr) [0 .. (size - 1)] usedBitmapWords :: Int -> Int usedBitmapWords 0 = error "Invalid large bitmap size 0." - usedBitmapWords size = (size `div` (fromIntegral wORD_SIZE_IN_BITS)) + 1 + usedBitmapWords size = (size `div` fromIntegral wORD_SIZE_IN_BITS) + 1 bitmapWordsPointerness :: Word -> [Word] -> [Pointerness] bitmapWordsPointerness size _ | size <= 0 = [] bitmapWordsPointerness _ [] = [] - bitmapWordsPointerness size (w:wds) = - bitmapWordPointerness (min size (fromIntegral wORD_SIZE_IN_BITS)) w ++ - bitmapWordsPointerness (size - (fromIntegral wORD_SIZE_IN_BITS)) wds + bitmapWordsPointerness size (w : wds) = + bitmapWordPointerness (min size (fromIntegral wORD_SIZE_IN_BITS)) w + ++ bitmapWordsPointerness (size - fromIntegral wORD_SIZE_IN_BITS) wds bitmapWordPointerness :: Word -> Word -> [Pointerness] bitmapWordPointerness 0 _ = [] @@ -279,26 +291,15 @@ bitmapWordPointerness bSize bitmapWord = (bitmapWord `shiftR` 1) decodeBitmaps :: StackSnapshot# -> WordOffset -> [Pointerness] -> IO [Closure] -decodeBitmaps stackSnapshot# index bitmapWords = - let bes = toEntries index bitmapWords - in do - traceM $ "decodeBitmaps - index: " ++ show index ++ " words: " ++ show bitmapWords - mapM toBitmapPayload bes +decodeBitmaps stack# index ps = + zipWithM toPayload ps [index ..] where - toBitmapPayload :: StackFrameIter -> IO Closure - toBitmapPayload (SfiPrimitive stack# i) = do - w <- getWord stack# i - pure $ UnknownTypeWordSizedPrimitive w - toBitmapPayload (SfiClosure stack# i) = getClosure stack# i - - toEntries :: WordOffset -> [Pointerness] -> [StackFrameIter] - toEntries _ [] = [] - toEntries i (p:ps) = - let sn = case p of - NonPointer -> SfiPrimitive stackSnapshot# i - Pointer -> SfiClosure stackSnapshot# i - in - sn : toEntries (i + 1) ps + toPayload :: Pointerness -> WordOffset -> IO Closure + toPayload p i = case p of + NonPointer -> do + w <- getWord stack# i + pure $ UnknownTypeWordSizedPrimitive w + Pointer -> getClosure stack# i decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = @@ -306,7 +307,10 @@ decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = (bitmap, size) <- IO $ \s -> case getterFun# stackSnapshot# (wordOffsetToWord# index) s of (# s1, b#, s# #) -> (# s1, (W# b#, W# s#) #) - decodeBitmaps stackSnapshot# (index + relativePayloadOffset) (bitmapWordPointerness size bitmap) + decodeBitmaps + stackSnapshot# + (index + relativePayloadOffset) + (bitmapWordPointerness size bitmap) unpackStackFrame :: StackFrameLocation -> IO StackFrame unpackStackFrame (StackSnapshot stackSnapshot#, index) = do @@ -449,12 +453,13 @@ decodeStack (StackSnapshot stack#) = do stackFrameLocations :: StackSnapshot -> [StackFrameLocation] stackFrameLocations s = stackHead s - : go (uncurry advanceStackFrameIter (stackHead s)) + : go (advanceStackFrameLocation (stackHead s)) where go :: Maybe StackFrameLocation -> [StackFrameLocation] go Nothing = [] - go (Just r) = r : go (uncurry advanceStackFrameIter r) + go (Just r) = r : go (advanceStackFrameLocation r) #else module GHC.Exts.Stack.Decode where +import qualified GHC.Base as stack #endif ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -8,8 +8,8 @@ // developed. #if defined(StgStack_marking) -// advanceStackFrameIterzh(StgStack* stack, StgWord offsetWords) -advanceStackFrameIterzh (P_ stack, W_ offsetWords) { +// advanceStackFrameLocationzh(StgStack* stack, StgWord offsetWords) +advanceStackFrameLocationzh (P_ stack, W_ offsetWords) { W_ frameSize; (frameSize) = ccall stackFrameSize(stack, offsetWords); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8848c8842f573b700a3594c901382e9375969616...46e8e371a42b00299fa5d34d3c22227cf88ee876 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8848c8842f573b700a3594c901382e9375969616...46e8e371a42b00299fa5d34d3c22227cf88ee876 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 08:55:35 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 16 Apr 2023 04:55:35 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Cleanup Message-ID: <643bb807e6430_10a80d5fa8d7fc76193d@gitlab.mail> Spam detection software, running on the system "mail.haskell.org", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 3dd9506c by Sven Tennie at 2023-04-16T08:53:15+00:00 Cleanup - - - - - [...] Content analysis details: (6.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 1.1 URI_HEX URI: URI hostname has long hexadecimal sequence 5.0 UNWANTED_LANGUAGE_BODY BODY: Message written in an undesired language 0.0 HTML_MESSAGE BODY: HTML included in message 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% [score: 0.4255] 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid The original message was not completely plain text, and may be unsafe to open with some email clients; in particular, it may contain a virus, or confirm that your address can receive spam. If you wish to view it, it may be safer to save it to a file and open it with an editor. -------------- next part -------------- An embedded message was scrubbed... From: "Sven Tennie (@supersven)" Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Cleanup Date: Sun, 16 Apr 2023 04:55:35 -0400 Size: 13293 URL: From gitlab at gitlab.haskell.org Sun Apr 16 09:41:42 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Sun, 16 Apr 2023 05:41:42 -0400 Subject: [Git][ghc/ghc][wip/ghc-9.4.5-backports] ci: lint-ci-config: regenerate cabal.config Message-ID: <643bc2d64f2b8_10a80d606b32987646d7@gitlab.mail> Zubin pushed to branch wip/ghc-9.4.5-backports at Glasgow Haskell Compiler / GHC Commits: a213d367 by Zubin Duggal at 2023-04-16T15:11:30+05:30 ci: lint-ci-config: regenerate cabal.config - - - - - 1 changed file: - .gitlab/generate_jobs Changes: ===================================== .gitlab/generate_jobs ===================================== @@ -3,6 +3,7 @@ cd "$(dirname "${BASH_SOURCE[0]}")" tmp=$(mktemp) +rm -f /root/.cabal/config ./gen_ci.hs $tmp rm -f jobs.yaml echo "### THIS IS A GENERATED FILE, DO NOT MODIFY DIRECTLY" > jobs.yaml View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a213d3676550a0e4d542172de539c0cfa2662431 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a213d3676550a0e4d542172de539c0cfa2662431 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 12:10:57 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 08:10:57 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Message-ID: <643be5d11a914_10a80d62c6707077223e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 9bc1c7c7 by Simon Peyton Jones at 2023-04-16T08:10:42-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - c7921c0a by Oleg Grenrus at 2023-04-16T08:10:48-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 6 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Tc/Types/Constraint.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings ===================================== compiler/GHC/Driver/Errors/Types.hs ===================================== @@ -25,7 +25,8 @@ import GHC.Prelude import Data.Bifunctor import Data.Typeable -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, PackageArg, gopt) +import GHC.Driver.Flags (GeneralFlag (Opt_BuildingCabalPackage)) import GHC.Types.Error import GHC.Unit.Module import GHC.Unit.State ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name, dataName) -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) import qualified GHC.LanguageExtensions as LangExt import Data.Data ===================================== compiler/GHC/HsToCore/Errors/Types.hs ===================================== @@ -9,7 +9,8 @@ import GHC.Prelude import GHC.Core (CoreRule, CoreExpr, RuleName) import GHC.Core.DataCon import GHC.Core.Type -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) +import GHC.Driver.Flags (WarningFlag) import GHC.Hs import GHC.HsToCore.Pmc.Solver.Types import GHC.Types.Basic (Activation) ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -117,7 +117,7 @@ import GHC.Core import GHC.Core.TyCo.Ppr import GHC.Utils.FV import GHC.Types.Var.Set -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags(reductionDepth)) import GHC.Types.Basic import GHC.Types.Unique import GHC.Types.Unique.Set ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -335,39 +335,9 @@ type role TExp nominal -- See Note [Role of TExp] newtype TExp (a :: TYPE (r :: RuntimeRep)) = TExp { unType :: Exp -- ^ Underlying untyped Template Haskell expression } --- ^ Represents an expression which has type @a at . Built on top of 'Exp', typed --- expressions allow for type-safe splicing via: --- --- - typed quotes, written as @[|| ... ||]@ where @...@ is an expression; if --- that expression has type @a@, then the quotation has type --- @'Q' ('TExp' a)@ --- --- - typed splices inside of typed quotes, written as @$$(...)@ where @...@ --- is an arbitrary expression of type @'Q' ('TExp' a)@ --- --- Traditional expression quotes and splices let us construct ill-typed --- expressions: --- --- >>> fmap ppr $ runQ [| True == $( [| "foo" |] ) |] --- GHC.Types.True GHC.Classes.== "foo" --- >>> GHC.Types.True GHC.Classes.== "foo" --- error: --- • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ --- • In the second argument of ‘(==)’, namely ‘"foo"’ --- In the expression: True == "foo" --- In an equation for ‘it’: it = True == "foo" +-- ^ Typed wrapper around an 'Exp'. -- --- With typed expressions, the type error occurs when /constructing/ the --- Template Haskell expression: --- --- >>> fmap ppr $ runQ [|| True == $$( [|| "foo" ||] ) ||] --- error: --- • Couldn't match type ‘[Char]’ with ‘Bool’ --- Expected type: Q (TExp Bool) --- Actual type: Q (TExp [Char]) --- • In the Template Haskell quotation [|| "foo" ||] --- In the expression: [|| "foo" ||] --- In the Template Haskell splice $$([|| "foo" ||]) +-- This is the typed representation of terms produced by typed quotes. -- -- Representation-polymorphic since /template-haskell-2.16.0.0/. @@ -395,13 +365,13 @@ unsafeTExpCoerce m = do { e <- m TExp's argument must have a nominal role, not phantom as would be inferred (#8459). Consider - e :: TExp Age - e = MkAge 3 + e :: Code Q Age + e = [|| MkAge 3 ||] foo = $(coerce e) + 4::Int The splice will evaluate to (MkAge 3) and you can't add that to -4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +4::Int. So you can't coerce a (Code Q Age) to a (Code Q Int). -} -- Code constructor @@ -409,6 +379,40 @@ type role Code representational nominal -- See Note [Role of TExp] newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code { examineCode :: m (TExp a) -- ^ Underlying monadic value } +-- ^ Represents an expression which has type @a@, built in monadic context @m at . Built on top of 'TExp', typed +-- expressions allow for type-safe splicing via: +-- +-- - typed quotes, written as @[|| ... ||]@ where @...@ is an expression; if +-- that expression has type @a@, then the quotation has type +-- @Quote m => Code m a@ +-- +-- - typed splices inside of typed quotes, written as @$$(...)@ where @...@ +-- is an arbitrary expression of type @Quote m => Code m a@ +-- +-- Traditional expression quotes and splices let us construct ill-typed +-- expressions: +-- +-- >>> fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |]) +-- GHC.Types.True GHC.Classes.== "foo" +-- >>> GHC.Types.True GHC.Classes.== "foo" +-- error: +-- • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ +-- • In the second argument of ‘(==)’, namely ‘"foo"’ +-- In the expression: True == "foo" +-- In an equation for ‘it’: it = True == "foo" +-- +-- With typed expressions, the type error occurs when /constructing/ the +-- Template Haskell expression: +-- +-- >>> fmap ppr $ runQ (unTypeCode [|| True == $$( [|| "foo" ||] ) ||]) +-- error: +-- • Couldn't match type ‘[Char]’ with ‘Bool’ +-- Expected type: Code Q Bool +-- Actual type: Code Q [Char] +-- • In the Template Haskell quotation [|| "foo" ||] +-- In the expression: [|| "foo" ||] +-- In the Template Haskell splice $$([|| "foo" ||]) + -- | Unsafely convert an untyped code representation into a typed code -- representation. @@ -958,7 +962,7 @@ sequenceQ = sequence -- Haskell quotation is bound outside the Oxford brackets (@[| ... |]@ or -- @[|| ... ||]@) but not at the top level. As an example: -- --- > add1 :: Int -> Q (TExp Int) +-- > add1 :: Int -> Code Q Int -- > add1 x = [|| x + 1 ||] -- -- Template Haskell has no way of knowing what value @x@ will take on at @@ -966,7 +970,7 @@ sequenceQ = sequence -- -- A 'Lift' instance must satisfy @$(lift x) ≡ x@ and @$$(liftTyped x) ≡ x@ -- for all @x@, where @$(...)@ and @$$(...)@ are Template Haskell splices. --- It is additionally expected that @'lift' x ≡ 'unTypeQ' ('liftTyped' x)@. +-- It is additionally expected that @'lift' x ≡ 'unTypeCode' ('liftTyped' x)@. -- -- 'Lift' instances can be derived automatically by use of the @-XDeriveLift@ -- GHC language extension: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6fd7f46f92337c4a48062d0890d617ca06b3c32...c7921c0affebc33d2c503b7ab5b6ff3d6c0cd81d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6fd7f46f92337c4a48062d0890d617ca06b3c32...c7921c0affebc33d2c503b7ab5b6ff3d6c0cd81d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 14:51:17 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 10:51:17 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Transfer DFunId_ness onto specialised bindings Message-ID: <643c0b65809a7_10a80d65422efc7868a6@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3684ae98 by Simon Peyton Jones at 2023-04-16T10:51:07-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - f39dbaf6 by Oleg Grenrus at 2023-04-16T10:51:09-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 5 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Tc/Types/Constraint.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings ===================================== compiler/GHC/Driver/Errors/Types.hs ===================================== @@ -25,7 +25,8 @@ import GHC.Prelude import Data.Bifunctor import Data.Typeable -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, PackageArg, gopt) +import GHC.Driver.Flags (GeneralFlag (Opt_BuildingCabalPackage)) import GHC.Types.Error import GHC.Unit.Module import GHC.Unit.State ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name, dataName) -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) import qualified GHC.LanguageExtensions as LangExt import Data.Data ===================================== compiler/GHC/HsToCore/Errors/Types.hs ===================================== @@ -9,7 +9,8 @@ import GHC.Prelude import GHC.Core (CoreRule, CoreExpr, RuleName) import GHC.Core.DataCon import GHC.Core.Type -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) +import GHC.Driver.Flags (WarningFlag) import GHC.Hs import GHC.HsToCore.Pmc.Solver.Types import GHC.Types.Basic (Activation) ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -117,7 +117,7 @@ import GHC.Core import GHC.Core.TyCo.Ppr import GHC.Utils.FV import GHC.Types.Var.Set -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags(reductionDepth)) import GHC.Types.Basic import GHC.Types.Unique import GHC.Types.Unique.Set View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7921c0affebc33d2c503b7ab5b6ff3d6c0cd81d...f39dbaf6b11a82291ccdec4f627413376f296bba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7921c0affebc33d2c503b7ab5b6ff3d6c0cd81d...f39dbaf6b11a82291ccdec4f627413376f296bba You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 17:36:59 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Sun, 16 Apr 2023 13:36:59 -0400 Subject: [Git][ghc/ghc][ghc-9.4] 147 commits: winio: do not re-translate input when handle is uncooked Message-ID: <643c323b57294_10a80d67fbd4a4807841@gitlab.mail> Zubin pushed to branch ghc-9.4 at Glasgow Haskell Compiler / GHC Commits: e10a1966 by Tamar Christina at 2023-03-28T11:26:33+05:30 winio: do not re-translate input when handle is uncooked (cherry picked from commit 626652f7c172f307bd87afaee59c7f0e2825c55d) - - - - - 0f46d481 by Andreas Klebinger at 2023-04-04T13:39:24+05:30 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- (cherry picked from commit 08ba87200ff068aa37cac082e61ee7e2d534daf5) (cherry picked from commit 96ab827a0d1ffd81bd906262b42409f2df808375) - - - - - e7d033c1 by sheaf at 2023-04-04T13:39:24+05:30 RTS: declare setKeepCAFs symbol Commit 08ba8720 failed to declare the dependency of keepCAFsForGHCi on the symbol setKeepCAFs in the RTS, which led to undefined symbol errors on Windows, as exhibited by the testcase frontend001. Thanks to Moritz Angermann and Ryan Scott for the diagnosis and fix. Fixes #22961 (cherry picked from commit cf564dd71548771394249e9bf959512a21bbcec0) (cherry picked from commit c17668466a404de8a7fc5ef5b2931790da9440b6) - - - - - 7d8cc70a by Simon Peyton Jones at 2023-04-11T10:21:53+05:30 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 (cherry picked from commit 3d55d8ab51ece43c51055c43c9e7aba77cce46c0) - - - - - c85909e5 by Simon Peyton Jones at 2023-04-11T10:21:53+05:30 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. (cherry picked from commit e193e53790dd5886feea3cf4c9c17625d188291b) - - - - - fdb6437f by Simon Peyton Jones at 2023-04-11T10:52:18+05:30 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 (cherry picked from commit 317f45c154f6fe25d50ef2f3febcc5883ff1b1ca) - - - - - 8cedbeb4 by Matthew Pickering at 2023-04-11T10:52:18+05:30 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s (cherry picked from commit a960ca817d6ad0109ea6edda50da3902cc538e86) - - - - - f0a2bbfb by Matthew Pickering at 2023-04-11T10:52:18+05:30 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. (cherry picked from commit 734847108420cf826a807c30ad54651659cf3a08) - - - - - 58250d83 by Matthew Pickering at 2023-04-11T10:52:18+05:30 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes (cherry picked from commit 8c0ea25fb4a27d4729aabf73f4c00b912bb0c58d) - - - - - 7d4d5b55 by Sebastian Graf at 2023-04-11T10:52:18+05:30 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite (cherry picked from commit e3fff7512bbf989386faaa1dccafdad1deabde84) - - - - - 76c31152 by Oleg Grenrus at 2023-04-11T10:52:18+05:30 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general (cherry picked from commit 1b812b6973a25cb1962e2fc543d2c4ed3cf31f3c) - - - - - a8eb6148 by Viktor Dukhovni at 2023-04-11T10:52:18+05:30 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 (cherry picked from commit fc02f3bbb5f47f880465e22999ba9794f658d8f6) - - - - - 52661e3d by Ryan Scott at 2023-04-11T10:52:18+05:30 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. (cherry picked from commit 4efee43db5090aac4dde1293357bdb548ae71c24) - - - - - dc916697 by Cheng Shao at 2023-04-11T10:52:18+05:30 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. (cherry picked from commit c45a5fffef2c76efbf5d3a009c3f6d0244a63f0d) - - - - - 1f8747ca by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. (cherry picked from commit be417a47c7695998dea0adc05489a7b8838a78b6) - - - - - b72cb3ac by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. (cherry picked from commit 30989d137b8f3a8fddbfd116e04b48f23c24f86c) - - - - - a15b863c by Ben Gamari at 2023-04-11T10:52:18+05:30 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. (cherry picked from commit 7566fd9de38c67360c090f828923d41587af519c) - - - - - 71e7be37 by Ben Gamari at 2023-04-11T10:52:18+05:30 testsuite: Add regression test for #22798 (cherry picked from commit 2cb500a5ee1a31dfe1a2cdd71f175442026eb082) - - - - - de3491f7 by Zubin Duggal at 2023-04-11T10:52:19+05:30 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 (cherry picked from commit 68dd64ffa6f164dce4ac010b9f5e1adfefeae7c7) - - - - - 770a9a00 by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. (cherry picked from commit 8bed166bb79445f90015757fd5baac69a7b835df) - - - - - d6a51cd1 by Zubin Duggal at 2023-04-11T10:52:19+05:30 bindist configure: Fail if find not found (#22691) (cherry picked from commit c9967d137cff83c7688e26f87a8b5e196a75ec93) - - - - - 4419309d by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. (cherry picked from commit 35a118001149eb8f5bab989be997757baa70bfec) - - - - - ea9ecc40 by sheaf at 2023-04-11T10:52:19+05:30 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 (cherry picked from commit 9ee761bf02cdd11c955454a222c85971d95dce11) - - - - - 12b45b4a by Andreas Klebinger at 2023-04-11T10:52:19+05:30 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 (cherry picked from commit 9296660b131d42f1b1f9c421040c5746d5c56989) - - - - - 4e5fd92b by Matthew Pickering at 2023-04-11T10:52:19+05:30 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 (cherry picked from commit a86aae8b562c12bb3cee8dcae5156b647f1a74ad) - - - - - 8f819453 by Sylvain Henry at 2023-04-11T10:52:19+05:30 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). (cherry picked from commit 4158722a6cff5d19e228356c525946b6c4b83396) - - - - - 82637685 by Ben Gamari at 2023-04-11T10:52:19+05:30 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. (cherry picked from commit b8d783d24b9a617ad1e3038abeb75d322703ef65) - - - - - 5a278522 by Matthew Pickering at 2023-04-11T16:44:41+05:30 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 (cherry picked from commit 32b32d7fbc5544ad6c435a1ea26e6353ec567a9b) - - - - - b43896ea by Matthew Pickering at 2023-04-11T16:44:41+05:30 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 (cherry picked from commit 1d1dd3fbfafdb9705076d4c587d5cf47e33b7640) - - - - - 59214122 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 (cherry picked from commit 7bfb30f92f5e21a8aca58068dc970040130433c6) - - - - - e6ec408e by Matthew Pickering at 2023-04-11T16:44:41+05:30 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 (cherry picked from commit 69500dd4a6dc81fa6fee6f24f0fe08a07b6112fc) - - - - - 52be078b by Matthew Pickering at 2023-04-11T16:44:41+05:30 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 (cherry picked from commit 336b2b1c8628b1317de46078e049b529205f2129) - - - - - 54010624 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 (cherry picked from commit 6469fea7c78408db679898168a8e9c50c8c7c5ce) - - - - - 64a60b3d by Matthew Pickering at 2023-04-11T16:44:41+05:30 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 (cherry picked from commit 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9) - - - - - 429c8d2d by Matthew Pickering at 2023-04-11T16:44:41+05:30 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 (cherry picked from commit 4fe9eaff11ccf1fe185de2918aef4f96fd200c72) - - - - - babd33d9 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p (cherry picked from commit ada29f5ca5a567b69713f08feac9ee4f247de117) - - - - - 3b0d9f8c by Matthew Pickering at 2023-04-11T16:44:41+05:30 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. (cherry picked from commit be701cc64f0ff78aa50bcd7293d8692dc1ba6c85) - - - - - 375fae2f by Simon Peyton Jones at 2023-04-11T16:44:41+05:30 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. (cherry picked from commit 496607fdb77baf12e2fe263104ba5d0d700eee3b) - - - - - f2f46364 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 (cherry picked from commit ac39e8e97fbb69e4a786c1c29d6e477e7944f998) - - - - - b22e4bda by Matthew Pickering at 2023-04-11T16:44:41+05:30 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 (cherry picked from commit 1262d3f8c03799a04d3c5fcf33d4d4db715ca9a1) - - - - - d3768c41 by Matthew Pickering at 2023-04-11T16:44:41+05:30 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 (cherry picked from commit e27eb80cc7e0c82e07fbd8d9ae8112d9070c4355) - - - - - b7ebc474 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 (cherry picked from commit 3d004d5a961fbbbe11da1050b725468a970bee4b) - - - - - 744464c3 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 (cherry picked from commit f2a0fea09a88693d876fb891ea7c8c97373c4aa6) - - - - - 53c4d24f by Krzysztof Gogolewski at 2023-04-11T16:44:42+05:30 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). (cherry picked from commit 7c16f3be6e1ac92f87d752f12ad6c6e7b7fd6207) - - - - - bbfe16dc by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. (cherry picked from commit a3a8e9e968ff9b10c6785d53a5f1c8fcef6db72b) - - - - - dd847c14 by sheaf at 2023-04-11T16:44:42+05:30 Hadrian: merge archives even in stage 0 We now always merge .a archives when ar supports -L. This change is necessary in order to bootstrap GHC using GHC 9.4 on Windows, as nested archives aren't supported. Not doing so triggered bug #21990 when trying to use the Win32 package, with errors such as: Not a x86_64 PE+ file. Unknown COFF 4 type in getHeaderInfo. ld.lld: error: undefined symbol: Win32zm2zi12zi0zi0_SystemziWin32ziConsoleziCtrlHandler_withConsoleCtrlHandler1_info We have to be careful about which ar is meant: in stage 0, the check should be done on the system ar (system-ar in system.config). (cherry picked from commit 545ff490144ed3ddd596d2a0c01b0a16b5528f63) - - - - - 3247e44a by Sylvain Henry at 2023-04-11T16:44:42+05:30 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. (cherry picked from commit e987e345c807035e4637ca3eae227ae501e16c42) - - - - - 35b059d8 by Sylvain Henry at 2023-04-11T16:44:42+05:30 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. (cherry picked from commit 48131ee2d8ba7074a4c2763a32c12df105305a75) - - - - - 9e07003f by Sylvain Henry at 2023-04-11T16:44:42+05:30 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. (cherry picked from commit 288fa0179a2f54e4594afe184eac71cc85c46643) - - - - - 69ab7f35 by Sylvain Henry at 2023-04-11T16:44:42+05:30 configure: support "windows" as an OS (cherry picked from commit 2fdf22aebda2307d86872c792633d1856d666c9b) - - - - - 5e102834 by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. (cherry picked from commit b3eacd64fb36724ed6c5d2d24a81211a161abef1) - - - - - ddf602f0 by Ben Gamari at 2023-04-11T16:44:42+05:30 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. (cherry picked from commit 9ffd5d57a7cc19bcd6ea0139b00c77639566ba82) - - - - - 60372935 by Ben Gamari at 2023-04-11T16:44:42+05:30 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. (cherry picked from commit f891a442046d8a5ebf4d4777847880ce06752b18) - - - - - 5d036a5a by Ben Gamari at 2023-04-11T16:44:42+05:30 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. (cherry picked from commit b13c6ea5d4b64841164f8cc58d6c6f3de390f2ed) - - - - - 98b09661 by Li-yao Xia at 2023-04-11T16:44:42+05:30 base: Move changelog entry to its place (cherry picked from commit 11de324aae17794c8753a8f7cb50c4140785fe27) - - - - - 850c5ad3 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. (cherry picked from commit d97354a82b6f79c4d9a4d389fafdd94375454f59) - - - - - b9d38595 by Matthew Pickering at 2023-04-11T16:44:42+05:30 Backport fix to #23184 to 9.4 This backports the fix suggested in #23184 to GHC-9.4 It is from the larger patch (!7861): ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` (cherry picked from commit d2dee3f82dcfdfc49cfb708222bb78aea0713cd6) - - - - - 7d9de292 by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. (cherry picked from commit c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60) - - - - - b64260bc by Ben Gamari at 2023-04-11T16:44:42+05:30 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. (cherry picked from commit c32abd4b936b3dfc61974ed5915c330fe7ed10d5) - - - - - 55392bee by Ben Gamari at 2023-04-11T16:44:42+05:30 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 (cherry picked from commit d1bb16ed3e18a4f41fcfe31f0bf57dbaf589d6c5) - - - - - 98f45e6f by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise (cherry picked from commit 7192ef91c855e1fae6997f75cfde76aafd0b4bcf) - - - - - 29236f70 by Simon Peyton Jones at 2023-04-11T16:44:42+05:30 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 (cherry picked from commit 6206cb9287f3f6e70c669660a646a65274870d2b) - - - - - 602bc279 by Simon Peyton Jones at 2023-04-11T16:44:43+05:30 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. (cherry picked from commit 964284fcab6e27fe2fa5c279ea008551cbc15dbb) - - - - - 9de197b8 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. (cherry picked from commit db83f8bbf2e0ac68df675dea6b716fb7c19c649a) - - - - - 36611c83 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. (cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a) - - - - - 874d956b by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Introduce stgMallocAlignedBytes (cherry picked from commit 5f7a4a6d8311d2faa9c90b2b0c4431dd4427839d) - - - - - 00797e00 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. (cherry picked from commit 8a6f745d963fc9b79c7b1e4b477f4fc724233655) - - - - - 69644eb3 by Ben Gamari at 2023-04-11T16:44:43+05:30 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. (cherry picked from commit 5464c73f192f76e75160e8992fe9720d943ae611) - - - - - ece2324c by Andreas Klebinger at 2023-04-11T16:44:43+05:30 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. (cherry picked from commit a1491c8791c57a64d94bc08d639d585815c8d4e2) - - - - - c6b63a85 by Ryan Scott at 2023-04-11T16:44:43+05:30 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` (cherry picked from commit de1d15127ac3f41ac3044215b0ea3398a36edc89) - - - - - a86389fa by Zubin Duggal at 2023-04-12T11:03:47+05:30 base: Remove HAVE_* CPP guards - - - - - 19ed0ca7 by Tamar Christina at 2023-04-12T11:03:47+05:30 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. (cherry picked from commit 48e391952c17ff7eab10b0b1456e3f2a2af28a9b) - - - - - 686c30f6 by Ben Gamari at 2023-04-12T11:03:48+05:30 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - c243cbdd by Zubin Duggal at 2023-04-12T11:03:48+05:30 lint-notes: accept output - - - - - 013436a2 by Ben Gamari at 2023-04-12T11:03:48+05:30 hadrian: Extend xattr Darwin hack to cover /lib As noted in #21506, it is now necessary to remove extended attributes from `/lib` as well as `/bin` to avoid SIP issues on Darwin. Fixes #21506. (cherry picked from commit 78d04cfadfd728bb088b08b1e88905b43cc0360c) - - - - - 0bc34bd0 by Zubin Duggal at 2023-04-14T13:07:37+05:30 Bump submodules: text, parsec, bytestring, containers - - - - - 40bf9669 by Zubin Duggal at 2023-04-14T13:07:37+05:30 Bump base to 4.17.1.0 and add release notes - - - - - 8244cdcf by Zubin Duggal at 2023-04-14T13:07:37+05:30 Allow LLVM 14 - - - - - 083017b9 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. (cherry picked from commit 605d954722a314c0da59ea07efc26d8a7cb59296) - - - - - c192ecd0 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. (cherry picked from commit 86f20258ab7dbfb56e323ee811e9eaef80b077d3) - - - - - 509c30d2 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. (cherry picked from commit f8e901dcc090ef81723fb9f3d8ea0a1baac4cbc3) - - - - - 1717f212 by Ben Gamari at 2023-04-14T13:07:37+05:30 rts: Encapsulate access to capabilities array (cherry picked from commit e0affaa9fc3e6dc0e65808afa383426b7fe9420a) - - - - - 2d6d6fdd by Ben Gamari at 2023-04-14T13:07:38+05:30 rts: Encapsulate sched_state (cherry picked from commit 7ca683e44f9f7a9a7984bbed4f49712838638fc8) - - - - - 76508973 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. (cherry picked from commit 2d71481ad481e6887e2ee342910b1495d53e6e4a) - - - - - de27e933 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix segment list races (cherry picked from commit d92b5bf5ca90fb126321224f28096224bce87539) - - - - - 1405f97a by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. (cherry picked from commit 0b0d924edcf7631ed1afc88d614849558fa8fa7f) - - - - - d01a6ea7 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. (cherry picked from commit 9a9874d2d96acdcd9daddb7aceaa7951153f6ac0) - - - - - ec088ed3 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Ensure that mutable fields have acquire barrier (cherry picked from commit d6990e6789efeb091c51c50580b68ea1bd997d00) - - - - - fe5c048b by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. (cherry picked from commit 83c2876d3783ac2f4ea969c9e01d15198aea03a3) - - - - - 6326b966 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make segment state updates atomic (cherry picked from commit 377697ea4d44023e0c690d722e1e27f03629227f) - - - - - d3404b5a by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. (cherry picked from commit c96fc9d52e138b89a85f8df8f722140f874bcede) - - - - - 9c77c4b9 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. (cherry picked from commit 71aea6d3160e1389c38bb94c281bd7c30a030147) - - - - - b96e007c by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. (cherry picked from commit 2d10d8dfdff1212286490c2c19b8f725ce501b10) - - - - - d29d4837 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. (cherry picked from commit 7570ae43218fbdee30f783af5a3f49fa3d8301e3) - - - - - 6d1d5e84 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. (cherry picked from commit b6a3ab00712ca40acd1d91ba910e18c972a345a8) - - - - - e07c917c by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). (cherry picked from commit 5a40353566516d7ba8b1db6877f8c3aba06e64aa) - - - - - d8c99faa by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Fix style (cherry picked from commit 1ca730ce410007781489821188ea8c1ca85f78f9) - - - - - f521c304 by Ben Gamari at 2023-04-14T13:07:38+05:30 nonmoving: Deduplicate assertion (cherry picked from commit 1cc4bd7a169c6d813330d3613836889568515000) - - - - - f59ee743 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. (cherry picked from commit 8623ab4bd7fb1326cebb3191fdee841af74bb345) - - - - - 66c32a26 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. (cherry picked from commit 3072bef55dc6e123e7eb84bb9154a13db4d043da) - - - - - a7be6c65 by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/Sanity: Mark pinned_object_blocks (cherry picked from commit 3223048a1ee73384010aa20be548bad95ef1744a) - - - - - 70a8ca3f by Ben Gamari at 2023-04-14T13:07:38+05:30 rts/Sanity: Look at nonmoving saved_filled lists (cherry picked from commit ce4cf9d59552b52ae3d4c1c1e71a83296f022c27) - - - - - 19db4bf7 by Ben Gamari at 2023-04-14T13:07:38+05:30 Evac: Squash data race in eval_selector_chain (cherry picked from commit 9ce9fba46bf3fe1af4ce39dba4276bb241f3ea29) - - - - - 1a6716be by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. (cherry picked from commit ba3c7b67bd74906de63b3988b18a14b01861d3c9) - - - - - fb9caa54 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Clarify comment (cherry picked from commit 883d00f9cfffe3bd451f7302116eb29ce836c600) - - - - - ecf80b17 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Add missing no-op in busy-wait loop (cherry picked from commit ed5443ec9195f27522abf4b2882dbc6b6a9f17f5) - - - - - 64f05017 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. (cherry picked from commit 244640a067c0158db5f14f133212caa1a830030e) - - - - - dbf32a81 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. (cherry picked from commit 683e0c7aef2bbfedbee02c8fa32789e32c89a4db) - - - - - 77ddce65 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sanity check nonmoving large objects and compacts (cherry picked from commit 90e240045c1ac5047f4038bbeed6d2b71b20bc77) - - - - - 162c3509 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. (cherry picked from commit 2f08265751c13f7bd0df1c46928fc09a064a8add) - - - - - a5fb1176 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't show occupancy if we didn't collect live words (cherry picked from commit 3288e96d4ffe8c5f70929c4fedbfef918148def1) - - - - - 986028e8 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. (cherry picked from commit 4392965d14920117db2cf4ce460dec6f094f6dfe) - - - - - 2c0ed71d by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Assert state of swept segments (cherry picked from commit d478ac18395962d33e14fc378ad9a424bdcd1496) - - - - - a6e08eff by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. (cherry picked from commit 3e47be7887b2df48d2ad50791a98131634d7e8ec) - - - - - ec8ae75e by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. (cherry picked from commit 7dc1679b133672029dd7afae834a7fc67265035c) - - - - - bdf67900 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. (cherry picked from commit bd80fcd18f7be5b9d445d80c828b1a734c0e5a3b) - - - - - 61e6b54d by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Post-sweep sanity checking (cherry picked from commit e941801a267a3b9d898b48d90737924a7b7e4da2) - - - - - 1f9376bc by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Avoid n_caps race (cherry picked from commit 68fa47f3f5d1c207bd9edd7206bcceb150377647) - - - - - 146530f0 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Don't push if nonmoving collector isn't enabled (cherry picked from commit b15c813717ab9797df7733575904a7131bc4044c) - - - - - ee3a6e37 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. (cherry picked from commit ca3bc40255ffadfd0df31ec3a6ec5df7ca7f663e) - - - - - c2b57cc8 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. (cherry picked from commit 023998885b16bea51c0c1cdceb3f0ef96dccd5e4) - - - - - 4f86e5d6 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Allow pinned gen0 objects to be WEAK keys (cherry picked from commit 0c6f15762d14ade2666d5ad7f665718b4a10f89e) - - - - - f0e75bc3 by Ben Gamari at 2023-04-14T13:07:39+05:30 rts: Reenable assertion (cherry picked from commit 5b60acba8d76ecc4d733043460972633b13eedb0) - - - - - 4fd491c1 by Ben Gamari at 2023-04-14T13:07:39+05:30 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. (cherry picked from commit f849374508432ce07c25db8848fbea0d71040038) - - - - - 890d0df6 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. (cherry picked from commit 43fda6487f729f8c627dbb2abbfc027444d54e52) - - - - - d616fef8 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. (cherry picked from commit a9062eaa577b3f1edf07908e57832524b5525d7d) - - - - - ca9068c0 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. (cherry picked from commit b284e1c1d1e8e2513a286e3bbc5f46d635b33dd8) - - - - - 4b6acb26 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. (cherry picked from commit 9c9899d5c99f09312a093b5cf99e5a0a9579bf3a) - - - - - f9b47bde by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Fix unregisterised build (cherry picked from commit f2ef2f5e7a01cf5ec97b751f344233a6a8b781ca) - - - - - a79e52cf by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Ensure that sanity checker accounts for saved_filled segments (cherry picked from commit 7cc7461c74bf78aca0987c8e8e0ec48297c28f2c) - - - - - 8a031eb8 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Move allocator into new source file (cherry picked from commit e6f7b809885609de9e647e7f96cc95929fde7a4a) - - - - - 1b294f15 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Split out nonmovingAllocateGC (cherry picked from commit cfc68b5c9ee9000010ccb2b7f1d346542df3b79f) - - - - - 4c855ce5 by Ben Gamari at 2023-04-14T13:07:40+05:30 testsuite: Mark ffi023 as broken due to #23089 (cherry picked from commit 600fdd58332e52ac1620178f4b4a296e131465a1) - - - - - 6a18fc31 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. (cherry picked from commit ac0240af44026b9fcc08b62beef696ce7ea50e53) - - - - - fa9c8e61 by Ben Gamari at 2023-04-14T13:07:40+05:30 nonmoving: Non-concurrent collection (cherry picked from commit be9b4ca4da78b10bc065957472ecf2c8ce7599a4) - - - - - b7a380d9 by Ben Gamari at 2023-04-14T13:07:40+05:30 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. (cherry picked from commit ec382ccc087015db3d8782d3079c757ef8f10e9b) - - - - - 70d9353f by Ben Gamari at 2023-04-14T13:07:40+05:30 contextswitch - - - - - b82c9613 by Ben Gamari at 2023-04-14T13:07:40+05:30 rts: Fix incorrect format specifier warnings - - - - - 11ac9861 by Zubin Duggal at 2023-04-14T13:07:40+05:30 compiler: Fix performance regression in backport of "Make FloatIn robust to shadowing" (6206cb9287f3f6e70c669660a646a65274870d2b) In 9.4, we have noFloatIntoArg :: CoreExprWithFVs' -> Type -> Bool noFloatIntoArg expr expr_ty = ... But in master when 6206cb92 landed, after "Drop the app invariant" (dcf30da8) we had noFloatIntoArg :: CoreExprWithFVs' -> Bool noFloatIntoArg expr = ... When deciding whether to float things into the argument of a function, in 9.4 we must know the type of the argument. This was previously done by extracting the type of the argument from the function type, computed as we walked through all the arguments. However, this backport regressed compile time performance due to allocations by `exprType` particularly in T16577 and T5642, where it turns out that computing the type of the arguments to a function is quite expensive. Instead, we can compute the type of the argument by looking at the argument term directly, which turns out to be much faster and eliminates the performance regression. - - - - - 0a6f2a0d by Teo Camarasu at 2023-04-14T13:08:15+05:30 Add regression test for #17574 This test currently fails in the nonmoving way (cherry picked from commit a56141a69842a78d56ec11be85a775eb703219bf) - - - - - 9a85b847 by Teo Camarasu at 2023-04-14T13:08:15+05:30 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 (cherry picked from commit 20c6669fc46c567e00d3cdf22aa84479b6d8dc17) - - - - - 2058c8ef by Teo Camarasu at 2023-04-14T13:08:15+05:30 Allow running memInventory when the concurrent nonmoving gc is enabled If the nonmoving gc is enabled and we are using a threaded RTS, we now try to grab the collector mutex to avoid memInventory and the collection racing. Before memInventory was disabled. (cherry picked from commit 62c3f7ee4199305cde009ededeae6ece1bcde7f0) (cherry picked from commit fabc5a1c9aa468e97429ca5f8e501ec4fbd1084f) - - - - - 8b5d4df0 by Matthew Pickering at 2023-04-15T17:12:01+05:30 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 8608657c by Matthew Pickering at 2023-04-15T17:12:01+05:30 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 (cherry picked from commit 64286132cc0db4e227637887f98f5a3ecf7d326a) (cherry picked from commit 48a9e688331fbc2ac91392c654bb7457c5f8a876) - - - - - 768caef1 by Matthew Pickering at 2023-04-15T17:12:02+05:30 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 (cherry picked from commit 926cd4ee097106cf9c6d1ae1fc32375e7fc45ff2) - - - - - 403470cf by Zubin Duggal at 2023-04-15T17:12:02+05:30 Prepare release 9.4.5 Metric Decrease: T13035 T15164 T1969 T9961 WWRec T12707 T13379 Metric Increase: T17123 - - - - - a213d367 by Zubin Duggal at 2023-04-16T15:11:30+05:30 ci: lint-ci-config: regenerate cabal.config - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/darwin/toolchain.nix - .gitlab/generate_jobs - compiler/GHC.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Usage.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bc7b1b26d3267644e6ec9d17879d2e803397c704...a213d3676550a0e4d542172de539c0cfa2662431 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bc7b1b26d3267644e6ec9d17879d2e803397c704...a213d3676550a0e4d542172de539c0cfa2662431 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 17:41:48 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 13:41:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Show an error when we cannot default a concrete tyvar Message-ID: <643c335c954d3_10a80d6835e694811497@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 55b1afd4 by Simon Peyton Jones at 2023-04-16T13:41:31-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - 2c2f984f by Oleg Grenrus at 2023-04-16T13:41:37-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 22 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyPatBind.stderr - + testsuite/tests/rep-poly/T23153.hs - + testsuite/tests/rep-poly/T23153.stderr - + testsuite/tests/rep-poly/T23154.hs - + testsuite/tests/rep-poly/T23154.stderr - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_fail/VtaFail.stderr Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings ===================================== compiler/GHC/Driver/Errors/Types.hs ===================================== @@ -25,7 +25,8 @@ import GHC.Prelude import Data.Bifunctor import Data.Typeable -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, PackageArg, gopt) +import GHC.Driver.Flags (GeneralFlag (Opt_BuildingCabalPackage)) import GHC.Types.Error import GHC.Unit.Module import GHC.Unit.State ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name, dataName) -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) import qualified GHC.LanguageExtensions as LangExt import Data.Data ===================================== compiler/GHC/HsToCore/Errors/Types.hs ===================================== @@ -9,7 +9,8 @@ import GHC.Prelude import GHC.Core (CoreRule, CoreExpr, RuleName) import GHC.Core.DataCon import GHC.Core.Type -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) +import GHC.Driver.Flags (WarningFlag) import GHC.Hs import GHC.HsToCore.Pmc.Solver.Types import GHC.Types.Basic (Activation) ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1728,6 +1728,11 @@ instance Diagnostic TcRnMessage where in ppr (getSrcSpan n) <> colon <+> ppr (tyConName tc) <+> text "from external module" + TcRnCannotDefaultConcrete frr + -> mkSimpleDecorated $ + ppr (frr_context frr) $$ + text "cannot be assigned a fixed runtime representation," <+> + text "not even by defaulting." diagnosticReason = \case TcRnUnknownMessage m @@ -2300,6 +2305,8 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnTypeSynonymCycle{} -> ErrorWithoutFlag + TcRnCannotDefaultConcrete{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -2899,6 +2906,8 @@ instance Diagnostic TcRnMessage where -> [suggestExtension LangExt.DataKinds] TcRnTypeSynonymCycle{} -> noHints + TcRnCannotDefaultConcrete{} + -> [SuggestAddTypeSignatures UnnamedBinding] diagnosticCode = constructorCode ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -3473,6 +3473,15 @@ data TcRnMessage where -> ![LIdP GhcRn] -- ^ The LHS args -> !PatSynInvalidRhsReason -- ^ The number of equation arguments -> TcRnMessage + {-| TcRnCannotDefaultConcrete is an error occurring when a concrete + type variable cannot be defaulted. + + Test cases: + T23153 + -} + TcRnCannotDefaultConcrete + :: !FixedRuntimeRepOrigin + -> TcRnMessage {-| TcRnMultiAssocTyFamDefaults is an error indicating that multiple default declarations were specified for an associated type family. ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -883,7 +883,7 @@ tcExprWithSig expr hs_ty loc = getLocA (dropWildCards hs_ty) ctxt = ExprSigCtxt (lhsSigWcTypeContextSpan hs_ty) -tcExprSig :: UserTypeCtxt -> LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcType) +tcExprSig :: UserTypeCtxt -> LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcSigmaType) tcExprSig ctxt expr (CompleteSig { sig_bndr = poly_id, sig_loc = loc }) = setSrcSpan loc $ -- Sets the location for the implication constraint do { let poly_ty = idType poly_id ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2119,14 +2119,17 @@ checkTouchableTyVarEq ev lhs_tv rhs ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else - do { let tv_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = TauTv - -- Make a concrete tyvar if lhs_tv is concrete - -- e.g. alpha[2,conc] ~ Maybe (F beta[4]) - -- We want to flatten to - -- alpha[2,conc] ~ Maybe gamma[2,conc] - -- gamma[2,conc] ~ F beta[4] - ; new_tv_ty <- TcM.newMetaTyVarTyWithInfo lhs_tv_lvl tv_info fam_app_kind + do { new_tv_ty <- + case lhs_tv_info of + ConcreteTv conc_info -> + -- Make a concrete tyvar if lhs_tv is concrete + -- e.g. alpha[2,conc] ~ Maybe (F beta[4]) + -- We want to flatten to + -- alpha[2,conc] ~ Maybe gamma[2,conc] + -- gamma[2,conc] ~ F beta[4] + TcM.newConcreteTyVarTyAtLevel conc_info lhs_tv_lvl fam_app_kind + _ -> TcM.newMetaTyVarTyAtLevel lhs_tv_lvl fam_app_kind + ; let pty = mkPrimEqPredRole Nominal fam_app new_tv_ty ; hole <- TcM.newCoercionHole pty ; let new_ev = CtWanted { ctev_pred = pty ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -117,7 +117,7 @@ import GHC.Core import GHC.Core.TyCo.Ppr import GHC.Utils.FV import GHC.Types.Var.Set -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags(reductionDepth)) import GHC.Types.Basic import GHC.Types.Unique import GHC.Types.Unique.Set ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -8,9 +8,6 @@ module GHC.Tc.Utils.Concrete ( -- * Ensuring that a type has a fixed runtime representation hasFixedRuntimeRep , hasFixedRuntimeRep_syntactic - - -- * Making a type concrete - , makeTypeConcrete ) where ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE RecursiveDo #-} {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -24,7 +25,7 @@ module GHC.Tc.Utils.TcMType ( newOpenFlexiTyVar, newOpenFlexiTyVarTy, newOpenTypeKind, newOpenBoxedTypeKind, newMetaKindVar, newMetaKindVars, - newMetaTyVarTyAtLevel, newMetaTyVarTyWithInfo, + newMetaTyVarTyAtLevel, newConcreteTyVarTyAtLevel, newAnonMetaTyVar, newConcreteTyVar, cloneMetaTyVar, cloneMetaTyVarWithInfo, newCycleBreakerTyVar, @@ -482,7 +483,16 @@ newInferExpType :: TcM ExpType newInferExpType = new_inferExpType Nothing newInferExpTypeFRR :: FixedRuntimeRepContext -> TcM ExpTypeFRR -newInferExpTypeFRR frr_orig = new_inferExpType (Just frr_orig) +newInferExpTypeFRR frr_orig + = do { th_stage <- getStage + ; if + -- See [Wrinkle: Typed Template Haskell] + -- in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete. + | Brack _ (TcPending {}) <- th_stage + -> new_inferExpType Nothing + + | otherwise + -> new_inferExpType (Just frr_orig) } new_inferExpType :: Maybe FixedRuntimeRepContext -> TcM ExpType new_inferExpType mb_frr_orig @@ -538,20 +548,28 @@ expTypeToType (Infer inf_res) = inferResultToType inf_res inferResultToType :: InferResult -> TcM Type inferResultToType (IR { ir_uniq = u, ir_lvl = tc_lvl - , ir_ref = ref }) + , ir_ref = ref + , ir_frr = mb_frr }) = do { mb_inferred_ty <- readTcRef ref ; tau <- case mb_inferred_ty of Just ty -> do { ensureMonoType ty -- See Note [inferResultToType] ; return ty } - Nothing -> do { rr <- newMetaTyVarTyAtLevel tc_lvl runtimeRepTy - ; tau <- newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) - -- See Note [TcLevel of ExpType] + Nothing -> do { tau <- new_meta ; writeMutVar ref (Just tau) ; return tau } ; traceTc "Forcing ExpType to be monomorphic:" (ppr u <+> text ":=" <+> ppr tau) ; return tau } + where + -- See Note [TcLevel of ExpType] + new_meta = case mb_frr of + Nothing -> do { rr <- newMetaTyVarTyAtLevel tc_lvl runtimeRepTy + ; newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) } + Just frr -> mdo { rr <- newConcreteTyVarTyAtLevel conc_orig tc_lvl runtimeRepTy + ; tau <- newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) + ; let conc_orig = ConcreteFRR $ FixedRuntimeRepOrigin tau frr + ; return tau } {- Note [inferResultToType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -874,6 +892,13 @@ newTauTvDetailsAtLevel tclvl , mtv_ref = ref , mtv_tclvl = tclvl }) } +newConcreteTvDetailsAtLevel :: ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails +newConcreteTvDetailsAtLevel conc_orig tclvl + = do { ref <- newMutVar Flexi + ; return (MetaTv { mtv_info = ConcreteTv conc_orig + , mtv_ref = ref + , mtv_tclvl = tclvl }) } + cloneMetaTyVar :: TcTyVar -> TcM TcTyVar cloneMetaTyVar tv = assert (isTcTyVar tv) $ @@ -931,7 +956,7 @@ isUnfilledMetaTyVar tv -------------------- -- Works with both type and kind variables -writeMetaTyVar :: TcTyVar -> TcType -> TcM () +writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM () -- Write into a currently-empty MetaTyVar writeMetaTyVar tyvar ty @@ -949,7 +974,7 @@ writeMetaTyVar tyvar ty = massertPpr False (text "Writing to non-meta tyvar" <+> ppr tyvar) -------------------- -writeMetaTyVarRef :: TcTyVar -> TcRef MetaDetails -> TcType -> TcM () +writeMetaTyVarRef :: HasDebugCallStack => TcTyVar -> TcRef MetaDetails -> TcType -> TcM () -- Here the tyvar is for error checking only; -- the ref cell must be for the same tyvar writeMetaTyVarRef tyvar ref ty @@ -1114,13 +1139,10 @@ newMetaTyVarTyAtLevel tc_lvl kind ; name <- newMetaTyVarName (fsLit "p") ; return (mkTyVarTy (mkTcTyVar name kind details)) } -newMetaTyVarTyWithInfo :: TcLevel -> MetaInfo -> TcKind -> TcM TcType -newMetaTyVarTyWithInfo tc_lvl info kind - = do { ref <- newMutVar Flexi - ; let details = MetaTv { mtv_info = info - , mtv_ref = ref - , mtv_tclvl = tc_lvl } - ; name <- newMetaTyVarName (fsLit "p") +newConcreteTyVarTyAtLevel :: ConcreteTvOrigin -> TcLevel -> TcKind -> TcM TcType +newConcreteTyVarTyAtLevel conc_orig tc_lvl kind + = do { details <- newConcreteTvDetailsAtLevel conc_orig tc_lvl + ; name <- newMetaTyVarName (fsLit "c") ; return (mkTyVarTy (mkTcTyVar name kind details)) } {- ********************************************************************* @@ -2258,7 +2280,7 @@ a \/\a in the final result but all the occurrences of a will be zonked to () * * ********************************************************************* -} -promoteMetaTyVarTo :: TcLevel -> TcTyVar -> TcM Bool +promoteMetaTyVarTo :: HasDebugCallStack => TcLevel -> TcTyVar -> TcM Bool -- When we float a constraint out of an implication we must restore -- invariant (WantedInv) in Note [TcLevel invariants] in GHC.Tc.Utils.TcType -- Return True <=> we did some promotion @@ -2276,7 +2298,7 @@ promoteMetaTyVarTo tclvl tv = return False -- Returns whether or not *any* tyvar is defaulted -promoteTyVarSet :: TcTyVarSet -> TcM Bool +promoteTyVarSet :: HasDebugCallStack => TcTyVarSet -> TcM Bool promoteTyVarSet tvs = do { tclvl <- getTcLevel ; bools <- mapM (promoteMetaTyVarTo tclvl) $ ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -56,6 +56,7 @@ import GHC.Tc.Utils.TcType import GHC.Tc.Utils.TcMType import GHC.Tc.Utils.Env ( tcLookupGlobalOnly ) import GHC.Tc.Types.Evidence +import GHC.Tc.Errors.Types import GHC.Core.TyCo.Ppr ( pprTyVar ) import GHC.Core.TyCon @@ -1737,7 +1738,7 @@ change. But in some cases it makes a HUGE difference: see test T9198 and #19668. So yes, it seems worth it. -} -zonkTyVarOcc :: ZonkEnv -> TcTyVar -> TcM Type +zonkTyVarOcc :: HasDebugCallStack => ZonkEnv -> TcTyVar -> TcM Type zonkTyVarOcc env@(ZonkEnv { ze_flexi = flexi , ze_tv_env = tv_env , ze_meta_tv_env = mtv_env_ref }) tv @@ -1810,6 +1811,9 @@ commitFlexi flexi tv zonked_kind | isMultiplicityTy zonked_kind -> do { traceTc "Defaulting flexi tyvar to Many:" (pprTyVar tv) ; return manyDataConTy } + | Just (ConcreteFRR origin) <- isConcreteTyVar_maybe tv + -> do { addErr $ TcRnCannotDefaultConcrete origin + ; return (anyTypeOfKind zonked_kind) } | otherwise -> do { traceTc "Defaulting flexi tyvar to Any:" (pprTyVar tv) ; return (anyTypeOfKind zonked_kind) } ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -480,8 +480,6 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalHsigDefaultMethods" = 93006 GhcDiagnosticCode "TcRnHsigFixityMismatch" = 93007 - GhcDiagnosticCode "HsigShapeSortMismatch" = 93008 - GhcDiagnosticCode "HsigShapeNotUnifiable" = 93009 GhcDiagnosticCode "TcRnHsigNoIface" = 93010 GhcDiagnosticCode "TcRnHsigMissingModuleExport" = 93011 GhcDiagnosticCode "TcRnBadGenericMethod" = 59794 @@ -551,8 +549,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnPatSynEscapedCoercion" = 88986 GhcDiagnosticCode "TcRnPatSynExistentialInResult" = 33973 GhcDiagnosticCode "TcRnPatSynArityMismatch" = 18365 - GhcDiagnosticCode "PatSynNotInvertible" = 69317 - GhcDiagnosticCode "PatSynUnboundVar" = 28572 + GhcDiagnosticCode "TcRnCannotDefaultConcrete" = 52083 GhcDiagnosticCode "TcRnMultiAssocTyFamDefaults" = 59128 GhcDiagnosticCode "TcRnTyFamDepsDisabled" = 43991 GhcDiagnosticCode "TcRnAbstractClosedTyFamDecl" = 60012 @@ -580,6 +577,10 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnTyFamNameMismatch" = 88221 GhcDiagnosticCode "TcRnTypeSynonymCycle" = 97522 + -- PatSynInvalidRhsReason + GhcDiagnosticCode "PatSynNotInvertible" = 69317 + GhcDiagnosticCode "PatSynUnboundVar" = 28572 + -- TcRnBadFieldAnnotation/BadFieldAnnotationReason GhcDiagnosticCode "LazyFieldsDisabled" = 81601 GhcDiagnosticCode "UnpackWithoutStrictness" = 10107 @@ -601,6 +602,10 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnPrecedenceParsingError" = 88747 GhcDiagnosticCode "TcRnSectionPrecedenceError" = 46878 + -- HsigShapeMismatchReason + GhcDiagnosticCode "HsigShapeSortMismatch" = 93008 + GhcDiagnosticCode "HsigShapeNotUnifiable" = 93009 + -- IllegalNewtypeReason GhcDiagnosticCode "DoesNotHaveSingleField" = 23517 GhcDiagnosticCode "IsNonLinear" = 38291 ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -8,7 +8,7 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘p0’ + Cannot unify ‘R’ with the type variable ‘c0’ because it is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -4,7 +4,7 @@ RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘p0’ + Cannot unify ‘R’ with the type variable ‘c0’ because it is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T ===================================== testsuite/tests/rep-poly/RepPolyPatBind.stderr ===================================== @@ -1,4 +1,20 @@ +RepPolyPatBind.hs:18:5: error: [GHC-55287] + • The pattern binding does not have a fixed runtime representation. + Its type is: + p0 :: TYPE c0 + Cannot unify ‘TupleRep [rep, rep]’ with the type variable ‘c0’ + because it is not a concrete ‘RuntimeRep’. + • In the pattern: (# x, y #) + In a pattern binding: (# x, y #) = undefined + In the expression: + let + x, y :: a + (# x, y #) = undefined + in x + • Relevant bindings include + foo :: () -> a (bound at RepPolyPatBind.hs:15:1) + RepPolyPatBind.hs:18:5: error: [GHC-55287] • • The binder ‘y’ does not have a fixed runtime representation. Its type is: ===================================== testsuite/tests/rep-poly/T23153.hs ===================================== @@ -0,0 +1,8 @@ +module T23153 where + +import GHC.Exts + +f :: forall r s (a :: TYPE (r s)). a -> () +f = f + +g h = f (h ()) ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -0,0 +1,15 @@ + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. ===================================== testsuite/tests/rep-poly/T23154.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PartialTypeSignatures #-} + +module T23154 where + +import GHC.Exts + +f x = x :: (_ :: (TYPE (_ _))) ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -0,0 +1,10 @@ + +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -116,3 +116,5 @@ test('T21650_b', normal, compile_fail, ['-Wno-deprecated-flags']) ## test('T23051', normal, compile_fail, ['']) +test('T23153', normal, compile_fail, ['']) +test('T23154', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/VtaFail.stderr ===================================== @@ -7,7 +7,7 @@ VtaFail.hs:7:16: error: [GHC-95781] answer_nosig = pairup_nosig @Int @Bool 5 True VtaFail.hs:14:17: error: [GHC-95781] - • Cannot apply expression of type ‘p1 -> p1’ + • Cannot apply expression of type ‘p0 -> p0’ to a visible type argument ‘Int’ • In the expression: (\ x -> x) @Int 12 In an equation for ‘answer_lambda’: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f39dbaf6b11a82291ccdec4f627413376f296bba...2c2f984f56b5b3b38800b1c971aa1b45b0fb9814 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f39dbaf6b11a82291ccdec4f627413376f296bba...2c2f984f56b5b3b38800b1c971aa1b45b0fb9814 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 21:01:00 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 16 Apr 2023 17:01:00 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23199 Message-ID: <643c620cb5a5a_10a80d6b6771c08239f2@gitlab.mail> Simon Peyton Jones pushed new branch wip/T23199 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23199 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 22:12:08 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 18:12:08 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Show an error when we cannot default a concrete tyvar Message-ID: <643c72b85718a_10a80d6c856c888352e4@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 17 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Zonk.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyPatBind.stderr - + testsuite/tests/rep-poly/T23153.hs - + testsuite/tests/rep-poly/T23153.stderr - + testsuite/tests/rep-poly/T23154.hs - + testsuite/tests/rep-poly/T23154.stderr - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_fail/VtaFail.stderr Changes: ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1728,6 +1728,11 @@ instance Diagnostic TcRnMessage where in ppr (getSrcSpan n) <> colon <+> ppr (tyConName tc) <+> text "from external module" + TcRnCannotDefaultConcrete frr + -> mkSimpleDecorated $ + ppr (frr_context frr) $$ + text "cannot be assigned a fixed runtime representation," <+> + text "not even by defaulting." diagnosticReason = \case TcRnUnknownMessage m @@ -2300,6 +2305,8 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnTypeSynonymCycle{} -> ErrorWithoutFlag + TcRnCannotDefaultConcrete{} + -> ErrorWithoutFlag diagnosticHints = \case TcRnUnknownMessage m @@ -2899,6 +2906,8 @@ instance Diagnostic TcRnMessage where -> [suggestExtension LangExt.DataKinds] TcRnTypeSynonymCycle{} -> noHints + TcRnCannotDefaultConcrete{} + -> [SuggestAddTypeSignatures UnnamedBinding] diagnosticCode = constructorCode ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -3473,6 +3473,15 @@ data TcRnMessage where -> ![LIdP GhcRn] -- ^ The LHS args -> !PatSynInvalidRhsReason -- ^ The number of equation arguments -> TcRnMessage + {-| TcRnCannotDefaultConcrete is an error occurring when a concrete + type variable cannot be defaulted. + + Test cases: + T23153 + -} + TcRnCannotDefaultConcrete + :: !FixedRuntimeRepOrigin + -> TcRnMessage {-| TcRnMultiAssocTyFamDefaults is an error indicating that multiple default declarations were specified for an associated type family. ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -883,7 +883,7 @@ tcExprWithSig expr hs_ty loc = getLocA (dropWildCards hs_ty) ctxt = ExprSigCtxt (lhsSigWcTypeContextSpan hs_ty) -tcExprSig :: UserTypeCtxt -> LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcType) +tcExprSig :: UserTypeCtxt -> LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcSigmaType) tcExprSig ctxt expr (CompleteSig { sig_bndr = poly_id, sig_loc = loc }) = setSrcSpan loc $ -- Sets the location for the implication constraint do { let poly_ty = idType poly_id ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2119,14 +2119,17 @@ checkTouchableTyVarEq ev lhs_tv rhs ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else - do { let tv_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = TauTv - -- Make a concrete tyvar if lhs_tv is concrete - -- e.g. alpha[2,conc] ~ Maybe (F beta[4]) - -- We want to flatten to - -- alpha[2,conc] ~ Maybe gamma[2,conc] - -- gamma[2,conc] ~ F beta[4] - ; new_tv_ty <- TcM.newMetaTyVarTyWithInfo lhs_tv_lvl tv_info fam_app_kind + do { new_tv_ty <- + case lhs_tv_info of + ConcreteTv conc_info -> + -- Make a concrete tyvar if lhs_tv is concrete + -- e.g. alpha[2,conc] ~ Maybe (F beta[4]) + -- We want to flatten to + -- alpha[2,conc] ~ Maybe gamma[2,conc] + -- gamma[2,conc] ~ F beta[4] + TcM.newConcreteTyVarTyAtLevel conc_info lhs_tv_lvl fam_app_kind + _ -> TcM.newMetaTyVarTyAtLevel lhs_tv_lvl fam_app_kind + ; let pty = mkPrimEqPredRole Nominal fam_app new_tv_ty ; hole <- TcM.newCoercionHole pty ; let new_ev = CtWanted { ctev_pred = pty ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -8,9 +8,6 @@ module GHC.Tc.Utils.Concrete ( -- * Ensuring that a type has a fixed runtime representation hasFixedRuntimeRep , hasFixedRuntimeRep_syntactic - - -- * Making a type concrete - , makeTypeConcrete ) where ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE RecursiveDo #-} {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -24,7 +25,7 @@ module GHC.Tc.Utils.TcMType ( newOpenFlexiTyVar, newOpenFlexiTyVarTy, newOpenTypeKind, newOpenBoxedTypeKind, newMetaKindVar, newMetaKindVars, - newMetaTyVarTyAtLevel, newMetaTyVarTyWithInfo, + newMetaTyVarTyAtLevel, newConcreteTyVarTyAtLevel, newAnonMetaTyVar, newConcreteTyVar, cloneMetaTyVar, cloneMetaTyVarWithInfo, newCycleBreakerTyVar, @@ -482,7 +483,16 @@ newInferExpType :: TcM ExpType newInferExpType = new_inferExpType Nothing newInferExpTypeFRR :: FixedRuntimeRepContext -> TcM ExpTypeFRR -newInferExpTypeFRR frr_orig = new_inferExpType (Just frr_orig) +newInferExpTypeFRR frr_orig + = do { th_stage <- getStage + ; if + -- See [Wrinkle: Typed Template Haskell] + -- in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete. + | Brack _ (TcPending {}) <- th_stage + -> new_inferExpType Nothing + + | otherwise + -> new_inferExpType (Just frr_orig) } new_inferExpType :: Maybe FixedRuntimeRepContext -> TcM ExpType new_inferExpType mb_frr_orig @@ -538,20 +548,28 @@ expTypeToType (Infer inf_res) = inferResultToType inf_res inferResultToType :: InferResult -> TcM Type inferResultToType (IR { ir_uniq = u, ir_lvl = tc_lvl - , ir_ref = ref }) + , ir_ref = ref + , ir_frr = mb_frr }) = do { mb_inferred_ty <- readTcRef ref ; tau <- case mb_inferred_ty of Just ty -> do { ensureMonoType ty -- See Note [inferResultToType] ; return ty } - Nothing -> do { rr <- newMetaTyVarTyAtLevel tc_lvl runtimeRepTy - ; tau <- newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) - -- See Note [TcLevel of ExpType] + Nothing -> do { tau <- new_meta ; writeMutVar ref (Just tau) ; return tau } ; traceTc "Forcing ExpType to be monomorphic:" (ppr u <+> text ":=" <+> ppr tau) ; return tau } + where + -- See Note [TcLevel of ExpType] + new_meta = case mb_frr of + Nothing -> do { rr <- newMetaTyVarTyAtLevel tc_lvl runtimeRepTy + ; newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) } + Just frr -> mdo { rr <- newConcreteTyVarTyAtLevel conc_orig tc_lvl runtimeRepTy + ; tau <- newMetaTyVarTyAtLevel tc_lvl (mkTYPEapp rr) + ; let conc_orig = ConcreteFRR $ FixedRuntimeRepOrigin tau frr + ; return tau } {- Note [inferResultToType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -874,6 +892,13 @@ newTauTvDetailsAtLevel tclvl , mtv_ref = ref , mtv_tclvl = tclvl }) } +newConcreteTvDetailsAtLevel :: ConcreteTvOrigin -> TcLevel -> TcM TcTyVarDetails +newConcreteTvDetailsAtLevel conc_orig tclvl + = do { ref <- newMutVar Flexi + ; return (MetaTv { mtv_info = ConcreteTv conc_orig + , mtv_ref = ref + , mtv_tclvl = tclvl }) } + cloneMetaTyVar :: TcTyVar -> TcM TcTyVar cloneMetaTyVar tv = assert (isTcTyVar tv) $ @@ -931,7 +956,7 @@ isUnfilledMetaTyVar tv -------------------- -- Works with both type and kind variables -writeMetaTyVar :: TcTyVar -> TcType -> TcM () +writeMetaTyVar :: HasDebugCallStack => TcTyVar -> TcType -> TcM () -- Write into a currently-empty MetaTyVar writeMetaTyVar tyvar ty @@ -949,7 +974,7 @@ writeMetaTyVar tyvar ty = massertPpr False (text "Writing to non-meta tyvar" <+> ppr tyvar) -------------------- -writeMetaTyVarRef :: TcTyVar -> TcRef MetaDetails -> TcType -> TcM () +writeMetaTyVarRef :: HasDebugCallStack => TcTyVar -> TcRef MetaDetails -> TcType -> TcM () -- Here the tyvar is for error checking only; -- the ref cell must be for the same tyvar writeMetaTyVarRef tyvar ref ty @@ -1114,13 +1139,10 @@ newMetaTyVarTyAtLevel tc_lvl kind ; name <- newMetaTyVarName (fsLit "p") ; return (mkTyVarTy (mkTcTyVar name kind details)) } -newMetaTyVarTyWithInfo :: TcLevel -> MetaInfo -> TcKind -> TcM TcType -newMetaTyVarTyWithInfo tc_lvl info kind - = do { ref <- newMutVar Flexi - ; let details = MetaTv { mtv_info = info - , mtv_ref = ref - , mtv_tclvl = tc_lvl } - ; name <- newMetaTyVarName (fsLit "p") +newConcreteTyVarTyAtLevel :: ConcreteTvOrigin -> TcLevel -> TcKind -> TcM TcType +newConcreteTyVarTyAtLevel conc_orig tc_lvl kind + = do { details <- newConcreteTvDetailsAtLevel conc_orig tc_lvl + ; name <- newMetaTyVarName (fsLit "c") ; return (mkTyVarTy (mkTcTyVar name kind details)) } {- ********************************************************************* @@ -2258,7 +2280,7 @@ a \/\a in the final result but all the occurrences of a will be zonked to () * * ********************************************************************* -} -promoteMetaTyVarTo :: TcLevel -> TcTyVar -> TcM Bool +promoteMetaTyVarTo :: HasDebugCallStack => TcLevel -> TcTyVar -> TcM Bool -- When we float a constraint out of an implication we must restore -- invariant (WantedInv) in Note [TcLevel invariants] in GHC.Tc.Utils.TcType -- Return True <=> we did some promotion @@ -2276,7 +2298,7 @@ promoteMetaTyVarTo tclvl tv = return False -- Returns whether or not *any* tyvar is defaulted -promoteTyVarSet :: TcTyVarSet -> TcM Bool +promoteTyVarSet :: HasDebugCallStack => TcTyVarSet -> TcM Bool promoteTyVarSet tvs = do { tclvl <- getTcLevel ; bools <- mapM (promoteMetaTyVarTo tclvl) $ ===================================== compiler/GHC/Tc/Utils/Zonk.hs ===================================== @@ -56,6 +56,7 @@ import GHC.Tc.Utils.TcType import GHC.Tc.Utils.TcMType import GHC.Tc.Utils.Env ( tcLookupGlobalOnly ) import GHC.Tc.Types.Evidence +import GHC.Tc.Errors.Types import GHC.Core.TyCo.Ppr ( pprTyVar ) import GHC.Core.TyCon @@ -1737,7 +1738,7 @@ change. But in some cases it makes a HUGE difference: see test T9198 and #19668. So yes, it seems worth it. -} -zonkTyVarOcc :: ZonkEnv -> TcTyVar -> TcM Type +zonkTyVarOcc :: HasDebugCallStack => ZonkEnv -> TcTyVar -> TcM Type zonkTyVarOcc env@(ZonkEnv { ze_flexi = flexi , ze_tv_env = tv_env , ze_meta_tv_env = mtv_env_ref }) tv @@ -1810,6 +1811,9 @@ commitFlexi flexi tv zonked_kind | isMultiplicityTy zonked_kind -> do { traceTc "Defaulting flexi tyvar to Many:" (pprTyVar tv) ; return manyDataConTy } + | Just (ConcreteFRR origin) <- isConcreteTyVar_maybe tv + -> do { addErr $ TcRnCannotDefaultConcrete origin + ; return (anyTypeOfKind zonked_kind) } | otherwise -> do { traceTc "Defaulting flexi tyvar to Any:" (pprTyVar tv) ; return (anyTypeOfKind zonked_kind) } ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -480,8 +480,6 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalHsigDefaultMethods" = 93006 GhcDiagnosticCode "TcRnHsigFixityMismatch" = 93007 - GhcDiagnosticCode "HsigShapeSortMismatch" = 93008 - GhcDiagnosticCode "HsigShapeNotUnifiable" = 93009 GhcDiagnosticCode "TcRnHsigNoIface" = 93010 GhcDiagnosticCode "TcRnHsigMissingModuleExport" = 93011 GhcDiagnosticCode "TcRnBadGenericMethod" = 59794 @@ -551,8 +549,7 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnPatSynEscapedCoercion" = 88986 GhcDiagnosticCode "TcRnPatSynExistentialInResult" = 33973 GhcDiagnosticCode "TcRnPatSynArityMismatch" = 18365 - GhcDiagnosticCode "PatSynNotInvertible" = 69317 - GhcDiagnosticCode "PatSynUnboundVar" = 28572 + GhcDiagnosticCode "TcRnCannotDefaultConcrete" = 52083 GhcDiagnosticCode "TcRnMultiAssocTyFamDefaults" = 59128 GhcDiagnosticCode "TcRnTyFamDepsDisabled" = 43991 GhcDiagnosticCode "TcRnAbstractClosedTyFamDecl" = 60012 @@ -580,6 +577,10 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnTyFamNameMismatch" = 88221 GhcDiagnosticCode "TcRnTypeSynonymCycle" = 97522 + -- PatSynInvalidRhsReason + GhcDiagnosticCode "PatSynNotInvertible" = 69317 + GhcDiagnosticCode "PatSynUnboundVar" = 28572 + -- TcRnBadFieldAnnotation/BadFieldAnnotationReason GhcDiagnosticCode "LazyFieldsDisabled" = 81601 GhcDiagnosticCode "UnpackWithoutStrictness" = 10107 @@ -601,6 +602,10 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnPrecedenceParsingError" = 88747 GhcDiagnosticCode "TcRnSectionPrecedenceError" = 46878 + -- HsigShapeMismatchReason + GhcDiagnosticCode "HsigShapeSortMismatch" = 93008 + GhcDiagnosticCode "HsigShapeNotUnifiable" = 93009 + -- IllegalNewtypeReason GhcDiagnosticCode "DoesNotHaveSingleField" = 23517 GhcDiagnosticCode "IsNonLinear" = 38291 ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -8,7 +8,7 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘p0’ + Cannot unify ‘R’ with the type variable ‘c0’ because it is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -4,7 +4,7 @@ RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘p0’ + Cannot unify ‘R’ with the type variable ‘c0’ because it is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T ===================================== testsuite/tests/rep-poly/RepPolyPatBind.stderr ===================================== @@ -1,4 +1,20 @@ +RepPolyPatBind.hs:18:5: error: [GHC-55287] + • The pattern binding does not have a fixed runtime representation. + Its type is: + p0 :: TYPE c0 + Cannot unify ‘TupleRep [rep, rep]’ with the type variable ‘c0’ + because it is not a concrete ‘RuntimeRep’. + • In the pattern: (# x, y #) + In a pattern binding: (# x, y #) = undefined + In the expression: + let + x, y :: a + (# x, y #) = undefined + in x + • Relevant bindings include + foo :: () -> a (bound at RepPolyPatBind.hs:15:1) + RepPolyPatBind.hs:18:5: error: [GHC-55287] • • The binder ‘y’ does not have a fixed runtime representation. Its type is: ===================================== testsuite/tests/rep-poly/T23153.hs ===================================== @@ -0,0 +1,8 @@ +module T23153 where + +import GHC.Exts + +f :: forall r s (a :: TYPE (r s)). a -> () +f = f + +g h = f (h ()) ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -0,0 +1,15 @@ + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23153.hs:8:1: error: [GHC-52083] + The argument ‘(h ())’ of ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. ===================================== testsuite/tests/rep-poly/T23154.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE PartialTypeSignatures #-} + +module T23154 where + +import GHC.Exts + +f x = x :: (_ :: (TYPE (_ _))) ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -0,0 +1,10 @@ + +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. + +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -116,3 +116,5 @@ test('T21650_b', normal, compile_fail, ['-Wno-deprecated-flags']) ## test('T23051', normal, compile_fail, ['']) +test('T23153', normal, compile_fail, ['']) +test('T23154', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/VtaFail.stderr ===================================== @@ -7,7 +7,7 @@ VtaFail.hs:7:16: error: [GHC-95781] answer_nosig = pairup_nosig @Int @Bool 5 True VtaFail.hs:14:17: error: [GHC-95781] - • Cannot apply expression of type ‘p1 -> p1’ + • Cannot apply expression of type ‘p0 -> p0’ to a visible type argument ‘Int’ • In the expression: (\ x -> x) @Int 12 In an equation for ‘answer_lambda’: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c04024617f1ee4c76844cfe0a886bab87c23bd0...bad2f8b8aa84241e523577062e2b69090efccb32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c04024617f1ee4c76844cfe0a886bab87c23bd0...bad2f8b8aa84241e523577062e2b69090efccb32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 22:12:38 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 18:12:38 -0400 Subject: [Git][ghc/ghc][master] Transfer DFunId_ness onto specialised bindings Message-ID: <643c72d66aaf_10a80d6c9612cc8388ca@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Specialise.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b0ea4809d92581a10e0e501a6fbd7339e8922bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b0ea4809d92581a10e0e501a6fbd7339e8922bf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 16 22:13:15 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 16 Apr 2023 18:13:15 -0400 Subject: [Git][ghc/ghc][master] Add import lists to few GHC.Driver.Session imports Message-ID: <643c72fbedce4_10a80d6cc4ec0084259a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 4 changed files: - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Tc/Types/Constraint.hs Changes: ===================================== compiler/GHC/Driver/Errors/Types.hs ===================================== @@ -25,7 +25,8 @@ import GHC.Prelude import Data.Bifunctor import Data.Typeable -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, PackageArg, gopt) +import GHC.Driver.Flags (GeneralFlag (Opt_BuildingCabalPackage)) import GHC.Types.Error import GHC.Unit.Module import GHC.Unit.State ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name, dataName) -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) import qualified GHC.LanguageExtensions as LangExt import Data.Data ===================================== compiler/GHC/HsToCore/Errors/Types.hs ===================================== @@ -9,7 +9,8 @@ import GHC.Prelude import GHC.Core (CoreRule, CoreExpr, RuleName) import GHC.Core.DataCon import GHC.Core.Type -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) +import GHC.Driver.Flags (WarningFlag) import GHC.Hs import GHC.HsToCore.Pmc.Solver.Types import GHC.Types.Basic (Activation) ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -117,7 +117,7 @@ import GHC.Core import GHC.Core.TyCo.Ppr import GHC.Utils.FV import GHC.Types.Var.Set -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags(reductionDepth)) import GHC.Types.Basic import GHC.Types.Unique import GHC.Types.Unique.Set View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1371ebb53a8206d6d99ac0d9bff4ed8a3043498 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1371ebb53a8206d6d99ac0d9bff4ed8a3043498 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 08:35:48 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 17 Apr 2023 04:35:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T21050 Message-ID: <643d04e450844_10a80d76e2d4b8880393@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T21050 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T21050 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 09:48:51 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 05:48:51 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Transfer DFunId_ness onto specialised bindings Message-ID: <643d16035d30c_10a80d782f0e68907170@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 4e08a73c by Matthew Pickering at 2023-04-17T05:48:43-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - c3749a9e by Simon Peyton Jones at 2023-04-17T05:48:43-04:00 Add regression test for #23199 - - - - - 10 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Tc/Types/Constraint.hs - + testsuite/tests/typecheck/should_compile/T23199.hs - testsuite/tests/typecheck/should_compile/all.T - + testsuite/tests/warnings/should_compile/T23212.hs - testsuite/tests/warnings/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -48,10 +48,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Name import GHC.Types.Tickish import GHC.Types.Id.Make ( voidArgId, voidPrimId ) -import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg ) +import GHC.Types.Var ( PiTyBinder(..), isLocalVar, isInvisibleFunArg, mkLocalVar ) import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Types.Id +import GHC.Types.Id.Info import GHC.Types.Error import GHC.Utils.Error ( mkMCDiagnostic ) @@ -59,6 +60,7 @@ import GHC.Utils.Monad ( foldlM ) import GHC.Utils.Misc import GHC.Utils.Outputable import GHC.Utils.Panic +import GHC.Utils.Panic.Plain( assert ) import GHC.Unit.Module( Module ) import GHC.Unit.Module.ModGuts @@ -1748,12 +1750,44 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) join_arity_decr = length rule_lhs_args - length spec_bndrs - spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity - join_arity_decr) - | otherwise - = Nothing - ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity + -------------------------------------- + -- Add a suitable unfolding; see Note [Inline specialisations] + -- The wrap_unf_body applies the original unfolding to the specialised + -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) + simpl_opts = initSimpleOpts dflags + wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds + spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body + rule_lhs_args fn_unf + + -------------------------------------- + -- Adding arity information just propagates it a bit faster + -- See Note [Arity decrease] in GHC.Core.Opt.Simplify + -- Copy InlinePragma information from the parent Id. + -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs + + spec_inl_prag + | not is_local -- See Note [Specialising imported functions] + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal + = neverInlinePragma + | otherwise + = inl_prag + + spec_fn_info + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr) + `setInlinePragInfo` spec_inl_prag + `setUnfoldingInfo` spec_unf + + -- Compute the IdDetails of the specialise Id + -- See Note [Transfer IdDetails during specialisation] + spec_fn_details + = case idDetails fn of + JoinId join_arity _ -> JoinId (join_arity - join_arity_decr) Nothing + DFunId is_nt -> DFunId is_nt + _ -> VanillaId + + ; spec_fn <- newSpecIdSM (idName fn) spec_fn_ty spec_fn_details spec_fn_info ; let -- The rule to put in the function's specialisation is: -- forall x @b d1' d2'. @@ -1768,33 +1802,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs herald fn rule_bndrs rule_lhs_args (mkVarApps (Var spec_fn) spec_bndrs) - simpl_opts = initSimpleOpts dflags - - -------------------------------------- - -- Add a suitable unfolding; see Note [Inline specialisations] - -- The wrap_unf_body applies the original unfolding to the specialised - -- arguments, not forgetting to wrap the dx_binds around the outside (#22358) - wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds - spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body - rule_lhs_args fn_unf - - spec_inl_prag - | not is_local -- See Note [Specialising imported functions] - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal - = neverInlinePragma - | otherwise - = inl_prag - - -------------------------------------- - -- Adding arity information just propagates it a bit faster - -- See Note [Arity decrease] in GHC.Core.Opt.Simplify - -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_fn - arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs - spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity + spec_f_w_arity = spec_fn _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty @@ -1824,7 +1832,7 @@ specLookupRule env fn args phase rules {- Note [Specialising DFuns] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DFuns have a special sort of unfolding (DFunUnfolding), and these are +DFuns have a special sort of unfolding (DFunUnfolding), and it is hard to specialise a DFunUnfolding to give another DFunUnfolding unless the DFun is fully applied (#18120). So, in the case of DFunIds we simply extend the CallKey with trailing UnspecTypes/UnspecArgs, @@ -1833,6 +1841,36 @@ so that we'll generate a rule that completely saturates the DFun. There is an ASSERT that checks this, in the DFunUnfolding case of GHC.Core.Unfold.Make.specUnfolding. +Note [Transfer IdDetails during specialisation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, `newSpecIdSM` comes up with a fresh Id the +specialised RHS will be bound to. It is critical that we get the `IdDetails` of +the specialised Id correct: + +* JoinId: We want the specialised Id to be a join point, too. But + we have to carefully adjust the arity + +* DFunId: It is crucial that we also make the new Id a DFunId. + - First, because it obviously /is/ a DFun, having a DFunUnfolding and + all that; see Note [Specialising DFuns] + + - Second, DFuns get very delicate special treatment in the demand analyser; + see GHC.Core.Opt.DmdAnal.enterDFun. If the specialised function isn't + also a DFunId, this special treatment doesn't happen, so the demand + analyser makes a too-strict DFun, and we get an infinite loop. See Note + [Do not strictify a DFun's parameter dictionaries] in GHC.Core.Opt.DmdAnal. + #22549 describes the loop, and (lower down) a case where a /specialised/ + DFun caused a loop. + +* WorkerLikeId: Introduced by WW, so after Specialise. Nevertheless, they come + up when specialising imports. We must keep them as VanillaIds because WW + will detect them as WorkerLikeIds again. That is, unless specialisation + allows unboxing of all previous CBV args, in which case sticking to + VanillaIds was the only correct choice to begin with. + +* RecSelId, DataCon*Id, ClassOpId, PrimOpId, FCallId, CoVarId, TickBoxId: + Never specialised. + Note [Specialisation Must Preserve Sharing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: @@ -3439,15 +3477,14 @@ newDictBndr env@(SE { se_subst = subst }) b env' = env { se_subst = subst `Core.extendSubstInScope` b' } ; pure (env', b') } -newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id +newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id -- Give the new Id a similar occurrence name to the old one -newSpecIdSM old_id new_ty join_arity_maybe +newSpecIdSM old_name new_ty details info = do { uniq <- getUniqueM - ; let name = idName old_id - new_occ = mkSpecOcc (nameOccName name) - new_id = mkUserLocal new_occ uniq ManyTy new_ty (getSrcSpan name) - `asJoinId_maybe` join_arity_maybe - ; return new_id } + ; let new_occ = mkSpecOcc (nameOccName old_name) + new_name = mkInternalName uniq new_occ (getSrcSpan old_name) + ; return (assert (not (isCoVarType new_ty)) $ + mkLocalVar details new_name ManyTy new_ty info) } {- Old (but interesting) stuff about unboxed bindings ===================================== compiler/GHC/Driver/Errors/Types.hs ===================================== @@ -25,7 +25,8 @@ import GHC.Prelude import Data.Bifunctor import Data.Typeable -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, PackageArg, gopt) +import GHC.Driver.Flags (GeneralFlag (Opt_BuildingCabalPackage)) import GHC.Types.Error import GHC.Unit.Module import GHC.Unit.State ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -514,13 +514,17 @@ warnUnusedPackages :: UnitState -> DynFlags -> ModuleGraph -> DriverMessages warnUnusedPackages us dflags mod_graph = let diag_opts = initDiagOpts dflags + home_mod_sum = filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph) + -- Only need non-source imports here because SOURCE imports are always HPT loadedPackages = concat $ mapMaybe (\(fs, mn) -> lookupModulePackage us (unLoc mn) fs) - $ concatMap ms_imps ( - filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph)) + $ concatMap ms_imps home_mod_sum + + any_import_ghc_prim = any ms_ghc_prim_import home_mod_sum - used_args = Set.fromList $ map unitId loadedPackages + used_args = Set.fromList (map unitId loadedPackages) + `Set.union` Set.fromList [ primUnitId | any_import_ghc_prim ] resolve (u,mflag) = do -- The units which we depend on via the command line explicitly ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -82,7 +82,7 @@ import GHC.Types.SrcLoc import GHC.Data.Bag -- collect ev vars from pats import GHC.Data.Maybe import GHC.Types.Name (Name, dataName) -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) import qualified GHC.LanguageExtensions as LangExt import Data.Data ===================================== compiler/GHC/HsToCore/Errors/Types.hs ===================================== @@ -9,7 +9,8 @@ import GHC.Prelude import GHC.Core (CoreRule, CoreExpr, RuleName) import GHC.Core.DataCon import GHC.Core.Type -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags, xopt) +import GHC.Driver.Flags (WarningFlag) import GHC.Hs import GHC.HsToCore.Pmc.Solver.Types import GHC.Types.Basic (Activation) ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -117,7 +117,7 @@ import GHC.Core import GHC.Core.TyCo.Ppr import GHC.Utils.FV import GHC.Types.Var.Set -import GHC.Driver.Session +import GHC.Driver.Session (DynFlags(reductionDepth)) import GHC.Types.Basic import GHC.Types.Unique import GHC.Types.Unique.Set ===================================== testsuite/tests/typecheck/should_compile/T23199.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} +module Foo where + +class C a b c | b -> c where + op :: a -> b -> c + +bar1 :: C a Int Char => a -> Char +bar1 x = op x (3 :: Int) :: Char + +bar2 x = op x (3 :: Int) :: Char ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -872,3 +872,4 @@ test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) test('T23192', normal, compile, ['']) +test('T23199', normal, compile, ['']) ===================================== testsuite/tests/warnings/should_compile/T23212.hs ===================================== @@ -0,0 +1,3 @@ +module T23212 where + +import GHC.Prim ===================================== testsuite/tests/warnings/should_compile/all.T ===================================== @@ -39,6 +39,10 @@ test('UnusedPackages', [normalise_version('bytestring') ], multimod_compile, ['UnusedPackages.hs', '-package=bytestring -package=base -package=process -package=ghc -Wunused-packages']) +test('T23212', [normalise_version('ghc-prim') + ], multimod_compile, + ['T23212', '-v0 -package=ghc-prim -Werror -Wunused-packages']) + test('T18402', normal, compile, ['']) test('T19564a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c2f984f56b5b3b38800b1c971aa1b45b0fb9814...c3749a9eda74e887207f224e491919d2cb4dd4e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c2f984f56b5b3b38800b1c971aa1b45b0fb9814...c3749a9eda74e887207f224e491919d2cb4dd4e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 11:18:29 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 17 Apr 2023 07:18:29 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] Precompute static closures for DataCons with zero-width args Message-ID: <643d2b05ca045_10a80d79b3ceb8931575@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 7db22908 by Rodrigo Mesquita at 2023-04-17T12:04:42+01:00 Precompute static closures for DataCons with zero-width args Relax the predicate over nullary datacons that determines whether we can return a precomputed static closure for them, such that we give precomputed static closures to datacons that only take zero-width arguments. Previously, we would only allow datacons that were nullary with regard to their Core representation, which prevented datacons with only zero-width arguments from using a precomputed static closure. - - - - - 2 changed files: - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -22,7 +22,7 @@ module GHC.StgToCmm.Closure ( argPrimRep, NonVoid(..), fromNonVoid, nonVoidIds, nonVoidStgArgs, - assertNonVoidIds, assertNonVoidStgArgs, + assertNonVoidIds, assertNonVoidStgArgs, hasNoNonZeroWidthArgs, -- * LambdaFormInfo LambdaFormInfo, -- Abstract @@ -170,6 +170,12 @@ assertNonVoidStgArgs :: [StgArg] -> [NonVoid StgArg] assertNonVoidStgArgs args = assert (not (any (isZeroBitTy . stgArgType) args)) $ coerce args +-- | Returns whether there are any arguments with a non-zero-width runtime +-- representation. +-- +-- Returns True if the datacon has no or /just/ zero-width arguments. +hasNoNonZeroWidthArgs :: DataCon -> Bool +hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys ----------------------------------------------------------------------------- -- Representations @@ -281,7 +287,6 @@ mkLFImported id = -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -326,9 +326,9 @@ because they don't support cross package data references well. -- See Note [Precomputed static closures] precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid StgArg] -> Maybe CgIdInfo precomputedStaticConInfo_maybe cfg binder con [] --- Nullary constructors - | isNullaryRepDataCon con - = Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + -- Nullary constructors (list of nonvoid args is null) + = assert (hasNoNonZeroWidthArgs con) $ + Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7db2290840030d0b8d23e10a1b774643e001dfdf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7db2290840030d0b8d23e10a1b774643e001dfdf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 11:20:58 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 17 Apr 2023 07:20:58 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] Precompute static closures for DataCons with zero-width args Message-ID: <643d2b9ad0571_10a80d79c53bbc9349c0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 0ad91552 by Rodrigo Mesquita at 2023-04-17T12:20:11+01:00 Precompute static closures for DataCons with zero-width args Relax the predicate over nullary datacons that determines whether we can return a precomputed static closure for them, such that we give precomputed static closures to datacons that only take zero-width arguments. Previously, we would only allow datacons that were nullary with regard to their Core representation, which prevented datacons with only zero-width arguments from using a precomputed static closure. Closes #23158 - - - - - 2 changed files: - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -22,7 +22,7 @@ module GHC.StgToCmm.Closure ( argPrimRep, NonVoid(..), fromNonVoid, nonVoidIds, nonVoidStgArgs, - assertNonVoidIds, assertNonVoidStgArgs, + assertNonVoidIds, assertNonVoidStgArgs, hasNoNonZeroWidthArgs, -- * LambdaFormInfo LambdaFormInfo, -- Abstract @@ -170,6 +170,12 @@ assertNonVoidStgArgs :: [StgArg] -> [NonVoid StgArg] assertNonVoidStgArgs args = assert (not (any (isZeroBitTy . stgArgType) args)) $ coerce args +-- | Returns whether there are any arguments with a non-zero-width runtime +-- representation. +-- +-- Returns True if the datacon has no or /just/ zero-width arguments. +hasNoNonZeroWidthArgs :: DataCon -> Bool +hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys ----------------------------------------------------------------------------- -- Representations @@ -281,7 +287,6 @@ mkLFImported id = -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -326,9 +326,9 @@ because they don't support cross package data references well. -- See Note [Precomputed static closures] precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid StgArg] -> Maybe CgIdInfo precomputedStaticConInfo_maybe cfg binder con [] --- Nullary constructors - | isNullaryRepDataCon con - = Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + -- Nullary constructors (list of nonvoid args is null) + = assert (hasNoNonZeroWidthArgs con) $ + Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ad9155289f058d7ba8df82fcf08a87aa6ab0f68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ad9155289f058d7ba8df82fcf08a87aa6ab0f68 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 12:09:05 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 08:09:05 -0400 Subject: [Git][ghc/ghc][master] Account for special GHC.Prim import in warnUnusedPackages Message-ID: <643d36e1d9ce8_10a80d7a9aeb7c9418e5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 3 changed files: - compiler/GHC/Driver/Make.hs - + testsuite/tests/warnings/should_compile/T23212.hs - testsuite/tests/warnings/should_compile/all.T Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -514,13 +514,17 @@ warnUnusedPackages :: UnitState -> DynFlags -> ModuleGraph -> DriverMessages warnUnusedPackages us dflags mod_graph = let diag_opts = initDiagOpts dflags + home_mod_sum = filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph) + -- Only need non-source imports here because SOURCE imports are always HPT loadedPackages = concat $ mapMaybe (\(fs, mn) -> lookupModulePackage us (unLoc mn) fs) - $ concatMap ms_imps ( - filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph)) + $ concatMap ms_imps home_mod_sum + + any_import_ghc_prim = any ms_ghc_prim_import home_mod_sum - used_args = Set.fromList $ map unitId loadedPackages + used_args = Set.fromList (map unitId loadedPackages) + `Set.union` Set.fromList [ primUnitId | any_import_ghc_prim ] resolve (u,mflag) = do -- The units which we depend on via the command line explicitly ===================================== testsuite/tests/warnings/should_compile/T23212.hs ===================================== @@ -0,0 +1,3 @@ +module T23212 where + +import GHC.Prim ===================================== testsuite/tests/warnings/should_compile/all.T ===================================== @@ -39,6 +39,10 @@ test('UnusedPackages', [normalise_version('bytestring') ], multimod_compile, ['UnusedPackages.hs', '-package=bytestring -package=base -package=process -package=ghc -Wunused-packages']) +test('T23212', [normalise_version('ghc-prim') + ], multimod_compile, + ['T23212', '-v0 -package=ghc-prim -Werror -Wunused-packages']) + test('T18402', normal, compile, ['']) test('T19564a', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51479ceb31b8bfef15b966de7cfd64d1fdb22257 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51479ceb31b8bfef15b966de7cfd64d1fdb22257 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 12:09:39 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 08:09:39 -0400 Subject: [Git][ghc/ghc][master] Add regression test for #23199 Message-ID: <643d3703d1303_10a80d7a71cb4894498c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/T23199.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/T23199.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} +module Foo where + +class C a b c | b -> c where + op :: a -> b -> c + +bar1 :: C a Int Char => a -> Char +bar1 x = op x (3 :: Int) :: Char + +bar2 x = op x (3 :: Int) :: Char ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -872,3 +872,4 @@ test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) test('T23192', normal, compile, ['']) +test('T23199', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1532a8b2b222fee73959a0760ac8867be7f19ce6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1532a8b2b222fee73959a0760ac8867be7f19ce6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 13:07:06 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 17 Apr 2023 09:07:06 -0400 Subject: [Git][ghc/ghc][wip/interface-loading-errs] 92 commits: Make exprIsConApp_maybe a bit cleverer Message-ID: <643d447a1c8a7_10a80d7bf221e89537ab@gitlab.mail> Matthew Pickering pushed to branch wip/interface-loading-errs at Glasgow Haskell Compiler / GHC Commits: c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 5cea333d by Matthew Pickering at 2023-04-17T14:06:31+01:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/FVs.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a62f7ac33d7bbe965b13bb23e29324a164151b2b...5cea333d2e8b03d71f554573eae42fc696dabf20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a62f7ac33d7bbe965b13bb23e29324a164151b2b...5cea333d2e8b03d71f554573eae42fc696dabf20 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 13:57:11 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 17 Apr 2023 09:57:11 -0400 Subject: [Git][ghc/ghc][wip/interface-loading-errs] Convert interface file loading errors into proper diagnostics Message-ID: <643d50373880e_10a80d7cce9c909563f1@gitlab.mail> Matthew Pickering pushed to branch wip/interface-loading-errs at Glasgow Haskell Compiler / GHC Commits: ec9b7dd7 by Matthew Pickering at 2023-04-17T14:57:04+01:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - 30 changed files: - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Error.hs - compiler/ghc.cabal.in - ghc/Main.hs - testsuite/tests/cabal/cabal05/cabal05.stderr - testsuite/tests/cabal/ghcpkg04.stderr - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec9b7dd7b80b9637a84e60ce9425bfd223b4c379 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec9b7dd7b80b9637a84e60ce9425bfd223b4c379 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 17:38:48 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 17 Apr 2023 13:38:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/misc-cleanup6 Message-ID: <643d84283b322_178e742e7758c369b0@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/misc-cleanup6 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/misc-cleanup6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 20:13:35 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 16:13:35 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Account for special GHC.Prim import in warnUnusedPackages Message-ID: <643da86fc06ad_178e7459060145039f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 7f8865e7 by Ryan Scott at 2023-04-17T16:13:20-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 44f83433 by Krzysztof Gogolewski at 2023-04-17T16:13:21-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 30 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Validity.hs - docs/users_guide/9.8.1-notes.rst - libraries/base/GHC/Event/Manager.hs - libraries/base/GHC/Event/TimerManager.hs - libraries/base/GHC/Fingerprint.hs - libraries/base/GHC/Fingerprint/Type.hs - libraries/base/GHC/IO/Encoding/Types.hs - + testsuite/tests/deriving/should_compile/T22696a.hs - + testsuite/tests/deriving/should_compile/T22696c.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/deriving/should_compile/drv015.hs - testsuite/tests/deriving/should_compile/T14339.hs → testsuite/tests/deriving/should_fail/T14339.hs - + testsuite/tests/deriving/should_fail/T14339.stderr - + testsuite/tests/deriving/should_fail/T22696b.hs - + testsuite/tests/deriving/should_fail/T22696b.stderr - testsuite/tests/deriving/should_fail/all.T - + testsuite/tests/typecheck/should_compile/T23199.hs - testsuite/tests/typecheck/should_compile/all.T - + testsuite/tests/warnings/should_compile/T23212.hs - testsuite/tests/warnings/should_compile/all.T - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2715,7 +2715,7 @@ genCCall64 addr conv dest_regs args = do <- load_args prom_args (allIntArgRegs platform) (allFPArgRegs platform) nilOL nilOL - let used_regs rs as = reverse (drop (length rs) (reverse as)) + let used_regs rs as = dropTail (length rs) as fregs_used = used_regs fregs (allFPArgRegs platform) aregs_used = used_regs aregs (allIntArgRegs platform) return (stack_args, aregs_used, fregs_used, load_args_code ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -556,7 +556,8 @@ chunkify xs where n_xs = length xs split [] = [] - split xs = take mAX_TUPLE_SIZE xs : split (drop mAX_TUPLE_SIZE xs) + split xs = let (as, bs) = splitAt mAX_TUPLE_SIZE xs + in as : split bs {- ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -1752,13 +1752,12 @@ newLvlVar lvld_rhs join_arity_maybe is_mk_static cloneCaseBndrs :: LevelEnv -> Level -> [Var] -> LvlM (LevelEnv, [Var]) cloneCaseBndrs env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env }) new_lvl vs - = do { us <- getUniqueSupplyM - ; let (subst', vs') = cloneBndrs subst us vs + = do { (subst', vs') <- cloneBndrs subst vs -- N.B. We are not moving the body of the case, merely its case -- binders. Consequently we should *not* set le_ctxt_lvl and -- le_join_ceil. See Note [Setting levels when floating -- single-alternative cases]. - env' = env { le_lvl_env = addLvls new_lvl lvl_env vs' + ; let env' = env { le_lvl_env = addLvls new_lvl lvl_env vs' , le_subst = subst' , le_env = foldl' add_id id_env (vs `zip` vs') } @@ -1773,13 +1772,13 @@ cloneLetVars :: RecFlag -> LevelEnv -> Level -> [InVar] cloneLetVars is_rec env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env }) dest_lvl vs - = do { us <- getUniqueSupplyM - ; let vs1 = map zap vs + = do { let vs1 = map zap vs -- See Note [Zapping the demand info] - (subst', vs2) = case is_rec of - NonRecursive -> cloneBndrs subst us vs1 - Recursive -> cloneRecIdBndrs subst us vs1 - prs = vs `zip` vs2 + ; (subst', vs2) <- case is_rec of + NonRecursive -> cloneBndrs subst vs1 + Recursive -> cloneRecIdBndrs subst vs1 + + ; let prs = vs `zip` vs2 env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs2 , le_subst = subst' , le_env = foldl' add_id id_env prs } ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -3461,9 +3461,8 @@ cloneBndrSM env@(SE { se_subst = subst }) bndr cloneRecBndrsSM :: SpecEnv -> [Id] -> SpecM (SpecEnv, [Id]) cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs - = do { us <- getUniqueSupplyM - ; let (subst', bndrs') = Core.cloneRecIdBndrs subst us bndrs - env' = env { se_subst = subst' } + = do { (subst', bndrs') <- Core.cloneRecIdBndrs subst bndrs + ; let env' = env { se_subst = subst' } ; return (env', bndrs') } newDictBndr :: SpecEnv -> CoreBndr -> SpecM (SpecEnv, CoreBndr) ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -213,12 +213,11 @@ mkWwBodies opts fun_id arg_vars res_ty demands res_cpr -- Clone and prepare arg_vars of the original fun RHS -- See Note [Freshen WW arguments] -- and Note [Zap IdInfo on worker args] - ; uniq_supply <- getUniqueSupplyM ; let args_free_tcvs = tyCoVarsOfTypes (res_ty : map varType arg_vars) empty_subst = mkEmptySubst (mkInScopeSet args_free_tcvs) zapped_arg_vars = map zap_var arg_vars - (subst, cloned_arg_vars) = cloneBndrs empty_subst uniq_supply zapped_arg_vars - res_ty' = substTyUnchecked subst res_ty + ; (subst, cloned_arg_vars) <- cloneBndrs empty_subst zapped_arg_vars + ; let res_ty' = substTyUnchecked subst res_ty init_str_marks = map (const NotMarkedStrict) cloned_arg_vars ; (useful1, work_args_str, wrap_fn_str, fn_args) ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -417,11 +417,12 @@ cloneIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id]) cloneIdBndrs subst us ids = mapAccumL (clone_id subst) subst (ids `zip` uniqsFromSupply us) -cloneBndrs :: Subst -> UniqSupply -> [Var] -> (Subst, [Var]) +cloneBndrs :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var]) -- Works for all kinds of variables (typically case binders) -- not just Ids -cloneBndrs subst us vs - = mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` uniqsFromSupply us) +cloneBndrs subst vs + = do us <- getUniquesM + pure $ mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` us) cloneBndr :: Subst -> Unique -> Var -> (Subst, Var) cloneBndr subst uniq v @@ -429,12 +430,11 @@ cloneBndr subst uniq v | otherwise = clone_id subst subst (v,uniq) -- Works for coercion variables too -- | Clone a mutually recursive group of 'Id's -cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id]) -cloneRecIdBndrs subst us ids - = (subst', ids') - where - (subst', ids') = mapAccumL (clone_id subst') subst - (ids `zip` uniqsFromSupply us) +cloneRecIdBndrs :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id]) +cloneRecIdBndrs subst ids + = do us <- getUniquesM + let (subst', ids') = mapAccumL (clone_id subst') subst (ids `zip` us) + pure (subst', ids') -- Just like substIdBndr, except that it always makes a new unique -- It is given the unique to use ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -514,13 +514,17 @@ warnUnusedPackages :: UnitState -> DynFlags -> ModuleGraph -> DriverMessages warnUnusedPackages us dflags mod_graph = let diag_opts = initDiagOpts dflags + home_mod_sum = filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph) + -- Only need non-source imports here because SOURCE imports are always HPT loadedPackages = concat $ mapMaybe (\(fs, mn) -> lookupModulePackage us (unLoc mn) fs) - $ concatMap ms_imps ( - filter (\ms -> homeUnitId_ dflags == ms_unitid ms) (mgModSummaries mod_graph)) + $ concatMap ms_imps home_mod_sum + + any_import_ghc_prim = any ms_ghc_prim_import home_mod_sum - used_args = Set.fromList $ map unitId loadedPackages + used_args = Set.fromList (map unitId loadedPackages) + `Set.union` Set.fromList [ primUnitId | any_import_ghc_prim ] resolve (u,mflag) = do -- The units which we depend on via the command line explicitly ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -41,6 +41,7 @@ import GHC.StgToJS.Types import Prelude import GHC.Platform +import GHC.Utils.Misc import Data.List (isPrefixOf) import System.IO import Data.Char (isSpace) @@ -299,7 +300,7 @@ getJsOptions handle = do parseJsOptions :: String -> [JSOption] parseJsOptions xs = go xs where - trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace + trim = dropWhileEndLE isSpace . dropWhile isSpace go [] = [] go xs = let (tok, rest) = break (== ',') xs tok' = trim tok ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -768,8 +768,8 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- Returns @Just p@ (where @p@ is the type of the Ct) if a Ct is -- suitable to be inferred in the context of a derived instance. -- Returns @Nothing@ if the Ct is too exotic. - -- See Note [Exotic derived instance contexts] for what - -- constitutes an exotic constraint. + -- See (VD2) in Note [Valid 'deriving' predicate] in + -- GHC.Tc.Validity for what constitutes an exotic constraint. get_good :: Ct -> Maybe PredType get_good ct | validDerivPred head_size p = Just p | otherwise = Nothing @@ -798,8 +798,9 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs min_theta_vars solved_wanteds -- This call to simplifyTop is purely for error reporting -- See Note [Error reporting for deriving clauses] - -- See also Note [Exotic derived instance contexts], which are caught - -- in this line of code. + -- See also Note [Valid 'deriving' predicate] in GHC.Tc.Validity, as this + -- line of code catches "exotic" constraints like the ones described in + -- (VD2) of that Note. ; simplifyTopImplic leftover_implic ; traceTc "GHC.Tc.Deriv" (ppr deriv_rhs $$ ppr min_theta) @@ -807,7 +808,7 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- Claim: the result instance declaration is guaranteed valid -- Hence no need to call: -- checkValidInstance tyvars theta clas inst_tys - -- See Note [Exotic derived instance contexts] + -- See Note [Valid 'deriving' predicate] in GHC.Tc.Validity ; return min_theta } @@ -1008,7 +1009,8 @@ error messages. In particular, if simplifyDeriv reaches a constraint that it cannot solve, which might include: 1. Insoluble constraints -2. "Exotic" constraints (See Note [Exotic derived instance contexts]) +2. "Exotic" constraints (See Note [Valid 'deriving' predicate] in + GHC.Tc.Validity) Then we report an error immediately in simplifyDeriv. @@ -1029,55 +1031,4 @@ And pass it to the simplifier. If the context (Foo a) is enough to discharge all the constraints in , then everything is hunky-dory. But if contains, say, an insoluble constraint, then (Foo a) won't be able to solve it, causing GHC to error. - -Note [Exotic derived instance contexts] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In a 'derived' instance declaration, we *infer* the context. It's a -bit unclear what rules we should apply for this; the Haskell report is -silent. Obviously, constraints like (Eq a) are fine, but what about - data T f a = MkT (f a) deriving( Eq ) -where we'd get an Eq (f a) constraint. That's probably fine too. - -One could go further: consider - data T a b c = MkT (Foo a b c) deriving( Eq ) - instance (C Int a, Eq b, Eq c) => Eq (Foo a b c) - -Notice that this instance (just) satisfies the Paterson termination -conditions. Then we *could* derive an instance decl like this: - - instance (C Int a, Eq b, Eq c) => Eq (T a b c) -even though there is no instance for (C Int a), because there just -*might* be an instance for, say, (C Int Bool) at a site where we -need the equality instance for T's. - -However, this seems pretty exotic, and it's quite tricky to allow -this, and yet give sensible error messages in the (much more common) -case where we really want that instance decl for C. - -So for now we simply require that the derived instance context -should have only type-variable constraints. - -Here is another example: - data Fix f = In (f (Fix f)) deriving( Eq ) -Here, if we are prepared to allow -XUndecidableInstances we -could derive the instance - instance Eq (f (Fix f)) => Eq (Fix f) -but this is so delicate that I don't think it should happen inside -'deriving'. If you want this, write it yourself! - -NB: if you want to lift this condition, make sure you still meet the -termination conditions! If not, the deriving mechanism generates -larger and larger constraints. Example: - data Succ a = S a - data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show - -Note the lack of a Show instance for Succ. First we'll generate - instance (Show (Succ a), Show a) => Show (Seq a) -and then - instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a) -and so on. Instead we want to complain of no instance for (Show (Succ a)). - -The bottom line -~~~~~~~~~~~~~~~ -Allow constraints which consist only of type variables, with no repeats. -} ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -1713,34 +1713,165 @@ The usual functional dependency checks also apply. Note [Valid 'deriving' predicate] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -validDerivPred checks for OK 'deriving' context. -See Note [Exotic derived instance contexts] in GHC.Tc.Deriv.Infer. However the predicate is -here because it is quite similar to checkInstTermination. - -It checks for two things: - -(VD1) The Paterson conditions; see Note [Paterson conditions] - Not on do we want to check for termination (of course), but it also - deals with a nasty corner case: - instance C a b => D (T a) where ... - Note that 'b' isn't a parameter of T. This gives rise to all sorts of - problems; in particular, it's hard to compare solutions for equality - when finding the fixpoint, and that means the inferContext loop does - not converge. See #5287, #21302 - -(VD2) No type constructors; no foralls, no equalities: - see Note [Exotic derived instance contexts] in GHC.Tc.Deriv.Infer - - We check the no-type-constructor bit using tyConsOfType. - Wrinkle: we look only at the /visible/ arguments of the class type - constructor. Including the non-visible arguments can cause the following, - perfectly valid instance to be rejected: - class Category (cat :: k -> k -> *) where ... - newtype T (c :: * -> * -> *) a b = MkT (c a b) - instance Category c => Category (T c) where ... - since the first argument to Category is a non-visible *, which has a - type constructor! See #11833. +In a 'derived' instance declaration, we *infer* the context. It's a bit unclear +what rules we should apply for this; the Haskell report is silent. Obviously, +constraints like `Eq a` are fine, but what about + data T f a = MkT (f a) deriving Eq + +where we'd get an `Eq (f a)` constraint. That's probably fine too. + +On the other hand, we don't want to allow *every* inferred constraint, as there +are some particularly complex constraints that are tricky to handle. If GHC +encounters a constraint that is too complex, it will reject it, and you will +have to use StandaloneDeriving to manually specify the instance context that +you want. + +There are two criteria for a constraint inferred by a `deriving` clause to be +considered valid, which are described below as (VD1) and (VD2). (Here, "VD" +stands for "valid deriving".) `validDerivPred` implements these checks. While +`validDerivPred` is similar to other things defined in GHC.Tc.Deriv.Infer, we +define it here in GHC.Tc.Validity because it is quite similar to +`checkInstTermination`. + +----------------------------------- +-- (VD1) The Paterson conditions -- +----------------------------------- + +Constraints must satisfy the Paterson conditions (see Note [Paterson +conditions]) to be valid. Not only does this check for termination (of course), +but it also deals with a nasty corner case: + + instance C a b => D (T a) where ... + +Note that `b` isn't a parameter of T. This gives rise to all sorts of +problems; in particular, it's hard to compare solutions for equality when +finding the fixpoint, and that means the +GHC.Tc.Deriv.Infer.simplifyInstanceContexts loop does not converge. +See #5287 and #21302. + +Another common situation in which a derived instance's context fails to meet +the Paterson conditions is when a constraint mentions a type variable more +often than the instance head, e.g., + + data Fix f = In (f (Fix f)) deriving Eq + +This would result in the following derived `Eq` instance: + + instance Eq (f (Fix f)) => Eq (Fix f) + +Because `f` is mentioned more often in the `Eq (f (Fix f))` constraint than in +the instance head `Eq (Fix f)`, GHC rejects this instance. + +This is a somewhat contentious restriction, and some have suggested that +instances like this one should be accepted if UndecidableInstances is enabled +(see #15868 for one such discussion). If we *do* lift this restriction in the +future, we should make sure to still meet the termination conditions. If not, +the deriving mechanism generates larger and larger constraints. Example: + + data Succ a = S a + data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show + +Note the lack of a Show instance for Succ. First we'll generate: + + instance (Show (Succ a), Show a) => Show (Seq a) + +and then: + + instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a) + +and so on. Instead we want to complain of no instance for (Show (Succ a)). + +--------------------------------- +-- (VD2) No exotic constraints -- +--------------------------------- + +A constraint must satisfy one of the following properties in order to be valid: + +* It is a `ClassPred` of the form `C a_1 ... a_n`, where C is a type class + constructor and a_1, ..., a_n are either raw type variables or applications + of type variables (e.g., `f a`). +* It is an `IrredPred` of the form `c a_1 ... a_n`, where `c` is a raw type + variable and a_1, ..., a_n are either raw type variables or applications of + type variables (e.g., `f a`). + +If a constraint does not meet either of these properties, it is considered +*exotic*. A constraint will be exotic if it contains: + +* Other type constructors (besides the class in a `ClassPred`), +* Foralls, or +* Equalities + +A common form of exotic constraint is one that mentions another type +constructor. For example, given the following: + + data NotAShowInstance + data Foo = MkFoo Int NotAShowInstance deriving Show + +GHC would attempt to generate the following derived `Show` instance: + + instance (Show Int, Show NotAShowInstance) => Show Foo + +Note that because there is a top-level `Show Int` instance, GHC is able to +simplify away the inferred `Show Int` constraint. However, it cannot do the +same for the `Show NotAShowInstance` constraint. One possibility would be to +generate this instance: + + instance Show NotAShowInstance => Show Foo + +But this is almost surely not what we want most of the time. For this reason, +we reject the constraint above as being exotic. + +Here are some other interesting examples: + +* Derived instances whose instance context would mention TypeError, such as the + code from the deriving/should_fail/T14339 test case, are exotic. For example: + + newtype Foo = Foo Int + + class Bar a where + bar :: a + + instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + + newtype Baz = Baz Foo + deriving Bar + + The `deriving Bar` clause would generate this instance: + + instance TypeError (Text "Boo") => Bar Baz + + The instance context is exotic, as `TypeError` is not a type constructor, and + `Text "Boo"` is not an application of type variables. As such, GHC rejects + it. This has the desirable side effect of causing the TypeError to fire in + the resulting error message. + +* The following `IrredPred`s are not exotic: + + instance c => C (T c a) + instance c a => C (T c a) + + This `IrredPred`, however, *is* exotic: + + instance c NotAShowInstance => C (T c) + + This is rejected for the same reasons that we do not permit a `ClassPred` + with a type constructor argument, such as the `Show NotAShowInstance` example + above. + +As part of implementing this check, GHC calls `tyConsOfType` on the arguments +of the constraint, ensuring that there are no other type constructors. +Wrinkle: for `ClassPred`s, we look only at the /visible/ arguments of the class +type constructor. Including the non-visible arguments can cause the following, +perfectly valid instance to be rejected: + + class Category (cat :: k -> k -> Type) where ... + newtype T (c :: Type -> Type -> Type) a b = MkT (c a b) + instance Category c => Category (T c) where ... + +since the first argument to `Category` is a non-visible `Type`, which has a type +constructor! See #11833. Note [Equality class instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1753,23 +1884,17 @@ validDerivPred :: PatersonSize -> PredType -> Bool -- See Note [Valid 'deriving' predicate] validDerivPred head_size pred = case classifyPredType pred of - EqPred {} -> False -- Reject equality constraints - ForAllPred {} -> False -- Rejects quantified predicates + EqPred {} -> False -- Reject equality constraints (VD2) + ForAllPred {} -> False -- Rejects quantified predicates (VD2) - ClassPred cls tys -> check_size (pSizeClassPred cls tys) - && isEmptyUniqSet (tyConsOfTypes visible_tys) + ClassPred cls tys -> check_size (pSizeClassPred cls tys) -- (VD1) + && isEmptyUniqSet (tyConsOfTypes visible_tys) -- (VD2) where - visible_tys = filterOutInvisibleTypes (classTyCon cls) tys -- (VD2) - - IrredPred {} -> check_size (pSizeType pred) - -- Very important that we do the "too many variable occurrences" - -- check here, via check_size. Example (test T21302): - -- instance c Eq a => Eq (BoxAssoc a) - -- data BAD = BAD (BoxAssoc Int) deriving( Eq ) - -- We don't want to accept an inferred predicate (c0 Eq Int) - -- from that `deriving(Eq)` clause, because the c0 is fresh, - -- so we'll think it's a "new" one, and loop in - -- GHC.Tc.Deriv.Infer.simplifyInstanceContexts + -- See the wrinkle about visible arguments in (VD2) + visible_tys = filterOutInvisibleTypes (classTyCon cls) tys + + IrredPred {} -> check_size (pSizeType pred) -- (VD1) + && isEmptyUniqSet (tyConsOfType pred) -- (VD2) where check_size pred_size = isNothing (pred_size `ltPatersonSize` head_size) ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -61,6 +61,32 @@ Compiler The point is that only the type S has a constructor with both fields "foo" and "bar", so this record update is unambiguous. +- Data types with ``deriving`` clauses now reject inferred instance contexts + that mention ``TypeError`` constraints (see :ref:`custom-errors`), such as + this one: :: + + newtype Foo = Foo Int + + class Bar a where + bar :: a + + instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + + newtype Baz = Baz Foo + deriving Bar + + Here, the derived ``Bar`` instance for ``Baz`` would look like this: :: + + instance TypeError (Text "Boo") => Bar Baz + + While GHC would accept this before, GHC 9.8 now rejects it, emitting "``Boo``" + in the resulting error message. If you really want to derive this instance and + defer the error to sites where the instance is used, you must do so manually + with :extension:`StandaloneDeriving`, e.g. :: + + deriving instance TypeError (Text "Boo") => Bar Baz + GHCi ~~~~ ===================================== libraries/base/GHC/Event/Manager.hs ===================================== @@ -467,7 +467,7 @@ onFdEvent mgr fd evs IT.delete (fromIntegral fd) tbl >>= maybe (return []) (selectCallbacks tbl) forM_ fdds $ \(FdData reg _ cb) -> cb reg evs where - -- | Here we look through the list of registrations for the fd of interest + -- Here we look through the list of registrations for the fd of interest -- and sort out which match the events that were triggered. We, -- -- 1. re-arm the fd as appropriate ===================================== libraries/base/GHC/Event/TimerManager.hs ===================================== @@ -175,7 +175,7 @@ step mgr = do state `seq` return (state == Running) where - -- | Call all expired timer callbacks and return the time to the + -- Call all expired timer callbacks and return the time to the -- next timeout. mkTimeout :: IO Timeout mkTimeout = do ===================================== libraries/base/GHC/Fingerprint.hs ===================================== @@ -84,7 +84,7 @@ getFileHash path = withBinaryFile path ReadMode $ \h -> where _BUFSIZE = 4096 - -- | Loop over _BUFSIZE sized chunks read from the handle, + -- Loop over _BUFSIZE sized chunks read from the handle, -- passing the callback a block of bytes and its size. processChunks :: Handle -> (Ptr Word8 -> Int -> IO ()) -> IO () processChunks h f = allocaBytes _BUFSIZE $ \arrPtr -> ===================================== libraries/base/GHC/Fingerprint/Type.hs ===================================== @@ -30,7 +30,7 @@ data Fingerprint = Fingerprint {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 instance Show Fingerprint where show (Fingerprint w1 w2) = hex16 w1 ++ hex16 w2 where - -- | Formats a 64 bit number as 16 digits hex. + -- Formats a 64 bit number as 16 digits hex. hex16 :: Word64 -> String hex16 i = let hex = showHex i "" in replicate (16 - length hex) '0' ++ hex ===================================== libraries/base/GHC/IO/Encoding/Types.hs ===================================== @@ -119,7 +119,6 @@ data TextEncoding -- | @since 4.3.0.0 instance Show TextEncoding where - -- | Returns the value of 'textEncodingName' show te = textEncodingName te -- | @since 4.4.0.0 ===================================== testsuite/tests/deriving/should_compile/T22696a.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UndecidableInstances #-} +module T22696a where + +import GHC.TypeLits + +newtype Foo = Foo Int + +class Bar a where + bar :: a + +instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + +newtype Baz = Baz Foo + +deriving instance TypeError (Text "Boo") => Bar Baz ===================================== testsuite/tests/deriving/should_compile/T22696c.hs ===================================== @@ -0,0 +1,24 @@ +module T22696c where + +class C a where + m :: a + +data S1 c a where + MkS1 :: c => S1 c a +instance c => C (S1 c a) where + m = MkS1 + +data S2 c a where + MkS2 :: c a => S2 c a +instance c a => C (S2 c a) where + m = MkS2 + +newtype T1 c a = MkT1 (S1 c a) deriving C +newtype T2 c a = MkT2 (S2 c a) deriving C + -- The inferred instances would be: + -- + -- instance c => C (T1 c a) + -- instance c a => C (T2 c a) + -- + -- These are valid instance context for the reasons described in + -- (VD2) in Note [Valid 'deriving' predicate] in GHC.Tc.Validity. ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -101,7 +101,6 @@ test('T13919', normal, compile, ['']) test('T13998', normal, compile, ['']) test('T14045b', normal, compile, ['']) test('T14094', normal, compile, ['']) -test('T14339', normal, compile, ['']) test('T14331', normal, compile, ['']) test('T14332', normal, compile, ['']) test('T14578', normal, compile, ['-ddump-deriv -dsuppress-uniques']) @@ -140,3 +139,5 @@ test('T20501', normal, compile, ['']) test('T20719', normal, compile, ['']) test('T20994', normal, compile, ['']) test('T22167', normal, compile, ['']) +test('T22696a', normal, compile, ['']) +test('T22696c', normal, compile, ['']) ===================================== testsuite/tests/deriving/should_compile/drv015.hs ===================================== @@ -1,12 +1,12 @@ --- July 07: I'm changing this from "should_compile" to "should_fail". --- It would generate an instance decl like +-- This will generate an instance decl like: +-- -- instance (Show (f a), Show (g a)) => Show (Pair1 f g a) --- and that is not Haskell 98. -- --- See Note [Exotic derived instance contexts] in GHC.Tc.Solver. --- The rule is simple: the context of a derived instance decl must --- contain constraints of form (C tyvar) only, just as H98. +-- Although the Haskell Report would not permit this instance if written out +-- explicitly, it does not say anything about whether it is acceptable for a +-- *derived* instance to generate it. As such, we allow this in GHC. +-- See Note [Valid 'deriving' predicate] in GHC.Tc.Validity. module ShouldCompile where ===================================== testsuite/tests/deriving/should_compile/T14339.hs → testsuite/tests/deriving/should_fail/T14339.hs ===================================== @@ -16,10 +16,10 @@ instance (TypeError (Text "Boo")) => Bar Foo where newtype Baz = Baz Foo deriving Bar --- Apparently we derive +-- We derive: +-- -- instance TypeError (Text "Boo") => Bar Baz -- --- Is that really what we want? It defers the type --- error... surely we should use standalone deriving --- if that is what we want? --- See GHC.Tc.Validity.validDerivPred and #22696. \ No newline at end of file +-- And error out due to the TypeError. See also +-- deriving/should_compile/T22696a, which uses StandaloneDeriving to write a +-- valid instance with a TypeError constraint in its instance context. ===================================== testsuite/tests/deriving/should_fail/T14339.stderr ===================================== @@ -0,0 +1,4 @@ + +T14339.hs:17:12: error: [GHC-64725] + • Boo + • When deriving the instance for (Bar Baz) ===================================== testsuite/tests/deriving/should_fail/T22696b.hs ===================================== @@ -0,0 +1,19 @@ +module T22696b where + +class C a where + m :: a + +data S c where + MkS :: c Int => S c + +instance c Int => C (S c) where + m = MkS + +newtype T c = MkT (S c) + deriving C + -- The inferred instance would be: + -- + -- instance c Int => C (T c) + -- + -- And we want to reject this instance due to the reasons mentioned in + -- (VD2) in Note [Valid 'deriving' predicate] in GHC.Tc.Validity. ===================================== testsuite/tests/deriving/should_fail/T22696b.stderr ===================================== @@ -0,0 +1,5 @@ + +T22696b.hs:13:12: error: [GHC-05617] + • Could not solve: ‘c Int’ + arising from the 'deriving' clause of a data type declaration + • When deriving the instance for (C (T c)) ===================================== testsuite/tests/deriving/should_fail/all.T ===================================== @@ -69,6 +69,7 @@ test('T12801', normal, compile_fail, ['']) test('T13154c', normal, compile_fail, ['']) test('T14365', [extra_files(['T14365B.hs','T14365B.hs-boot'])], multimod_compile_fail, ['T14365A','']) +test('T14339', normal, compile_fail, ['']) test('T14728a', normal, compile_fail, ['']) test('T14728b', normal, compile_fail, ['']) test('T14916', normal, compile_fail, ['']) @@ -84,3 +85,4 @@ test('T21087', normal, compile_fail, ['']) test('T21087b', [extra_files(['T21087b_aux.hs','T21087b_aux.hs-boot'])], multimod_compile_fail, ['T21087b', '']) test('T21302', normal, compile_fail, ['']) test('T21871', normal, compile_fail, ['']) +test('T22696b', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_compile/T23199.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} +module Foo where + +class C a b c | b -> c where + op :: a -> b -> c + +bar1 :: C a Int Char => a -> Char +bar1 x = op x (3 :: Int) :: Char + +bar2 x = op x (3 :: Int) :: Char ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -872,3 +872,4 @@ test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) test('T23192', normal, compile, ['']) +test('T23199', normal, compile, ['']) ===================================== testsuite/tests/warnings/should_compile/T23212.hs ===================================== @@ -0,0 +1,3 @@ +module T23212 where + +import GHC.Prim ===================================== testsuite/tests/warnings/should_compile/all.T ===================================== @@ -39,6 +39,10 @@ test('UnusedPackages', [normalise_version('bytestring') ], multimod_compile, ['UnusedPackages.hs', '-package=bytestring -package=base -package=process -package=ghc -Wunused-packages']) +test('T23212', [normalise_version('ghc-prim') + ], multimod_compile, + ['T23212', '-v0 -package=ghc-prim -Werror -Wunused-packages']) + test('T18402', normal, compile, ['']) test('T19564a', normal, compile, ['']) ===================================== utils/deriveConstants/Main.hs ===================================== @@ -27,7 +27,6 @@ needing to run the program, by inspecting the object file using 'nm'. import Control.Monad (when, unless) import Data.Bits (shiftL) -import Data.Char (toLower) import Data.List (elemIndex, stripPrefix, intercalate) import Data.Map (Map) import qualified Data.Map as Map View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3749a9eda74e887207f224e491919d2cb4dd4e9...44f834339cf9d7cb94c8cb348bc468147506f5ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3749a9eda74e887207f224e491919d2cb4dd4e9...44f834339cf9d7cb94c8cb348bc468147506f5ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 22:43:47 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 18:43:47 -0400 Subject: [Git][ghc/ghc][master] validDerivPred: Reject exotic constraints in IrredPreds Message-ID: <643dcba33a43f_178e7480f7f64711e5@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 12 changed files: - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Validity.hs - docs/users_guide/9.8.1-notes.rst - + testsuite/tests/deriving/should_compile/T22696a.hs - + testsuite/tests/deriving/should_compile/T22696c.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/deriving/should_compile/drv015.hs - testsuite/tests/deriving/should_compile/T14339.hs → testsuite/tests/deriving/should_fail/T14339.hs - + testsuite/tests/deriving/should_fail/T14339.stderr - + testsuite/tests/deriving/should_fail/T22696b.hs - + testsuite/tests/deriving/should_fail/T22696b.stderr - testsuite/tests/deriving/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -768,8 +768,8 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- Returns @Just p@ (where @p@ is the type of the Ct) if a Ct is -- suitable to be inferred in the context of a derived instance. -- Returns @Nothing@ if the Ct is too exotic. - -- See Note [Exotic derived instance contexts] for what - -- constitutes an exotic constraint. + -- See (VD2) in Note [Valid 'deriving' predicate] in + -- GHC.Tc.Validity for what constitutes an exotic constraint. get_good :: Ct -> Maybe PredType get_good ct | validDerivPred head_size p = Just p | otherwise = Nothing @@ -798,8 +798,9 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs min_theta_vars solved_wanteds -- This call to simplifyTop is purely for error reporting -- See Note [Error reporting for deriving clauses] - -- See also Note [Exotic derived instance contexts], which are caught - -- in this line of code. + -- See also Note [Valid 'deriving' predicate] in GHC.Tc.Validity, as this + -- line of code catches "exotic" constraints like the ones described in + -- (VD2) of that Note. ; simplifyTopImplic leftover_implic ; traceTc "GHC.Tc.Deriv" (ppr deriv_rhs $$ ppr min_theta) @@ -807,7 +808,7 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- Claim: the result instance declaration is guaranteed valid -- Hence no need to call: -- checkValidInstance tyvars theta clas inst_tys - -- See Note [Exotic derived instance contexts] + -- See Note [Valid 'deriving' predicate] in GHC.Tc.Validity ; return min_theta } @@ -1008,7 +1009,8 @@ error messages. In particular, if simplifyDeriv reaches a constraint that it cannot solve, which might include: 1. Insoluble constraints -2. "Exotic" constraints (See Note [Exotic derived instance contexts]) +2. "Exotic" constraints (See Note [Valid 'deriving' predicate] in + GHC.Tc.Validity) Then we report an error immediately in simplifyDeriv. @@ -1029,55 +1031,4 @@ And pass it to the simplifier. If the context (Foo a) is enough to discharge all the constraints in , then everything is hunky-dory. But if contains, say, an insoluble constraint, then (Foo a) won't be able to solve it, causing GHC to error. - -Note [Exotic derived instance contexts] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In a 'derived' instance declaration, we *infer* the context. It's a -bit unclear what rules we should apply for this; the Haskell report is -silent. Obviously, constraints like (Eq a) are fine, but what about - data T f a = MkT (f a) deriving( Eq ) -where we'd get an Eq (f a) constraint. That's probably fine too. - -One could go further: consider - data T a b c = MkT (Foo a b c) deriving( Eq ) - instance (C Int a, Eq b, Eq c) => Eq (Foo a b c) - -Notice that this instance (just) satisfies the Paterson termination -conditions. Then we *could* derive an instance decl like this: - - instance (C Int a, Eq b, Eq c) => Eq (T a b c) -even though there is no instance for (C Int a), because there just -*might* be an instance for, say, (C Int Bool) at a site where we -need the equality instance for T's. - -However, this seems pretty exotic, and it's quite tricky to allow -this, and yet give sensible error messages in the (much more common) -case where we really want that instance decl for C. - -So for now we simply require that the derived instance context -should have only type-variable constraints. - -Here is another example: - data Fix f = In (f (Fix f)) deriving( Eq ) -Here, if we are prepared to allow -XUndecidableInstances we -could derive the instance - instance Eq (f (Fix f)) => Eq (Fix f) -but this is so delicate that I don't think it should happen inside -'deriving'. If you want this, write it yourself! - -NB: if you want to lift this condition, make sure you still meet the -termination conditions! If not, the deriving mechanism generates -larger and larger constraints. Example: - data Succ a = S a - data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show - -Note the lack of a Show instance for Succ. First we'll generate - instance (Show (Succ a), Show a) => Show (Seq a) -and then - instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a) -and so on. Instead we want to complain of no instance for (Show (Succ a)). - -The bottom line -~~~~~~~~~~~~~~~ -Allow constraints which consist only of type variables, with no repeats. -} ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -1713,34 +1713,165 @@ The usual functional dependency checks also apply. Note [Valid 'deriving' predicate] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -validDerivPred checks for OK 'deriving' context. -See Note [Exotic derived instance contexts] in GHC.Tc.Deriv.Infer. However the predicate is -here because it is quite similar to checkInstTermination. - -It checks for two things: - -(VD1) The Paterson conditions; see Note [Paterson conditions] - Not on do we want to check for termination (of course), but it also - deals with a nasty corner case: - instance C a b => D (T a) where ... - Note that 'b' isn't a parameter of T. This gives rise to all sorts of - problems; in particular, it's hard to compare solutions for equality - when finding the fixpoint, and that means the inferContext loop does - not converge. See #5287, #21302 - -(VD2) No type constructors; no foralls, no equalities: - see Note [Exotic derived instance contexts] in GHC.Tc.Deriv.Infer - - We check the no-type-constructor bit using tyConsOfType. - Wrinkle: we look only at the /visible/ arguments of the class type - constructor. Including the non-visible arguments can cause the following, - perfectly valid instance to be rejected: - class Category (cat :: k -> k -> *) where ... - newtype T (c :: * -> * -> *) a b = MkT (c a b) - instance Category c => Category (T c) where ... - since the first argument to Category is a non-visible *, which has a - type constructor! See #11833. +In a 'derived' instance declaration, we *infer* the context. It's a bit unclear +what rules we should apply for this; the Haskell report is silent. Obviously, +constraints like `Eq a` are fine, but what about + data T f a = MkT (f a) deriving Eq + +where we'd get an `Eq (f a)` constraint. That's probably fine too. + +On the other hand, we don't want to allow *every* inferred constraint, as there +are some particularly complex constraints that are tricky to handle. If GHC +encounters a constraint that is too complex, it will reject it, and you will +have to use StandaloneDeriving to manually specify the instance context that +you want. + +There are two criteria for a constraint inferred by a `deriving` clause to be +considered valid, which are described below as (VD1) and (VD2). (Here, "VD" +stands for "valid deriving".) `validDerivPred` implements these checks. While +`validDerivPred` is similar to other things defined in GHC.Tc.Deriv.Infer, we +define it here in GHC.Tc.Validity because it is quite similar to +`checkInstTermination`. + +----------------------------------- +-- (VD1) The Paterson conditions -- +----------------------------------- + +Constraints must satisfy the Paterson conditions (see Note [Paterson +conditions]) to be valid. Not only does this check for termination (of course), +but it also deals with a nasty corner case: + + instance C a b => D (T a) where ... + +Note that `b` isn't a parameter of T. This gives rise to all sorts of +problems; in particular, it's hard to compare solutions for equality when +finding the fixpoint, and that means the +GHC.Tc.Deriv.Infer.simplifyInstanceContexts loop does not converge. +See #5287 and #21302. + +Another common situation in which a derived instance's context fails to meet +the Paterson conditions is when a constraint mentions a type variable more +often than the instance head, e.g., + + data Fix f = In (f (Fix f)) deriving Eq + +This would result in the following derived `Eq` instance: + + instance Eq (f (Fix f)) => Eq (Fix f) + +Because `f` is mentioned more often in the `Eq (f (Fix f))` constraint than in +the instance head `Eq (Fix f)`, GHC rejects this instance. + +This is a somewhat contentious restriction, and some have suggested that +instances like this one should be accepted if UndecidableInstances is enabled +(see #15868 for one such discussion). If we *do* lift this restriction in the +future, we should make sure to still meet the termination conditions. If not, +the deriving mechanism generates larger and larger constraints. Example: + + data Succ a = S a + data Seq a = Cons a (Seq (Succ a)) | Nil deriving Show + +Note the lack of a Show instance for Succ. First we'll generate: + + instance (Show (Succ a), Show a) => Show (Seq a) + +and then: + + instance (Show (Succ (Succ a)), Show (Succ a), Show a) => Show (Seq a) + +and so on. Instead we want to complain of no instance for (Show (Succ a)). + +--------------------------------- +-- (VD2) No exotic constraints -- +--------------------------------- + +A constraint must satisfy one of the following properties in order to be valid: + +* It is a `ClassPred` of the form `C a_1 ... a_n`, where C is a type class + constructor and a_1, ..., a_n are either raw type variables or applications + of type variables (e.g., `f a`). +* It is an `IrredPred` of the form `c a_1 ... a_n`, where `c` is a raw type + variable and a_1, ..., a_n are either raw type variables or applications of + type variables (e.g., `f a`). + +If a constraint does not meet either of these properties, it is considered +*exotic*. A constraint will be exotic if it contains: + +* Other type constructors (besides the class in a `ClassPred`), +* Foralls, or +* Equalities + +A common form of exotic constraint is one that mentions another type +constructor. For example, given the following: + + data NotAShowInstance + data Foo = MkFoo Int NotAShowInstance deriving Show + +GHC would attempt to generate the following derived `Show` instance: + + instance (Show Int, Show NotAShowInstance) => Show Foo + +Note that because there is a top-level `Show Int` instance, GHC is able to +simplify away the inferred `Show Int` constraint. However, it cannot do the +same for the `Show NotAShowInstance` constraint. One possibility would be to +generate this instance: + + instance Show NotAShowInstance => Show Foo + +But this is almost surely not what we want most of the time. For this reason, +we reject the constraint above as being exotic. + +Here are some other interesting examples: + +* Derived instances whose instance context would mention TypeError, such as the + code from the deriving/should_fail/T14339 test case, are exotic. For example: + + newtype Foo = Foo Int + + class Bar a where + bar :: a + + instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + + newtype Baz = Baz Foo + deriving Bar + + The `deriving Bar` clause would generate this instance: + + instance TypeError (Text "Boo") => Bar Baz + + The instance context is exotic, as `TypeError` is not a type constructor, and + `Text "Boo"` is not an application of type variables. As such, GHC rejects + it. This has the desirable side effect of causing the TypeError to fire in + the resulting error message. + +* The following `IrredPred`s are not exotic: + + instance c => C (T c a) + instance c a => C (T c a) + + This `IrredPred`, however, *is* exotic: + + instance c NotAShowInstance => C (T c) + + This is rejected for the same reasons that we do not permit a `ClassPred` + with a type constructor argument, such as the `Show NotAShowInstance` example + above. + +As part of implementing this check, GHC calls `tyConsOfType` on the arguments +of the constraint, ensuring that there are no other type constructors. +Wrinkle: for `ClassPred`s, we look only at the /visible/ arguments of the class +type constructor. Including the non-visible arguments can cause the following, +perfectly valid instance to be rejected: + + class Category (cat :: k -> k -> Type) where ... + newtype T (c :: Type -> Type -> Type) a b = MkT (c a b) + instance Category c => Category (T c) where ... + +since the first argument to `Category` is a non-visible `Type`, which has a type +constructor! See #11833. Note [Equality class instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1753,23 +1884,17 @@ validDerivPred :: PatersonSize -> PredType -> Bool -- See Note [Valid 'deriving' predicate] validDerivPred head_size pred = case classifyPredType pred of - EqPred {} -> False -- Reject equality constraints - ForAllPred {} -> False -- Rejects quantified predicates + EqPred {} -> False -- Reject equality constraints (VD2) + ForAllPred {} -> False -- Rejects quantified predicates (VD2) - ClassPred cls tys -> check_size (pSizeClassPred cls tys) - && isEmptyUniqSet (tyConsOfTypes visible_tys) + ClassPred cls tys -> check_size (pSizeClassPred cls tys) -- (VD1) + && isEmptyUniqSet (tyConsOfTypes visible_tys) -- (VD2) where - visible_tys = filterOutInvisibleTypes (classTyCon cls) tys -- (VD2) - - IrredPred {} -> check_size (pSizeType pred) - -- Very important that we do the "too many variable occurrences" - -- check here, via check_size. Example (test T21302): - -- instance c Eq a => Eq (BoxAssoc a) - -- data BAD = BAD (BoxAssoc Int) deriving( Eq ) - -- We don't want to accept an inferred predicate (c0 Eq Int) - -- from that `deriving(Eq)` clause, because the c0 is fresh, - -- so we'll think it's a "new" one, and loop in - -- GHC.Tc.Deriv.Infer.simplifyInstanceContexts + -- See the wrinkle about visible arguments in (VD2) + visible_tys = filterOutInvisibleTypes (classTyCon cls) tys + + IrredPred {} -> check_size (pSizeType pred) -- (VD1) + && isEmptyUniqSet (tyConsOfType pred) -- (VD2) where check_size pred_size = isNothing (pred_size `ltPatersonSize` head_size) ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -61,6 +61,32 @@ Compiler The point is that only the type S has a constructor with both fields "foo" and "bar", so this record update is unambiguous. +- Data types with ``deriving`` clauses now reject inferred instance contexts + that mention ``TypeError`` constraints (see :ref:`custom-errors`), such as + this one: :: + + newtype Foo = Foo Int + + class Bar a where + bar :: a + + instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + + newtype Baz = Baz Foo + deriving Bar + + Here, the derived ``Bar`` instance for ``Baz`` would look like this: :: + + instance TypeError (Text "Boo") => Bar Baz + + While GHC would accept this before, GHC 9.8 now rejects it, emitting "``Boo``" + in the resulting error message. If you really want to derive this instance and + defer the error to sites where the instance is used, you must do so manually + with :extension:`StandaloneDeriving`, e.g. :: + + deriving instance TypeError (Text "Boo") => Bar Baz + GHCi ~~~~ ===================================== testsuite/tests/deriving/should_compile/T22696a.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UndecidableInstances #-} +module T22696a where + +import GHC.TypeLits + +newtype Foo = Foo Int + +class Bar a where + bar :: a + +instance (TypeError (Text "Boo")) => Bar Foo where + bar = undefined + +newtype Baz = Baz Foo + +deriving instance TypeError (Text "Boo") => Bar Baz ===================================== testsuite/tests/deriving/should_compile/T22696c.hs ===================================== @@ -0,0 +1,24 @@ +module T22696c where + +class C a where + m :: a + +data S1 c a where + MkS1 :: c => S1 c a +instance c => C (S1 c a) where + m = MkS1 + +data S2 c a where + MkS2 :: c a => S2 c a +instance c a => C (S2 c a) where + m = MkS2 + +newtype T1 c a = MkT1 (S1 c a) deriving C +newtype T2 c a = MkT2 (S2 c a) deriving C + -- The inferred instances would be: + -- + -- instance c => C (T1 c a) + -- instance c a => C (T2 c a) + -- + -- These are valid instance context for the reasons described in + -- (VD2) in Note [Valid 'deriving' predicate] in GHC.Tc.Validity. ===================================== testsuite/tests/deriving/should_compile/all.T ===================================== @@ -101,7 +101,6 @@ test('T13919', normal, compile, ['']) test('T13998', normal, compile, ['']) test('T14045b', normal, compile, ['']) test('T14094', normal, compile, ['']) -test('T14339', normal, compile, ['']) test('T14331', normal, compile, ['']) test('T14332', normal, compile, ['']) test('T14578', normal, compile, ['-ddump-deriv -dsuppress-uniques']) @@ -140,3 +139,5 @@ test('T20501', normal, compile, ['']) test('T20719', normal, compile, ['']) test('T20994', normal, compile, ['']) test('T22167', normal, compile, ['']) +test('T22696a', normal, compile, ['']) +test('T22696c', normal, compile, ['']) ===================================== testsuite/tests/deriving/should_compile/drv015.hs ===================================== @@ -1,12 +1,12 @@ --- July 07: I'm changing this from "should_compile" to "should_fail". --- It would generate an instance decl like +-- This will generate an instance decl like: +-- -- instance (Show (f a), Show (g a)) => Show (Pair1 f g a) --- and that is not Haskell 98. -- --- See Note [Exotic derived instance contexts] in GHC.Tc.Solver. --- The rule is simple: the context of a derived instance decl must --- contain constraints of form (C tyvar) only, just as H98. +-- Although the Haskell Report would not permit this instance if written out +-- explicitly, it does not say anything about whether it is acceptable for a +-- *derived* instance to generate it. As such, we allow this in GHC. +-- See Note [Valid 'deriving' predicate] in GHC.Tc.Validity. module ShouldCompile where ===================================== testsuite/tests/deriving/should_compile/T14339.hs → testsuite/tests/deriving/should_fail/T14339.hs ===================================== @@ -16,10 +16,10 @@ instance (TypeError (Text "Boo")) => Bar Foo where newtype Baz = Baz Foo deriving Bar --- Apparently we derive +-- We derive: +-- -- instance TypeError (Text "Boo") => Bar Baz -- --- Is that really what we want? It defers the type --- error... surely we should use standalone deriving --- if that is what we want? --- See GHC.Tc.Validity.validDerivPred and #22696. \ No newline at end of file +-- And error out due to the TypeError. See also +-- deriving/should_compile/T22696a, which uses StandaloneDeriving to write a +-- valid instance with a TypeError constraint in its instance context. ===================================== testsuite/tests/deriving/should_fail/T14339.stderr ===================================== @@ -0,0 +1,4 @@ + +T14339.hs:17:12: error: [GHC-64725] + • Boo + • When deriving the instance for (Bar Baz) ===================================== testsuite/tests/deriving/should_fail/T22696b.hs ===================================== @@ -0,0 +1,19 @@ +module T22696b where + +class C a where + m :: a + +data S c where + MkS :: c Int => S c + +instance c Int => C (S c) where + m = MkS + +newtype T c = MkT (S c) + deriving C + -- The inferred instance would be: + -- + -- instance c Int => C (T c) + -- + -- And we want to reject this instance due to the reasons mentioned in + -- (VD2) in Note [Valid 'deriving' predicate] in GHC.Tc.Validity. ===================================== testsuite/tests/deriving/should_fail/T22696b.stderr ===================================== @@ -0,0 +1,5 @@ + +T22696b.hs:13:12: error: [GHC-05617] + • Could not solve: ‘c Int’ + arising from the 'deriving' clause of a data type declaration + • When deriving the instance for (C (T c)) ===================================== testsuite/tests/deriving/should_fail/all.T ===================================== @@ -69,6 +69,7 @@ test('T12801', normal, compile_fail, ['']) test('T13154c', normal, compile_fail, ['']) test('T14365', [extra_files(['T14365B.hs','T14365B.hs-boot'])], multimod_compile_fail, ['T14365A','']) +test('T14339', normal, compile_fail, ['']) test('T14728a', normal, compile_fail, ['']) test('T14728b', normal, compile_fail, ['']) test('T14916', normal, compile_fail, ['']) @@ -84,3 +85,4 @@ test('T21087', normal, compile_fail, ['']) test('T21087b', [extra_files(['T21087b_aux.hs','T21087b_aux.hs-boot'])], multimod_compile_fail, ['T21087b', '']) test('T21302', normal, compile_fail, ['']) test('T21871', normal, compile_fail, ['']) +test('T22696b', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0158c5f10869f567091c4f0cd9b127c0dc5cc413 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0158c5f10869f567091c4f0cd9b127c0dc5cc413 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 17 22:44:26 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 17 Apr 2023 18:44:26 -0400 Subject: [Git][ghc/ghc][master] Misc cleanup Message-ID: <643dcbcaf07f6_178e747ecf14c74648@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 13 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/StgToJS/Linker/Utils.hs - libraries/base/GHC/Event/Manager.hs - libraries/base/GHC/Event/TimerManager.hs - libraries/base/GHC/Fingerprint.hs - libraries/base/GHC/Fingerprint/Type.hs - libraries/base/GHC/IO/Encoding/Types.hs - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2715,7 +2715,7 @@ genCCall64 addr conv dest_regs args = do <- load_args prom_args (allIntArgRegs platform) (allFPArgRegs platform) nilOL nilOL - let used_regs rs as = reverse (drop (length rs) (reverse as)) + let used_regs rs as = dropTail (length rs) as fregs_used = used_regs fregs (allFPArgRegs platform) aregs_used = used_regs aregs (allIntArgRegs platform) return (stack_args, aregs_used, fregs_used, load_args_code ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -556,7 +556,8 @@ chunkify xs where n_xs = length xs split [] = [] - split xs = take mAX_TUPLE_SIZE xs : split (drop mAX_TUPLE_SIZE xs) + split xs = let (as, bs) = splitAt mAX_TUPLE_SIZE xs + in as : split bs {- ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -1752,13 +1752,12 @@ newLvlVar lvld_rhs join_arity_maybe is_mk_static cloneCaseBndrs :: LevelEnv -> Level -> [Var] -> LvlM (LevelEnv, [Var]) cloneCaseBndrs env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env }) new_lvl vs - = do { us <- getUniqueSupplyM - ; let (subst', vs') = cloneBndrs subst us vs + = do { (subst', vs') <- cloneBndrs subst vs -- N.B. We are not moving the body of the case, merely its case -- binders. Consequently we should *not* set le_ctxt_lvl and -- le_join_ceil. See Note [Setting levels when floating -- single-alternative cases]. - env' = env { le_lvl_env = addLvls new_lvl lvl_env vs' + ; let env' = env { le_lvl_env = addLvls new_lvl lvl_env vs' , le_subst = subst' , le_env = foldl' add_id id_env (vs `zip` vs') } @@ -1773,13 +1772,13 @@ cloneLetVars :: RecFlag -> LevelEnv -> Level -> [InVar] cloneLetVars is_rec env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env }) dest_lvl vs - = do { us <- getUniqueSupplyM - ; let vs1 = map zap vs + = do { let vs1 = map zap vs -- See Note [Zapping the demand info] - (subst', vs2) = case is_rec of - NonRecursive -> cloneBndrs subst us vs1 - Recursive -> cloneRecIdBndrs subst us vs1 - prs = vs `zip` vs2 + ; (subst', vs2) <- case is_rec of + NonRecursive -> cloneBndrs subst vs1 + Recursive -> cloneRecIdBndrs subst vs1 + + ; let prs = vs `zip` vs2 env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs2 , le_subst = subst' , le_env = foldl' add_id id_env prs } ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -3461,9 +3461,8 @@ cloneBndrSM env@(SE { se_subst = subst }) bndr cloneRecBndrsSM :: SpecEnv -> [Id] -> SpecM (SpecEnv, [Id]) cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs - = do { us <- getUniqueSupplyM - ; let (subst', bndrs') = Core.cloneRecIdBndrs subst us bndrs - env' = env { se_subst = subst' } + = do { (subst', bndrs') <- Core.cloneRecIdBndrs subst bndrs + ; let env' = env { se_subst = subst' } ; return (env', bndrs') } newDictBndr :: SpecEnv -> CoreBndr -> SpecM (SpecEnv, CoreBndr) ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -213,12 +213,11 @@ mkWwBodies opts fun_id arg_vars res_ty demands res_cpr -- Clone and prepare arg_vars of the original fun RHS -- See Note [Freshen WW arguments] -- and Note [Zap IdInfo on worker args] - ; uniq_supply <- getUniqueSupplyM ; let args_free_tcvs = tyCoVarsOfTypes (res_ty : map varType arg_vars) empty_subst = mkEmptySubst (mkInScopeSet args_free_tcvs) zapped_arg_vars = map zap_var arg_vars - (subst, cloned_arg_vars) = cloneBndrs empty_subst uniq_supply zapped_arg_vars - res_ty' = substTyUnchecked subst res_ty + ; (subst, cloned_arg_vars) <- cloneBndrs empty_subst zapped_arg_vars + ; let res_ty' = substTyUnchecked subst res_ty init_str_marks = map (const NotMarkedStrict) cloned_arg_vars ; (useful1, work_args_str, wrap_fn_str, fn_args) ===================================== compiler/GHC/Core/Subst.hs ===================================== @@ -417,11 +417,12 @@ cloneIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id]) cloneIdBndrs subst us ids = mapAccumL (clone_id subst) subst (ids `zip` uniqsFromSupply us) -cloneBndrs :: Subst -> UniqSupply -> [Var] -> (Subst, [Var]) +cloneBndrs :: MonadUnique m => Subst -> [Var] -> m (Subst, [Var]) -- Works for all kinds of variables (typically case binders) -- not just Ids -cloneBndrs subst us vs - = mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` uniqsFromSupply us) +cloneBndrs subst vs + = do us <- getUniquesM + pure $ mapAccumL (\subst (v, u) -> cloneBndr subst u v) subst (vs `zip` us) cloneBndr :: Subst -> Unique -> Var -> (Subst, Var) cloneBndr subst uniq v @@ -429,12 +430,11 @@ cloneBndr subst uniq v | otherwise = clone_id subst subst (v,uniq) -- Works for coercion variables too -- | Clone a mutually recursive group of 'Id's -cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id]) -cloneRecIdBndrs subst us ids - = (subst', ids') - where - (subst', ids') = mapAccumL (clone_id subst') subst - (ids `zip` uniqsFromSupply us) +cloneRecIdBndrs :: MonadUnique m => Subst -> [Id] -> m (Subst, [Id]) +cloneRecIdBndrs subst ids + = do us <- getUniquesM + let (subst', ids') = mapAccumL (clone_id subst') subst (ids `zip` us) + pure (subst', ids') -- Just like substIdBndr, except that it always makes a new unique -- It is given the unique to use ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -41,6 +41,7 @@ import GHC.StgToJS.Types import Prelude import GHC.Platform +import GHC.Utils.Misc import Data.List (isPrefixOf) import System.IO import Data.Char (isSpace) @@ -299,7 +300,7 @@ getJsOptions handle = do parseJsOptions :: String -> [JSOption] parseJsOptions xs = go xs where - trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace + trim = dropWhileEndLE isSpace . dropWhile isSpace go [] = [] go xs = let (tok, rest) = break (== ',') xs tok' = trim tok ===================================== libraries/base/GHC/Event/Manager.hs ===================================== @@ -467,7 +467,7 @@ onFdEvent mgr fd evs IT.delete (fromIntegral fd) tbl >>= maybe (return []) (selectCallbacks tbl) forM_ fdds $ \(FdData reg _ cb) -> cb reg evs where - -- | Here we look through the list of registrations for the fd of interest + -- Here we look through the list of registrations for the fd of interest -- and sort out which match the events that were triggered. We, -- -- 1. re-arm the fd as appropriate ===================================== libraries/base/GHC/Event/TimerManager.hs ===================================== @@ -175,7 +175,7 @@ step mgr = do state `seq` return (state == Running) where - -- | Call all expired timer callbacks and return the time to the + -- Call all expired timer callbacks and return the time to the -- next timeout. mkTimeout :: IO Timeout mkTimeout = do ===================================== libraries/base/GHC/Fingerprint.hs ===================================== @@ -84,7 +84,7 @@ getFileHash path = withBinaryFile path ReadMode $ \h -> where _BUFSIZE = 4096 - -- | Loop over _BUFSIZE sized chunks read from the handle, + -- Loop over _BUFSIZE sized chunks read from the handle, -- passing the callback a block of bytes and its size. processChunks :: Handle -> (Ptr Word8 -> Int -> IO ()) -> IO () processChunks h f = allocaBytes _BUFSIZE $ \arrPtr -> ===================================== libraries/base/GHC/Fingerprint/Type.hs ===================================== @@ -30,7 +30,7 @@ data Fingerprint = Fingerprint {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 instance Show Fingerprint where show (Fingerprint w1 w2) = hex16 w1 ++ hex16 w2 where - -- | Formats a 64 bit number as 16 digits hex. + -- Formats a 64 bit number as 16 digits hex. hex16 :: Word64 -> String hex16 i = let hex = showHex i "" in replicate (16 - length hex) '0' ++ hex ===================================== libraries/base/GHC/IO/Encoding/Types.hs ===================================== @@ -119,7 +119,6 @@ data TextEncoding -- | @since 4.3.0.0 instance Show TextEncoding where - -- | Returns the value of 'textEncodingName' show te = textEncodingName te -- | @since 4.4.0.0 ===================================== utils/deriveConstants/Main.hs ===================================== @@ -27,7 +27,6 @@ needing to run the program, by inspecting the object file using 'nm'. import Control.Monad (when, unless) import Data.Bits (shiftL) -import Data.Char (toLower) import Data.List (elemIndex, stripPrefix, intercalate) import Data.Map (Map) import qualified Data.Map as Map View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1036481824fed7f8d5c9f70816b3dadd22098e42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1036481824fed7f8d5c9f70816b3dadd22098e42 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 00:00:36 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 17 Apr 2023 20:00:36 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/zap-void-StgOpApp-args Message-ID: <643ddda45c9ec_178e7497c6344802ef@gitlab.mail> Matthew Craven pushed new branch wip/zap-void-StgOpApp-args at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/zap-void-StgOpApp-args You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 00:22:50 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 17 Apr 2023 20:22:50 -0400 Subject: [Git][ghc/ghc][wip/zap-void-StgOpApp-args] Experiment: Try zapping StgOpApp void args in Unarise Message-ID: <643de2da2c5f0_178e749f598b8804e4@gitlab.mail> Matthew Craven pushed to branch wip/zap-void-StgOpApp-args at Glasgow Haskell Compiler / GHC Commits: c517c838 by Matthew Craven at 2023-04-17T20:22:22-04:00 Experiment: Try zapping StgOpApp void args in Unarise - - - - - 1 changed file: - compiler/GHC/Stg/Unarise.hs Changes: ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -534,7 +534,7 @@ unariseExpr rho (StgConApp dc n args ty_args) return $ (StgConApp dc n args' (map stgArgType args')) unariseExpr rho (StgOpApp op args ty) - = return (StgOpApp op (unariseFunArgs rho args) ty) + = return (StgOpApp op (unariseConArgs rho args) ty) unariseExpr rho (StgCase scrut bndr alt_ty alts) -- tuple/sum binders in the scrutinee can always be eliminated View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c517c83891145cd6c9352aed5008bef6c1934f1f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c517c83891145cd6c9352aed5008bef6c1934f1f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 00:24:10 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 17 Apr 2023 20:24:10 -0400 Subject: [Git][ghc/ghc][wip/zap-void-StgOpApp-args] Experiment: Try zapping StgOpApp void args in Unarise Message-ID: <643de32a587a6_178e749f5796480687@gitlab.mail> Matthew Craven pushed to branch wip/zap-void-StgOpApp-args at Glasgow Haskell Compiler / GHC Commits: 22048b91 by Matthew Craven at 2023-04-17T20:23:55-04:00 Experiment: Try zapping StgOpApp void args in Unarise - - - - - 5 changed files: - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Layout.hs - compiler/GHC/StgToCmm/Prim.hs Changes: ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -534,7 +534,7 @@ unariseExpr rho (StgConApp dc n args ty_args) return $ (StgConApp dc n args' (map stgArgType args')) unariseExpr rho (StgOpApp op args ty) - = return (StgOpApp op (unariseFunArgs rho args) ty) + = return (StgOpApp op (unariseConArgs rho args) ty) unariseExpr rho (StgCase scrut bndr alt_ty alts) -- tuple/sum binders in the scrutinee can always be eliminated ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -642,7 +642,7 @@ isSimpleOp (StgFCallOp (CCall (CCallSpec _ _ safe)) _) _ = return $! not (playSa -- dataToTag# evaluates its argument, see Note [dataToTag# magic] in GHC.Core.Opt.ConstantFold isSimpleOp (StgPrimOp DataToTagOp) _ = return False isSimpleOp (StgPrimOp op) stg_args = do - arg_exprs <- getNonVoidArgAmodes stg_args + arg_exprs <- getArgAmodes (assertNonVoidStgArgs stg_args) cfg <- getStgToCmmConfig -- See Note [Inlining out-of-line primops and heap checks] return $! shouldInlinePrimOp cfg op arg_exprs @@ -971,7 +971,7 @@ maybeAltHeapCheck (GcInAlts regs, ReturnedTo lret off) code = cgConApp :: DataCon -> ConstructorNumber -> [StgArg] -> FCode ReturnKind cgConApp con mn stg_args | isUnboxedTupleDataCon con -- Unboxed tuple: assign and return - = do { arg_exprs <- getNonVoidArgAmodes stg_args + = do { arg_exprs <- getArgAmodes (assertNonVoidStgArgs stg_args) ; tickyUnboxedTupleReturn (length arg_exprs) ; emitReturn arg_exprs } ===================================== compiler/GHC/StgToCmm/Foreign.hs ===================================== @@ -6,6 +6,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE ViewPatterns #-} + module GHC.StgToCmm.Foreign ( cgForeignCall, emitPrimCall, @@ -672,20 +674,16 @@ getFCallArgs :: -- It's (b) that makes this differ from getNonVoidArgAmodes -- Precondition: args and typs have the same length -- See Note [Unlifted boxed arguments to foreign calls] -getFCallArgs args typ +getFCallArgs (assertNonVoidStgArgs -> args) typ = do { mb_cmms <- mapM get (zipEqual "getFCallArgs" args (collectStgFArgTypes typ)) ; return (catMaybes mb_cmms) } where get (arg,typ) - | null arg_reps - = return Nothing - | otherwise - = do { cmm <- getArgAmode (NonVoid arg) + = do { cmm <- getArgAmode arg ; profile <- getProfile ; return (Just (add_shim profile typ cmm, hint)) } where - arg_ty = stgArgType arg - arg_reps = typePrimRep arg_ty + arg_ty = stgArgType (fromNonVoid arg) hint = typeForeignHint arg_ty -- The minimum amount of information needed to determine ===================================== compiler/GHC/StgToCmm/Layout.hs ===================================== @@ -27,7 +27,7 @@ module GHC.StgToCmm.Layout ( getHpRelOffset, ArgRep(..), toArgRep, argRepSizeW, -- re-exported from GHC.StgToCmm.ArgRep - getArgAmode, getNonVoidArgAmodes + getArgAmode, getArgAmodes, getNonVoidArgAmodes ) where @@ -601,6 +601,9 @@ getArgAmode :: NonVoid StgArg -> FCode CmmExpr getArgAmode (NonVoid (StgVarArg var)) = idInfoToAmode <$> getCgIdInfo var getArgAmode (NonVoid (StgLitArg lit)) = cgLit lit +getArgAmodes :: [NonVoid StgArg] -> FCode [CmmExpr] +getArgAmodes = mapM getArgAmode + getNonVoidArgAmodes :: [StgArg] -> FCode [CmmExpr] -- NB: Filters out void args, -- so the result list may be shorter than the argument list ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -20,6 +20,7 @@ import GHC.Prelude hiding ((<*>)) import GHC.Platform import GHC.Platform.Profile +import GHC.StgToCmm.Closure import GHC.StgToCmm.Config import GHC.StgToCmm.Layout import GHC.StgToCmm.Foreign @@ -78,11 +79,11 @@ cgOpApp (StgFCallOp fcall ty) stg_args res_ty cgOpApp (StgPrimOp primop) args res_ty = do cfg <- getStgToCmmConfig - cmm_args <- getNonVoidArgAmodes args + cmm_args <- getArgAmodes (assertNonVoidStgArgs args) cmmPrimOpApp cfg primop cmm_args (Just res_ty) cgOpApp (StgPrimCallOp primcall) args _res_ty - = do { cmm_args <- getNonVoidArgAmodes args + = do { cmm_args <- getArgAmodes (assertNonVoidStgArgs args) ; let fun = CmmLit (CmmLabel (mkPrimCallLabel primcall)) ; emitCall (NativeNodeCall, NativeReturn) fun cmm_args } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22048b914dd885e6798d7b64cc3e7c9eaf2ec413 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22048b914dd885e6798d7b64cc3e7c9eaf2ec413 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 02:25:24 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 17 Apr 2023 22:25:24 -0400 Subject: [Git][ghc/ghc][wip/zap-void-StgOpApp-args] StgToCmm: void argument to SeqOp was unarised away Message-ID: <643dff9491c06_178e74be535ac856b0@gitlab.mail> Matthew Craven pushed to branch wip/zap-void-StgOpApp-args at Glasgow Haskell Compiler / GHC Commits: ee5510b9 by Matthew Craven at 2023-04-17T22:24:03-04:00 StgToCmm: void argument to SeqOp was unarised away - - - - - 1 changed file: - compiler/GHC/StgToCmm/Expr.hs Changes: ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -71,7 +71,7 @@ cgExpr (StgApp fun args) = cgIdApp fun args -- seq# a s ==> a -- See Note [seq# magic] in GHC.Core.Opt.ConstantFold -cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _res_ty) = +cgExpr (StgOpApp (StgPrimOp SeqOp) [StgVarArg a] _res_ty) = cgIdApp a [] -- dataToTag# :: a -> Int# @@ -541,7 +541,7 @@ The special case for seq# in cgCase does this: is the same as the return convention for just 'a') -} -cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a, _] _) bndr alt_type alts +cgCase (StgOpApp (StgPrimOp SeqOp) [StgVarArg a] _) bndr alt_type alts = -- Note [Handle seq#] -- And see Note [seq# magic] in GHC.Core.Opt.ConstantFold -- Use the same return convention as vanilla 'a'. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee5510b9747bd8783fe2bd8513d4f98c7f93a438 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee5510b9747bd8783fe2bd8513d4f98c7f93a438 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 03:08:54 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Mon, 17 Apr 2023 23:08:54 -0400 Subject: [Git][ghc/ghc][wip/zap-void-StgOpApp-args] filter out voidrep args in collectStgFArgTypes Message-ID: <643e09c655968_178e74c966c64861ba@gitlab.mail> Matthew Craven pushed to branch wip/zap-void-StgOpApp-args at Glasgow Haskell Compiler / GHC Commits: 745b3f7e by Matthew Craven at 2023-04-17T23:08:21-04:00 filter out voidrep args in collectStgFArgTypes - - - - - 1 changed file: - compiler/GHC/StgToCmm/Foreign.hs Changes: ===================================== compiler/GHC/StgToCmm/Foreign.hs ===================================== @@ -720,20 +720,23 @@ collectStgFArgTypes = go [] go _ (CastTy{}) = panic "myCollectTypeArgs: CastTy" go _ (CoercionTy{}) = panic "myCollectTypeArgs: CoercionTy" go bs (FunTy {ft_arg = arg, ft_res=res}) = - go (typeToStgFArgType arg:bs) res + case typeToStgFArgType arg of + Just b -> go (b : bs) res + Nothing -> go bs res -- Choose the offset based on the type. For anything other -- than an unlifted boxed type, there is no offset. -- See Note [Unlifted boxed arguments to foreign calls] -typeToStgFArgType :: Type -> StgFArgType +typeToStgFArgType :: Type -> Maybe StgFArgType typeToStgFArgType typ - | tycon == arrayPrimTyCon = StgArrayType - | tycon == mutableArrayPrimTyCon = StgArrayType - | tycon == smallArrayPrimTyCon = StgSmallArrayType - | tycon == smallMutableArrayPrimTyCon = StgSmallArrayType - | tycon == byteArrayPrimTyCon = StgByteArrayType - | tycon == mutableByteArrayPrimTyCon = StgByteArrayType - | otherwise = StgPlainType + | tycon == arrayPrimTyCon = Just StgArrayType + | tycon == mutableArrayPrimTyCon = Just StgArrayType + | tycon == smallArrayPrimTyCon = Just StgSmallArrayType + | tycon == smallMutableArrayPrimTyCon = Just StgSmallArrayType + | tycon == byteArrayPrimTyCon = Just StgByteArrayType + | tycon == mutableByteArrayPrimTyCon = Just StgByteArrayType + | isZeroBitTy typ = Nothing + | otherwise = Just StgPlainType where -- Should be a tycon app, since this is a foreign call. We look -- through newtypes so the offset does not change if a user replaces View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745b3f7e502c0ffd1410f46524d317cb97c5daf8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745b3f7e502c0ffd1410f46524d317cb97c5daf8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 07:32:03 2023 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 18 Apr 2023 03:32:03 -0400 Subject: [Git][ghc/ghc] Pushed new tag ghc-9.4.5-release Message-ID: <643e477328406_178e7410e4dd8c92734@gitlab.mail> Zubin pushed new tag ghc-9.4.5-release at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/ghc-9.4.5-release You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 08:56:49 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 18 Apr 2023 04:56:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/js-base_access Message-ID: <643e5b51d2b5_178e74124fb7502050f1@gitlab.mail> Josh Meredith pushed new branch wip/js-base_access at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/js-base_access You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 11:16:03 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 18 Apr 2023 07:16:03 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 36 commits: Allow WARNING pragmas to be controlled with custom categories Message-ID: <643e7bf3b5ff4_178e7414acec0c2309f8@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 416cfc2f by Adam Gundry at 2023-04-14T10:19:58+00:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - a0118ecc by Adam Gundry at 2023-04-14T10:19:58+00:00 Move mention of warning groups change to 9.8.1 release notes - - - - - 6cf9d8e7 by Ben Gamari at 2023-04-14T10:19:58+00:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 88896c2e by Joachim Breitner at 2023-04-14T10:19:58+00:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 967e1d37 by Li-yao Xia at 2023-04-14T10:19:58+00:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 2f1b29ed by Teo Camarasu at 2023-04-14T10:19:58+00:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - 984f5b4b by Teo Camarasu at 2023-04-14T10:19:58+00:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 59c0d8c9 by David Feuer at 2023-04-14T10:19:58+00:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - 6fbe63ed by Bodigrim at 2023-04-14T10:19:58+00:00 Improve documentation of atomicModifyMutVar2# - - - - - 1deb445d by Cheng Shao at 2023-04-14T10:19:58+00:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - 079ce35d by Cheng Shao at 2023-04-14T10:19:58+00:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 88723364 by Bodigrim at 2023-04-14T10:19:58+00:00 Improve documentation for resizing of byte arrays - - - - - 5f54f18b by Ryan Scott at 2023-04-14T10:19:58+00:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - ad752445 by David Feuer at 2023-04-14T10:19:58+00:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - b11d0785 by David Feuer at 2023-04-14T10:19:58+00:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - 2beae1d3 by Simon Peyton Jones at 2023-04-14T10:19:58+00:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - ec5cc9e0 by Ryan Scott at 2023-04-14T10:19:58+00:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - c4461053 by Ubuntu at 2023-04-14T10:19:58+00:00 Run script - - - - - 127b885f by Ubuntu at 2023-04-14T10:19:58+00:00 Work around #22451 - - - - - ab484414 by Ubuntu at 2023-04-14T10:19:58+00:00 Refine run script - - - - - 0d4405f9 by Ben Gamari at 2023-04-14T10:19:58+00:00 CheckGC - - - - - f8b86712 by Ubuntu at 2023-04-14T10:19:58+00:00 llvm: Sequential consistency - - - - - 07edf5ae by Ubuntu at 2023-04-14T10:19:58+00:00 C++ fixes - - - - - 410fa293 by Ubuntu at 2023-04-14T10:19:58+00:00 rts: sequential consistency - - - - - caf48b62 by Ubuntu at 2023-04-14T10:19:59+00:00 check-gc: fix large objects - - - - - 093145b7 by Ubuntu at 2023-04-14T10:19:59+00:00 check-gc on GC - - - - - e7664804 by Ubuntu at 2023-04-14T10:19:59+00:00 run - - - - - ece06e2d by Ubuntu at 2023-04-14T10:19:59+00:00 run - - - - - b151e731 by Ubuntu at 2023-04-14T10:19:59+00:00 run.sh: update - - - - - b86bc529 by Ubuntu at 2023-04-14T10:19:59+00:00 run: refactor - - - - - 124184b0 by Ubuntu at 2023-04-17T21:04:47+00:00 Use C11 atomics - - - - - a109e4f5 by Ubuntu at 2023-04-17T21:05:03+00:00 Disable selector optimisation - - - - - 5f3584a5 by Ubuntu at 2023-04-18T09:31:38+00:00 Fix thunk update further - - - - - fdeab17e by Ubuntu at 2023-04-18T10:53:15+00:00 Add acquire fence in WHITEHOLE - - - - - c1cfb5f8 by Ubuntu at 2023-04-18T10:53:42+00:00 whitespace - - - - - 177d3681 by Ubuntu at 2023-04-18T10:53:48+00:00 Note - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Unit/Module/Warnings.hs - compiler/GHC/Utils/Error.hs - docs/users_guide/9.6.1-notes.rst - docs/users_guide/9.8.1-notes.rst - docs/users_guide/exts/pragmas.rst - docs/users_guide/using-warnings.rst - hadrian/src/Oracles/Setting.hs - libraries/base/Data/Data.hs - libraries/base/Data/IORef.hs - libraries/base/Data/Typeable/Internal.hs - libraries/base/GHC/Conc/Sync.hs - libraries/base/GHC/IORef.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4106472154c2f815129acb6149eab933bdc390c...177d368192b501e9ba016996e5e88f1bc3b2faf2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4106472154c2f815129acb6149eab933bdc390c...177d368192b501e9ba016996e5e88f1bc3b2faf2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 12:18:07 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 18 Apr 2023 08:18:07 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 150 commits: Allow WARNING pragmas to be controlled with custom categories Message-ID: <643e8a7f90a4_178e7415c7758023620@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - e85f1b7b by Ben Gamari at 2023-04-18T07:29:04-04:00 rts/IPE: Fix unused mutex warning - - - - - 05a4aa30 by Ubuntu at 2023-04-18T07:36:05-04:00 rts: C++ fixes - - - - - 6a2324f8 by Ben Gamari at 2023-04-18T07:36:08-04:00 compiler: Style fixes - - - - - 9546df64 by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS, but it's a data race nevertheless. - - - - - 0276f6ee by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Silence spurious data races in ticky counters Previously we would use non-atomic accesses when bumping ticky counters, which would result in spurious data race reports from ThreadSanitizer when the threaded RTS was in use. - - - - - 63ac3972 by Ben Gamari at 2023-04-18T07:36:08-04:00 Improve TSAN documentation - - - - - 840fbd9e by Ben Gamari at 2023-04-18T07:36:08-04:00 compiler/cmm: Ensure that dump output has proc name Previously dump output from the early Cmm passes would not be labelled with a proc label. - - - - - fe417254 by Ben Gamari at 2023-04-18T07:36:08-04:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 61512488 by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Fix various data races - - - - - 1c6daf8b by Ben Gamari at 2023-04-18T07:36:08-04:00 base: use atomic write when updating timer manager - - - - - 7ead0355 by Ben Gamari at 2023-04-18T07:36:08-04:00 Use relaxed atomics to manipulate TSO status fields - - - - - 33cfd077 by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Drop unnecessary atomic - - - - - 927b92fd by Ben Gamari at 2023-04-18T07:36:08-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers - - - - - 6c7d6088 by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Fix synchronization on thread blocking state - - - - - c1ef39b1 by Ben Gamari at 2023-04-18T07:36:08-04:00 rts: Relaxed load MutVar info table - - - - - 45a26ba4 by Ben Gamari at 2023-04-18T07:36:08-04:00 More principled treatment of acquire fences - - - - - 13684dd5 by Ben Gamari at 2023-04-18T07:36:08-04:00 Wordsmith Note - - - - - 28f40d26 by Ben Gamari at 2023-04-18T07:36:08-04:00 Use relaxed accesses in ticky bumping - - - - - 2983b735 by Ben Gamari at 2023-04-18T07:36:08-04:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - 7b4d62f8 by Ben Gamari at 2023-04-18T07:36:09-04:00 Things - - - - - 06afb9fe by Ben Gamari at 2023-04-18T07:36:09-04:00 rts: Relax info pointer stores - - - - - 9c370dd9 by Ubuntu at 2023-04-18T07:36:09-04:00 Work around #22451 - - - - - 6507ac82 by Ubuntu at 2023-04-18T07:36:09-04:00 llvm: Sequential consistency - - - - - 6ab3d2cd by Ubuntu at 2023-04-18T07:36:09-04:00 rts: sequential consistency - - - - - 8086060f by Ubuntu at 2023-04-18T07:36:09-04:00 ghc-prim: Use C11 atomics - - - - - 1a7fc46a by Ubuntu at 2023-04-18T07:36:09-04:00 Fix thunk update further - - - - - 36ab795a by Ubuntu at 2023-04-18T07:36:09-04:00 Add acquire fence in WHITEHOLE - - - - - 7f783c90 by Ubuntu at 2023-04-18T07:36:09-04:00 whitespace - - - - - 57907004 by Ubuntu at 2023-04-18T07:36:09-04:00 Note - - - - - e1e63aed by Ben Gamari at 2023-04-18T07:36:09-04:00 STM: relaxed - - - - - fecc19fb by Ubuntu at 2023-04-18T07:36:09-04:00 Run script - - - - - b32406bf by Ubuntu at 2023-04-18T07:36:09-04:00 Refine run script - - - - - ce510a0e by Ubuntu at 2023-04-18T07:36:09-04:00 run - - - - - 94ca254d by Ubuntu at 2023-04-18T07:36:09-04:00 Disable selector optimisation - - - - - b3548160 by Ben Gamari at 2023-04-18T07:36:09-04:00 CheckGC - - - - - f5f18a35 by Ubuntu at 2023-04-18T07:36:09-04:00 check-gc: fix large objects - - - - - d2a0aa5a by Ubuntu at 2023-04-18T07:36:09-04:00 check-gc on GC - - - - - 1899ed50 by Ben Gamari at 2023-04-18T07:40:24-04:00 ACQUIRE_FENCE - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/CodeGen.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/177d368192b501e9ba016996e5e88f1bc3b2faf2...1899ed5070d546653b9b4ce8173cc43cfa48b221 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/177d368192b501e9ba016996e5e88f1bc3b2faf2...1899ed5070d546653b9b4ce8173cc43cfa48b221 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 12:20:58 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 18 Apr 2023 08:20:58 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: validDerivPred: Reject exotic constraints in IrredPreds Message-ID: <643e8b2a61879_178e7415d2ce582364b0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - a8bd4732 by Matthew Pickering at 2023-04-18T08:20:49-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - e05b0ee6 by sheaf at 2023-04-18T08:20:54-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 30 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/44f834339cf9d7cb94c8cb348bc468147506f5ad...e05b0ee65fde4f220e51365648e8c497b2f2fa8e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/44f834339cf9d7cb94c8cb348bc468147506f5ad...e05b0ee65fde4f220e51365648e8c497b2f2fa8e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 12:24:15 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 18 Apr 2023 08:24:15 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] Add Note Message-ID: <643e8bef9b8bd_178e7415da338c24488b@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 37471bae by Ben Gamari at 2023-04-18T08:23:58-04:00 Add Note - - - - - 1 changed file: - rts/Updates.h Changes: ===================================== rts/Updates.h ===================================== @@ -12,6 +12,365 @@ #include "BeginPrivate.h" #endif +/* + * + * Note [Thunks, blackholes, and indirections] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Consider the following STG binding: + * + * thnk = {fv_0, fv_1} \u [] g x y; + * + * This binding is a updatable thunk carrying free variables `fv_0` and `fv_1`. + * Over its lifetime, this closure may transition through three states: + * + * 1. it starts life as a thunk, which carries with it free variables + * 2. if a thread enters it, it may turn into a blackhole + * 3. if evaluation finishes, it will be "updated", turning it into an indirection + * pointing to the result of the evaluation + * + * On the heap, state (1) is represented as a closure with the following layout + * (embodied in the C runtime by the `StgThunk` struct): + * + * thnk + * ┌───────────────────────┐ ╮ + * │ blah_info │ │ + * ├────────────┬──────────┤ │ StgThunkHeader + * │ indirectee │ NULL │ │ + * ├────────────┼──────────┤ ╯ + * │ payload[0] │ fv_0 │ + * ├────────────┼──────────┤ + * │ payload[1] │ fv_1 │ + * └────────────┴──────────┘ + * + * Here `blah_info` is a pointer to the thunk's info table, which will be of + * type THUNK. The `indirectee` field (also known as the "SMP header") is + * initially NULL and is unused while the closure remains a thunk. However, as + * we will see, it will eventually point to the result of the thunk's + * evaluation. + * + * + * Entry + * ----- + * As usual, to enter `thnk` (step (2) of the lifetime) a mutator thread + * `tso_0` will jump to its entry code (which is recorded in or next to its + * info table, depending upon whether tables-next-to-code is enabled). This + * entry code will push an "update frame" (namely, either `stg_upd_frame` or + * `stg_bh_upd_frame`) to `tso_0`'s stack and begin the evaluation of the + * thunk's RHS. + * + * However, before commencing evaluation, the entry code may also mark the + * thunk as being under evaluation; this process is known a "blackholing". + * Whether this happens depends upon which of GHC's two blackholing strategies + * which was selected during the compilation of the defining module. We will + * discuss the simpler "eager blackholing" case first and later introduce the + * more-efficient "lazy blackholing" strategy. + * + * + * Eager blackholing + * ----------------- + * Under the eager blackholing strategy (which is enabled via the + * `-feager-blackholing` flag), a thunk's entry code (generated by + * `GHC.StgToCmm.Bind.emitBlackHoleCode`) will immediately turn the thunk into + * a blackhole, indicating that the thunk is under evaluation. Additionally, + * the indirectee field will be updated to point to the thread performing the + * evaluation, `tso_0`. Since we know statically that the thunk is now a + * `BLACKHOLE`, the thunk entry code will push an `stg_bh_upd_frame` to the + * stack in this case (in contrast to the lazy strategy, as we will see later). + * + * After this `thnk` will look like, + * + * thnk + * ┌───────────────────────┐ + * │ EAGER_BLACKHOLE_info │ + * ├────────────┬──────────┤ tso_0 + * │ indirectee │ tso_0 │─────────►┌──────┐ + * ├────────────┼──────────┤ │ ... │ + * │ payload[0] │ fv_0 │ └──────┘ + * ├────────────┼──────────┤ + * │ payload[1] │ fv_1 │ + * └────────────┴──────────┘ + * + * Note that blackholing in this way does not guarantee mutual exclusion: Two + * threads may indeed race to enter `thnk`. This will result in both threads + * performing evaluation and, in some cases, the blackhole being updated + * multiple times. + * + * + * Updating a thunk + * ---------------- + * When `tso_0` finishes the evaluation of `thnk`, it will return to the entry + * code of the update frame pushed when the thunk was entered (e.g. + * `stg_bh_upd_frame`). This code first checks whether the blackhole + * has already been updated by another thread; if it has then `tso_0` will + * throw out its result and reuse that which the earlier thread recorded in the + * blackhole's `indirectee` field. + * + * If the blackhole has not yet been updated then `tso_0` will: + * + * 1. set `thnk`'s `indirectee` field to point to the result of its + * evaluation, and + * 2. set its info table to `BLACKHOLE_info` + * + * N.B. You might notice that step (2) here appears to be redundant as we + * already set the info table pointer to `EAGER_BLACKHOLE_info` above. However, + * as we will see below, this may not be the case when lazy blackholing is in + * use. + * + * After these updates we will have the following: + * + * thnk + * ┌───────────────────────┐ + * │ BLACKHOLE_info │ + * ├────────────┬──────────┤ result + * │ indirectee │ result │─────────►┌────────┐ + * ├────────────┼──────────┤ │ ... │ + * │ payload[0] │ fv_0 │ └────────┘ + * ├────────────┼──────────┤ + * │ payload[1] │ fv_1 │ + * └────────────┴──────────┘ + * + * In addition, the code will check the blocking queues that were added to the + * blackhole (recorded in the `indirectee` field, as we will see below) and + * wake them up (see `Threads.c:updateThunk`). + * + * Note that we are using `BLACKHOLE_info` to represent two distinct states of + * a thunk: + * + * - if the indirectee points to a `TSO` or `BLOCKING_QUEUE`, then the + * `BLACKHOLE` represents a thunk currently being evaluated + * + * - otherwise `BLACKHOLE` is merely representing an evaluated thunk and + * serves as an indirection to the final result. + * + * This overloading may seem odd given that we also have `stg_IND_info`, which + * also represents an indirection. However, the overloading serves a purpose: + * it means that safely updating a blackhole (step (3) of the + * lifetime above) requires only a single store (namely the store to the + * `indirectee` field). + * + * If we were to instead use `stg_IND` to represent the updated thunk, we would + * require two stores and consequently have an awkward period where the info + * table and indirectee fields are inconsistent: + * + * - if we were to update the info table first, there would be a period where + * the `indirectee` field pointed to the TSO which did the evaluation and + * not the result as one would expect. + * + * - if we were to update the indirectee first, there would be a period where + * the closure is still a `BLACKHOLE_info` yet the indirectee points to the + * evaluation result. + * + * For this reason, it is simpler to use `BLACKHOLE` to represent both states + * (2) and (3), distinguishing them using the identity of the indirectee. The + * uses of `stg_IND` are few and will be discussed below. + * + * + * Lazy blackholing + * ---------------- + * While the strict blackholing strategy described above is simple and is + * faithful to the semantics of the STG machine, it is fairly costly on modern + * hardware. Specifically, thunk entry can be extremely common and in a + * parallel program blackholing may induce considerable pressure on the + * machine's memory subsystem. + * + * To mitigate this GHC by default uses a lazy blackholing strategy. Here we + * take advantage of the fact that redundant evaluation of a thunk is + * acceptable and defer blackholing until the thread returns to the scheduler. + * This is an optimisation as frequently we will finish evaluation *before* + * yielding; in this case we avoid incurring the memory writes necessary to + * blackhole the thunk (step (2)) and rather update the thunk straight to an + * indirection. + * + * When entering a thunk compiled with lazy blackholing, we push an + * `stg_upd_frame` (not `stg_upd_bh_frame`) frame to the stack and do not + * modify the thunk closure itself. + * + * If the thread yields before finishing evaluation, the thunk will be turned + * into a `BLACKHOLE` in `ThreadPaused.c:threadPaused`. This function traverses + * the stack of the yielding thread looking for update frames; when such a + * frame is encountered, it checks the info table of the updatee and: + * + * - if it is `BLACKHOLE` then thunk has already been claimed for evaluation + * by another thread and the yielding thread is instead added to the + * `BLACKHOLE`'s blocking queue (see Note [suspend duplicate work] in + * `ThreadPaused.c`). + * + * - if not, then it blackholes the thunk as done in eager blackholing (but + * using the `BLACKHOLE_info` info table instead of `EAGER_BLACKHOLE_info`). + * + * Update frames processed in this manner are rewritten to become + * `stg_marked_upd_frame`s. The stack traversal continues until a + * `stg_marked_upd_frame_info` frame is encountered, at which point we know + * that all subsequent frames have already been processed in a previous yield. + * + * The entry code of `stg_upd_frame` is considerably simpler than that of + * `stg_bh_upd_frame` since we know that the thunk has not accumulated any + * `BLOCKING_QUEUE`s in need of waking (since it was never blackhole'd). This + * is itself a small optimisation for the common case of uncontended thunk + * update. By contrast, the entry code of `stg_marked_upd_frame` is identical + * to that of `stg_bh_upd_frame` and must deal with waking of blocked threads. + * + * See `Note [suspend duplicate work]` in `ThreadPaused.c` for a subtle case + * involving the interaction between lazy and eager blackholing. + * + * See `Note [upd-black-hole]` in `Scav.c` for another subtle case. + * + * + * Blocking on a blackhole'd thunk + * ------------------------------- + * If another thread `tso_1` enters `thnk` while it is blackholed by `tso_0`, + * the entry code of `BLACKHOLE` will allocate a `MSG_BLACKHOLE` object + * `msg_bh_0`. This message will be sent to the capability where the thread + * owning the thunk resides (see `Messages.c:messageBlackHole`). This + * capability will allocate a `BLOCKING_QUEUE` object `bq_0` recording the fact + * that `tso_1` is waiting for the result of `thnk`'s evaluation and link it to + * `thnk` as follows: + * + * thnk + * ┌─►┌───────────────────────┐ + * │ │ EAGER_BLACKHOLE_info │ + * │ ├────────────┬──────────┤ + * │ │ indirectee │ bq_0 ├──────┐ + * │ ├────────────┼──────────┤ │ + * │ │ payload[0] │ fv_0 │ │ + * │ ├────────────┼──────────┤ │ + * │ │ payload[1] │ fv_1 │ │ + * │ └────────────┴──────────┘ │ + * │ │ msg_bh_0 + * │ ┌───────────────────────────┘ ┌──►┌───────────────────────────┐ + * │ │ │ │ MSG_BLACKHOLE_info │ + * │ │ │ ├───────────┬───────────────┤ + * │ │ bq_0 │ │ link │ END_TSO_QUEUE │ + * │ └─►┌──────────────────────┐ │ ├───────────┼───────────────┤ + * │ │ BLOCKING_QUEUE_info │ │ │ result │ NULL │ + * │ ├───────────┬──────────┤ │ ├───────────┼───────────────┤ tso_1 + * │ │ link │ NULL │ │ │ tso │ tso_1 ├────►┌──────┐ + * │ ├───────────┼──────────┤ │ └───────────┴───────────────┘ │ ... │ + * │ │ queue │ msg_bh_0 ├────┘ └──────┘ + * │ ├───────────┼──────────┤ tso_0 + * │ │ owner │ tso_0 ├───────►┌──────┐ + * │ ├───────────┼──────────┤ │ ... │ + * │ │ bh │ thnk ├────┐ └──────┘ + * │ └───────────┴──────────┘ │ + * │ │ + * └────────────────────────────────────┘ + * + * Additionally, the `BLOCKING_QUEUE` is added to the `bq` list of the owning + * TSO, which collects all blocking queue objects which are blocked on thunks + * owned by the thread. + * + * In addition to this book-keeping, the `MSG_BLACKHOLE` message result in + * `tso_0` being promoted in its capability's run queue in the hope that + * `tso_1` and other blocked threads may be unblocked more quickly. + * + * + * Waking up blocking queues + * ------------------------- + * As noted above, when a thread updates a `BLACKHOLE`'d thunk it may find that + * some threads have added themselves to the thunk's blocking queue. Naturally, + * we must ensure that these threads are woken up. However, this gets a bit + * subtle since multiple threads may have raced to enter the thunk. + * + * That is, we may end up in a situation like one of these (TODO audit): + * + * ### Race A + * + * Thread 0 Thread 1 Thread 2 + * -------------------------- -------------------------- ---------------------- + * enter thnk + * enter thnk + * thnk.indirectee := tso_0 + * thnk.indirectee := tso_1 + * thnk.info := BLACKHOLE + * thnk.info := BLACKHOLE + * enter, block on thnk + * send MSG_BLACKHOLE to tso_1->cap + * finishes evaluation + * thnk.indirectee := result + * handle MSG_BLACKHOLE + * add + * + * ### Race B + * + * Thread 0 Thread 1 Thread 2 + * -------------------------- -------------------------- ---------------------- + * enter thnk + * enter thnk + * thnk.indirectee := tso_0 + * thnk.indirectee := tso_1 + * thnk.info := BLACKHOLE + * thnk.info := BLACKHOLE + * enter, block on thnk + * send MSG_BLACKHOLE to tso_1->cap + * handle MSG_BLACKHOLE + * add + * finishes evaluation + * thnk.indirectee := result + * + * ### Race C + * + * Thread 0 Thread 1 Thread 2 + * -------------------------- -------------------------- ---------------------- + * enter thnk + * enter thnk + * thnk.indirectee := tso_0 + * thnk.info := BLACKHOLE + * enter, block on thnk + * send MSG_BLACKHOLE to tso_0->cap + * handle MSG_BLACKHOLE + * thnk.indirectee := new BLOCKING_QUEUE + * + * thnk.indirectee := tso_1 + * thnk.info := BLACKHOLE + * + * + * Exception handling + * ------------------ + * When an exception is thrown to a thread which is evaluating a thunk, it is + * important that we put things back into a state in which evaluation can + * be resumed by another thread. This is done by `RaiseAsync.c:raiseAsync` + * which walks the stack looking for update frames and rewrites the updatees + * into indirections pointing to an `AP_STACK` closure recording the aborted + * execution state. + * + * See `RaiseAsync.c:raiseAsync` for details. + * + * + * CAFs + * ---- + * Top-level thunks (CAFs) reuse much of this machinery. The only differences + * are + * + * - CAF entry ensures mutual exclusion (see `Note [atomic CAF entry]` + * in `Storage.c` for why) + * + * - we have a distinct blackhole type, `stg_CAF_BLACKHOLE_info`; it's + * not clear that maintaining this distinction from + * `stg_EAGER_BLACKHOLE_info` is strictly necessary. + * + * See `Note [CAF management]` in `Storage.c` . + * + * + * Memory ordering + * --------------- + * The memory orderings necessary for safe concurrent thunk evaluation + * are rather subtle and described in Note [Heap memory barriers] in `SMP.h`. + * + * + * The uses of `stg_IND` + * --------------------- + * As noted above, `stg_IND_info` is not used for thunk evaluation. Instead, it + * merely serves as a general-purpose indirection in a few miscellaneous cases: + * + * * it is used to "short-out" `BLOCKING_QUEUE`s and `MVAR_TSO_QUEUES` that have + * already been woken-up. See Note [BLACKHOLE pointing to IND] in `Evac.c`. + * + * * It is used to perform indirection of selector thunks (see + * `Evac.c:unchain_thunk_selectors`). + * + */ + /* ----------------------------------------------------------------------------- Updates -------------------------------------------------------------------------- */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37471bae2a217b7fcb537142f768a503b979f0da -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37471bae2a217b7fcb537142f768a503b979f0da You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 14:31:17 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 18 Apr 2023 10:31:17 -0400 Subject: [Git][ghc/ghc][master] Convert interface file loading errors into proper diagnostics Message-ID: <643ea9b5f39f_178e7417ee511c28062b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - 30 changed files: - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Error.hs - compiler/ghc.cabal.in - ghc/Main.hs - testsuite/tests/cabal/cabal05/cabal05.stderr - testsuite/tests/cabal/ghcpkg04.stderr - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e1d33d7a428965c7024290cebb3d77b84230169 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5e1d33d7a428965c7024290cebb3d77b84230169 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 14:32:02 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 18 Apr 2023 10:32:02 -0400 Subject: [Git][ghc/ghc][master] Don't panic in ltPatersonSize Message-ID: <643ea9e28207c_178e7417f79330289315@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 3 changed files: - compiler/GHC/Tc/Utils/TcType.hs - + testsuite/tests/typecheck/should_compile/T23171.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -2394,22 +2394,32 @@ has a separate call to isStuckTypeFamily, so the `F` above will still be accepte -} +-- | Why was the LHS 'PatersonSize' not strictly smaller than the RHS 'PatersonSize'? +-- +-- See Note [Paterson conditions] in GHC.Tc.Validity. data PatersonSizeFailure - = PSF_TyFam TyCon -- Type family - | PSF_Size -- Too many type constructors/variables - | PSF_TyVar [TyVar] -- These type variables appear more often than in instance head; - -- no duplicates in this list + -- | Either side contains a type family. + = PSF_TyFam TyCon + -- | The size of the LHS is not strictly less than the size of the RHS. + | PSF_Size + -- | These type variables appear more often in the LHS than in the RHS. + | PSF_TyVar [TyVar] -- ^ no duplicates in this list -------------------------------------- -data PatersonSize -- See Note [Paterson conditions] in GHC.Tc.Validity - = PS_TyFam TyCon -- Mentions a type family; infinite size - - | PS_Vanilla { ps_tvs :: [TyVar] -- Free tyvars, including repetitions; - , ps_size :: Int -- Number of type constructors and variables +-- | The Paterson size of a given type, in the sense of +-- Note [Paterson conditions] in GHC.Tc.Validity +-- +-- - after expanding synonyms, +-- - ignoring coercions (as they are not user written). +data PatersonSize + -- | The type mentions a type family, so the size could be anything. + = PS_TyFam TyCon + + -- | The type does not mention a type family. + | PS_Vanilla { ps_tvs :: [TyVar] -- ^ free tyvars, including repetitions; + , ps_size :: Int -- ^ number of type constructors and variables } - -- Always after expanding synonyms - -- Always ignore coercions (not user written) -- ToDo: ignore invisible arguments? See Note [Invisible arguments and termination] instance Outputable PatersonSize where @@ -2422,21 +2432,26 @@ pSizeZero, pSizeOne :: PatersonSize pSizeZero = PS_Vanilla { ps_tvs = [], ps_size = 0 } pSizeOne = PS_Vanilla { ps_tvs = [], ps_size = 1 } -ltPatersonSize :: PatersonSize -- Size of constraint - -> PatersonSize -- Size of instance head; never PS_TyFam +-- | @ltPatersonSize ps1 ps2@ returns: +-- +-- - @Nothing@ iff @ps1@ is definitely strictly smaller than @ps2@, +-- - @Just ps_fail@ otherwise; @ps_fail@ says what went wrong. +ltPatersonSize :: PatersonSize + -> PatersonSize -> Maybe PatersonSizeFailure --- (ps1 `ltPatersonSize` ps2) returns --- Nothing iff ps1 is strictly smaller than p2 --- Just ps_fail says what went wrong -ltPatersonSize (PS_TyFam tc) _ = Just (PSF_TyFam tc) ltPatersonSize (PS_Vanilla { ps_tvs = tvs1, ps_size = s1 }) (PS_Vanilla { ps_tvs = tvs2, ps_size = s2 }) | s1 >= s2 = Just PSF_Size | bad_tvs@(_:_) <- noMoreTyVars tvs1 tvs2 = Just (PSF_TyVar bad_tvs) | otherwise = Nothing -- OK! -ltPatersonSize (PS_Vanilla {}) (PS_TyFam tc) - = pprPanic "ltPSize" (ppr tc) - -- Impossible because we never have a type family in an instance head +ltPatersonSize (PS_TyFam tc) _ = Just (PSF_TyFam tc) +ltPatersonSize _ (PS_TyFam tc) = Just (PSF_TyFam tc) + -- NB: this last equation is never taken when checking instances, because + -- type families are disallowed in instance heads. + -- + -- However, this function is also used in the logic for solving superclass + -- constraints (see Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance), + -- in which case we might well hit this case (see e.g. T23171). noMoreTyVars :: [TyVar] -- Free vars (with repetitions) of the constraint C -> [TyVar] -- Free vars (with repetitions) of the head H ===================================== testsuite/tests/typecheck/should_compile/T23171.hs ===================================== @@ -0,0 +1,43 @@ +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} + +module T23171 where + +import Data.Kind + +type C1 :: Type -> Type -> Constraint +class C1 t m where + +type C2 :: Type -> Constraint +class C2 a where + +type C3 :: Type -> Constraint +class C2 a => C3 a where + +type D :: Type -> Constraint +class D t where +instance (forall m. C3 m => C1 t m) => D t where + +type T :: Type -> Type +type family T a where + +try :: forall (e :: Type). D (T e) => e -> () +try _ = () + +type C1T :: Type -> Type -> Constraint +class C1 (T e) m => C1T e m + +tried :: forall (e :: Type). (forall m. C1T e m) => e -> () +tried = try @e + +-- From the call to "try", we get [W] D (T e). +-- After using the instance for D, we get the QC [G] C3 m ==> [W] C1 (T e) m. +-- +-- The Given "[G] C3 m" thus arises from superclass expansion +-- from "D (T e)", which contains a type family application, T. +-- So the logic in 'mkStrictSuperClasses' better be able to handle that when +-- expanding the superclasses of C3 (in this case, C2); in particular +-- ltPatersonSize needs to handle a type family in its second argument. + ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -871,5 +871,6 @@ test('T22194', normal, compile, ['']) test('QualifiedRecordUpdate', [ extra_files(['QualifiedRecordUpdate_aux.hs']) ] , multimod_compile, ['QualifiedRecordUpdate', '-v0']) +test('T23171', normal, compile, ['']) test('T23192', normal, compile, ['']) test('T23199', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df1a581188694479a583270548896245fc23b525 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df1a581188694479a583270548896245fc23b525 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 14:42:01 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 18 Apr 2023 10:42:01 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 2 commits: Fix upload_ghc_libs glob Message-ID: <643eac39a1b8b_178e74183968282950df@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 660294de by GHC GitLab CI at 2023-04-06T12:34:16+01:00 Fix upload_ghc_libs glob - - - - - e26193da by GHC GitLab CI at 2023-04-18T15:41:01+01:00 Cores - - - - - 2 changed files: - .gitlab/ci.sh - .gitlab/rel_eng/upload_ghc_libs.py Changes: ===================================== .gitlab/ci.sh ===================================== @@ -169,7 +169,7 @@ PATH="$toolchain/bin:$PATH" export METRICS_FILE="$TOP/performance-metrics.tsv" -cores="$(mk/detect-cpu-count.sh)" +cores=1 #"$(mk/detect-cpu-count.sh)" # Use a local temporary directory to ensure that concurrent builds don't # interfere with one another ===================================== .gitlab/rel_eng/upload_ghc_libs.py ===================================== @@ -25,6 +25,7 @@ import tempfile import re import pickle import os +import glob WORK_DIR = Path('.upload-libs') @@ -152,7 +153,10 @@ def prepare_docs(bindist: Path, pkg: Package): cabal_file = pkg.path / f'{pkg.name}.cabal' version = get_version(cabal_file) assert version is not None - docdir = bindist / 'doc' / 'html' / 'libraries' / (pkg.name + "-" + version) + docdir_prefix = bindist / 'doc' / 'html' / 'libraries' / (pkg.name + "-" + version) + + docdir = glob.glob(str(docdir_prefix) + "*")[0] + print(docdir) # Build the documentation tarball from the bindist documentation stem = f'{pkg.name}-{version}-docs' View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a75037892c809b196d0538de306883e215c4ddfc...e26193da044df324ac77f9421a7fe974ba520226 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a75037892c809b196d0538de306883e215c4ddfc...e26193da044df324ac77f9421a7fe974ba520226 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 16:07:09 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Tue, 18 Apr 2023 12:07:09 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Unconditional jumps Message-ID: <643ec02d27bf3_178e7419e6b20c3145f7@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: c425f153 by Sven Tennie at 2023-04-18T16:06:40+00:00 Unconditional jumps - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -103,6 +103,7 @@ stmtToInstrs stmt = do where ty = cmmRegType reg format = cmmTypeFormat ty CmmBranch id -> genBranch id + CmmCall { cml_target = arg } -> genJump arg a -> error $ "TODO: stmtToInstrs " ++ (showSDocUnsafe . pdoc platform) a assignReg_FltCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock @@ -147,6 +148,13 @@ getRegister' config plat expr e -> error ("TODO: getRegister' other " ++ show e) e -> error ("TODO: getRegister'" ++ show e) +-- ----------------------------------------------------------------------------- +-- Jumps +genJump :: CmmExpr{-the branch target-} -> NatM InstrBlock +genJump expr@(CmmLit (CmmLabel lbl)) + = return $ unitOL (annExpr expr (J (TLabel lbl))) +genJump expr = error $ "TODO: genJump " ++ show expr + -- ----------------------------------------------------------------------------- -- Unconditional branches genBranch :: BlockId -> NatM InstrBlock ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -13,6 +13,7 @@ import GHC.Types.Unique.Supply import GHC.Utils.Outputable import Prelude import GHC.Platform.Regs (freeReg) +import GHC.Cmm.CLabel data Instr = -- comment pseudo-op @@ -36,7 +37,11 @@ data Instr | -- load immediate pseudo-instruction LI Reg Integer | -- jump pseudo-instruction - J BlockId + J Target + +data Target + = TBlock BlockId + | TLabel CLabel allocMoreStack :: Int -> @@ -136,7 +141,7 @@ isJumpishInstr J {} = True -- register allocator needs to worry about. jumpDestsOfInstr :: Instr -> [BlockId] jumpDestsOfInstr (ANN _ i) = jumpDestsOfInstr i -jumpDestsOfInstr (J t) = [t] +jumpDestsOfInstr (J (TBlock t)) = [t] jumpDestsOfInstr _ = [] -- | Change the destination of this jump instruction. @@ -231,7 +236,7 @@ takeRegRegMoveInstr J {} = Nothing mkJumpInstr :: BlockId -> [Instr] -mkJumpInstr id = [J id] +mkJumpInstr id = [J (TBlock id)] -- Subtract an amount from the C stack pointer mkStackAllocInstr :: ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -137,8 +137,9 @@ pprInstr platform instr = case instr of pprReg (RegReal (RealRegSingle r)) = text "x" <> (text.show) r pprReg (RegVirtual r) = panic $ "RISCV64.Ppr.ppr: Unexpected virtual register " ++ show r - pprJ :: IsLine doc => BlockId -> doc - pprJ label = text "\tj" <+> pprBlockId label + pprJ :: IsLine doc => Target -> doc + pprJ (TBlock label) = text "\tj" <+> pprBlockId label + pprJ (TLabel label) = text "\tj" <+> pprAsmLabel platform label pprBlockId:: IsLine doc => BlockId -> doc pprBlockId blockId = pprAsmLabel platform (mkLocalBlockLabel (getUnique blockId)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c425f15324cbf92f423176bb5eb50c7c9e5bc43e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c425f15324cbf92f423176bb5eb50c7c9e5bc43e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 16:14:14 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 18 Apr 2023 12:14:14 -0400 Subject: [Git][ghc/ghc][wip/T23083] 5 commits: exprIsTrivial: Factor out shared implementation Message-ID: <643ec1d6c6c07_178e741a05cfc03150ec@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: bf06957d by Sebastian Graf at 2023-04-18T18:10:31+02:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - c5111c3a by Sebastian Graf at 2023-04-18T18:10:31+02:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - 65176d6e by Sebastian Graf at 2023-04-18T18:10:31+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - 5eb3e158 by Sebastian Graf at 2023-04-18T18:11:55+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - a7375eda by Sebastian Graf at 2023-04-18T18:11:55+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - docs/users_guide/using-optimisation.rst - testsuite/tests/corelint/T21115b.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8dfac07272cd782d19a19541603fa89f49e1a83d...a7375eda6069861fa62fd23bf76f2fea1e9971d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8dfac07272cd782d19a19541603fa89f49e1a83d...a7375eda6069861fa62fd23bf76f2fea1e9971d1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 16:35:14 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 18 Apr 2023 12:35:14 -0400 Subject: [Git][ghc/ghc][wip/T23083] 149 commits: Bump Win32 to 2.13.4.0 Message-ID: <643ec6c2e9035_178e741a71aab032147d@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d1465c45 by Sebastian Graf at 2023-04-18T18:35:04+02:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - 3965414a by Sebastian Graf at 2023-04-18T18:35:04+02:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - c90448f1 by Sebastian Graf at 2023-04-18T18:35:04+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - 311db6dd by Sebastian Graf at 2023-04-18T18:35:05+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 469dbdf5 by Sebastian Graf at 2023-04-18T18:35:05+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a7375eda6069861fa62fd23bf76f2fea1e9971d1...469dbdf53edb300a888a90b6abf6193c4c804039 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a7375eda6069861fa62fd23bf76f2fea1e9971d1...469dbdf53edb300a888a90b6abf6193c4c804039 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 16:36:00 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 18 Apr 2023 12:36:00 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead Message-ID: <643ec6f0991ec_178e741a874cf832186b@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: fd4dfa42 by Sebastian Graf at 2023-04-18T18:35:45+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - a60cd275 by Sebastian Graf at 2023-04-18T18:35:45+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 29 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -717,9 +717,13 @@ this exhaustive list can be empty! its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils -* An empty case is replaced by its scrutinee during the CoreToStg - conversion; remember STG is un-typed, so there is no need for - the empty case to do the type conversion. +* We stick to empty cases until code generation, when StgToX emits an eval on + the scrutinee in GHC.StgToCmm.Expr.cgCase and GHC.StgToJS.Expr.genCase. + +Historical Note: We used to lower EmptyCase in CorePrep by way of an +unsafeCoercion on the scrutinee, but that yielded panics in CodeGen when +we were beginning to eta expand in arguments, plus required to mess with +heterogenously-kinded coercions. It's simpler to stick to it until Cmm anyway. Note [Join points] ~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -1390,7 +1390,7 @@ setNominalRole_maybe r co | case prov of PhantomProv _ -> False -- should always be phantom ProofIrrelProv _ -> True -- it's always safe PluginProv _ -> False -- who knows? This choice is conservative. - CorePrepProv _ -> True + CorePrepProv -> True = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1516,7 +1516,7 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco UnivCo (PluginProv _) _ _ _ -> mkKindCo co - UnivCo (CorePrepProv _) _ _ _ -> mkKindCo co + UnivCo CorePrepProv _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2339,7 +2339,7 @@ seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co seqProv (PluginProv _) = () -seqProv (CorePrepProv _) = () +seqProv CorePrepProv = () seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -622,7 +622,7 @@ opt_univ env sym prov role oty1 oty2 #endif ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco PluginProv _ -> prov - CorePrepProv _ -> prov + CorePrepProv -> prov ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,7 @@ orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co orphNamesOfProv (PluginProv _) = emptyNameSet -orphNamesOfProv (CorePrepProv _) = emptyNameSet +orphNamesOfProv CorePrepProv = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo @@ -798,4 +798,3 @@ freeVars = go go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) - ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2301,9 +2301,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) -- see #9122 for discussion of these checks checkTypes t1 t2 - | allow_ill_kinded_univ_co prov - = return () -- Skip kind checks - | otherwise = do { checkWarnL fixed_rep_1 (report "left-hand type does not have a fixed runtime representation") ; checkWarnL fixed_rep_2 @@ -2321,13 +2318,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) reps1 = typePrimRep t1 reps2 = typePrimRep t2 - -- CorePrep deliberately makes ill-kinded casts - -- e.g (case error @Int "blah" of {}) :: Int# - -- ==> (error @Int "blah") |> Unsafe Int Int# - -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - allow_ill_kinded_univ_co (CorePrepProv homo_kind) = not homo_kind - allow_ill_kinded_univ_co _ = False - validateCoercion :: PrimRep -> PrimRep -> LintM () validateCoercion rep1 rep2 = do { platform <- getPlatform @@ -2357,8 +2347,8 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov - lint_prov _ _ prov@(CorePrepProv _) = return prov + lint_prov _ _ prov@(PluginProv _) = return prov + lint_prov _ _ prov at CorePrepProv = return prov check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -661,7 +661,7 @@ tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc -tyCoFVsOfProv (CorePrepProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc +tyCoFVsOfProv CorePrepProv fv_cand in_scope acc = emptyFV fv_cand in_scope acc tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -731,8 +731,8 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True -almost_devoid_co_var_of_prov (CorePrepProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _) _ = True +almost_devoid_co_var_of_prov CorePrepProv _ = True almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1131,7 +1131,7 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyUniqSet - go_prov (CorePrepProv _) = emptyUniqSet + go_prov CorePrepProv = emptyUniqSet -- this last case can happen from the tyConsOfType used from -- checkTauTvUpdate @@ -1345,5 +1345,4 @@ occCheckExpand vs_to_avoid ty go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p - + go_prov _ p at CorePrepProv = return p ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1437,9 +1437,9 @@ data UnivCoProvenance | PluginProv String -- ^ From a plugin, which asserts that this coercion -- is sound. The string is for the use of the plugin. - | CorePrepProv -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - Bool -- True <=> the UnivCo must be homogeneously kinded - -- False <=> allow hetero-kinded, e.g. Int ~ Int# + | CorePrepProv -- ^ See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep + -- The UnivCo is always homogeneously kinded, e.g., it + -- disallows Int ~ Int# deriving Data.Data @@ -1447,7 +1447,7 @@ instance Outputable UnivCoProvenance where ppr (PhantomProv _) = text "(phantom)" ppr (ProofIrrelProv _) = text "(proof irrel.)" ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) - ppr (CorePrepProv _) = text "(CorePrep)" + ppr CorePrepProv = text "(CorePrep)" -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1760,7 +1760,7 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co go_prov _ (PluginProv _) = mempty - go_prov _ (CorePrepProv _) = mempty + go_prov _ CorePrepProv = mempty -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1826,7 +1826,7 @@ provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co provSize (PluginProv _) = 1 -provSize (CorePrepProv _) = 1 +provSize CorePrepProv = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -912,7 +912,7 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -252,7 +252,7 @@ tidyCo env@(_, subst) co go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -580,7 +580,7 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) go_prov _ p@(PluginProv _) = p - go_prov _ p@(CorePrepProv _) = p + go_prov _ p at CorePrepProv = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -998,7 +998,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov env (PhantomProv co) = PhantomProv <$> go_co env co go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p + go_prov _ p at CorePrepProv = return p {- ********************************************************************* ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -321,7 +321,7 @@ toIfaceCoercionX fr co go_prov (PhantomProv co) = IfacePhantomProv (go co) go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) go_prov (PluginProv str) = IfacePluginProv str - go_prov (CorePrepProv b) = IfaceCorePrepProv b + go_prov CorePrepProv = IfaceCorePrepProv toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -19,8 +19,7 @@ module GHC.CoreToStg ( CoreToStgOpts (..), coreToStg ) where import GHC.Prelude import GHC.Core -import GHC.Core.Utils ( exprType, findDefault, isJoinBind - , exprIsTickedString_maybe ) +import GHC.Core.Utils import GHC.Core.Opt.Arity ( manifestArity ) import GHC.Core.Type import GHC.Core.TyCon @@ -49,7 +48,7 @@ import GHC.Unit.Module import GHC.Data.FastString import GHC.Platform ( Platform ) import GHC.Platform.Ways -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps import GHC.Utils.Outputable import GHC.Utils.Monad @@ -430,29 +429,7 @@ coreToStgExpr (Cast expr _) = coreToStgExpr expr -- Cases require a little more real work. - -{- -coreToStgExpr (Case scrut _ _ []) - = coreToStgExpr scrut - -- See Note [Empty case alternatives] in GHC.Core If the case - -- alternatives are empty, the scrutinee must diverge or raise an - -- exception, so we can just dive into it. - -- - -- Of course this may seg-fault if the scrutinee *does* return. A - -- belt-and-braces approach would be to move this case into the - -- code generator, and put a return point anyway that calls a - -- runtime system error function. - -coreToStgExpr e0@(Case scrut bndr _ [alt]) = do - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder is dead - -- It usually is, but see #18227 - , (_,_,rhs) <- alt - = coreToStgExpr rhs - -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce --} - --- The normal case for case-expressions +-- As Note [Empty case alternatives] in GHC.Core says, we hold on to EmptyCase coreToStgExpr (Case scrut bndr _ alts) = do { scrut2 <- coreToStgExpr scrut ; alts2 <- extendVarEnvCts [(bndr, LambdaBound)] (mapM vars_alt alts) @@ -574,6 +551,11 @@ coreToStgApp f args ticks = do -- This is the guy that turns applications into A-normal form -- --------------------------------------------------------------------------- +getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e + where + panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] = return ([], []) @@ -594,34 +576,14 @@ coreToStgArgs (Tick t e : args) coreToStgArgs (arg : args) = do -- Non-type argument (stg_args, ticks) <- coreToStgArgs args - arg' <- coreToStgExpr arg - let - (aticks, arg'') = stripStgTicksTop tickishFloatable arg' - stg_arg = case arg'' of - StgApp v [] -> StgVarArg v - StgConApp con _ [] _ -> StgVarArg (dataConWorkId con) - StgOpApp (StgPrimOp op) [] _ -> StgVarArg (primOpWrapperId op) - StgLit lit -> StgLitArg lit - _ -> pprPanic "coreToStgArgs" (ppr arg $$ pprStgExpr panicStgPprOpts arg' $$ pprStgExpr panicStgPprOpts arg'') - - -- WARNING: what if we have an argument like (v `cast` co) - -- where 'co' changes the representation type? - -- (This really only happens if co is unsafe.) - -- Then all the getArgAmode stuff in CgBindery will set the - -- cg_rep of the CgIdInfo based on the type of v, rather - -- than the type of 'co'. - -- This matters particularly when the function is a primop - -- or foreign call. - -- Wanted: a better solution than this hacky warning - platform <- getPlatform - let + let arg' = getStgArgFromTrivialArg arg arg_rep = typePrimRep (exprType arg) - stg_arg_rep = typePrimRep (stgArgType stg_arg) + stg_arg_rep = typePrimRep (stgArgType arg') bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep) warnPprTrace bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) $ - return (stg_arg : stg_args, ticks ++ aticks) + return (arg' : stg_args, ticks) coreToStgTick :: Type -- type of the ticked expression -> CoreTickish @@ -959,6 +921,9 @@ myCollectBinders expr -- | If the argument expression is (potential chain of) 'App', return the head -- of the app chain, and collect ticks/args along the chain. +-- INVARIANT: If the app head is trivial, return the atomic Var/Lit that was +-- wrapped in casts, empty case, ticks, etc. +-- So keep in sync with 'exprIsTrivial'. myCollectArgs :: HasDebugCallStack => CoreExpr -> (CoreExpr, [CoreArg], [CoreTickish]) myCollectArgs expr = go expr [] [] @@ -970,8 +935,10 @@ myCollectArgs expr -- See Note [Ticks in applications] go e as (t:ts) -- ticks can appear in type apps go (Cast e _) as ts = go e as ts + go (Case e _ _ []) as ts = assertPpr (null as) (ppr e $$ ppr as $$ ppr expr) $ + go e [] ts -- NB: Empty case discards arguments go (Lam b e) as ts - | isTyVar b = go e as ts -- Note [Collect args] + | isTyVar b = go e (drop 1 as) ts -- Note [Collect args] go e as ts = (e, as, ts) {- Note [Collect args] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -142,7 +142,7 @@ The goal of this pass is to prepare for code generation. profiling mode. We have to do this here because we won't have unfoldings after this pass (see `trimUnfolding` and Note [Drop unfoldings and rules]. -12. Eliminate case clutter in favour of unsafe coercions. +12. Eliminate unsafeEqualityProof in favour of unsafe coercions. See Note [Unsafe coercions] 13. Eliminate some magic Ids, specifically @@ -159,45 +159,17 @@ any trivial or useless bindings. Note [Unsafe coercions] ~~~~~~~~~~~~~~~~~~~~~~~ -CorePrep does these two transformations: - -1. Convert empty case to cast with an unsafe coercion - (case e of {}) ===> e |> unsafe-co - See Note [Empty case alternatives] in GHC.Core: if the case - alternatives are empty, the scrutinee must diverge or raise an - exception, so we can just dive into it. - - Of course, if the scrutinee *does* return, we may get a seg-fault. - A belt-and-braces approach would be to persist empty-alternative - cases to code generator, and put a return point anyway that calls a - runtime system error function. - - Notice that eliminating empty case can lead to an ill-kinded coercion - case error @Int "foo" of {} :: Int# - ===> error @Int "foo" |> unsafe-co - where unsafe-co :: Int ~ Int# - But that's fine because the expression diverges anyway. And it's - no different to what happened before. - -2. Eliminate unsafeEqualityProof in favour of an unsafe coercion - case unsafeEqualityProof of UnsafeRefl g -> e - ===> e[unsafe-co/g] - See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce - - Note that this requires us to substitute 'unsafe-co' for 'g', and - that is the main (current) reason for cpe_tyco_env in CorePrepEnv. - Tiresome, but not difficult. - -These transformations get rid of "case clutter", leaving only casts. -We are doing no further significant transformations, so the reasons -for the case forms have disappeared. And it is extremely helpful for -the ANF-ery, CoreToStg, and backends, if trivial expressions really do -look trivial. #19700 was an example. - -In both cases, the "unsafe-co" is just (UnivCo ty1 ty2 (CorePrepProv b)), -The boolean 'b' says whether the unsafe coercion is supposed to be -kind-homogeneous (yes for (2), no for (1). This information is used -/only/ by Lint. +CorePrep eliminates unsafeEqualityProof in favour of an unsafe coercion + case unsafeEqualityProof of UnsafeRefl g -> e + ===> e[unsafe-co/g] +See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce. + +The "unsafe-co" is just (UnivCo ty1 ty2 CorePrepProv), +a coercion that is always kind-homogeneous (as checked by Lint). + +Note that this requires us to substitute 'unsafe-co' for 'g', and +that is the main (current) reason for cpe_tyco_env in CorePrepEnv. +Tiresome, but not difficult. Note [CorePrep invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -830,23 +802,6 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } --- Eliminate empty case --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut _ ty []) - = do { (floats, scrut') <- cpeRhsE env scrut - ; let ty' = cpSubstTy env ty - scrut_ty' = exprType scrut' - co' = mkUnivCo prov Representational scrut_ty' ty' - prov = CorePrepProv False - -- False says that the kinds of two types may differ - -- E.g. we might cast Int to Int#. This is fine - -- because the scrutinee is guaranteed to diverge - - ; return (floats, Cast scrut' co') } - -- This can give rise to - -- Warning: Unsafe coercion: between unboxed and boxed value - -- but it's fine because 'scrut' diverges - -- Eliminate unsafeEqualityProof -- See Note [Unsafe coercions] cpeRhsE env (Case scrut bndr _ alts) @@ -855,8 +810,7 @@ cpeRhsE env (Case scrut bndr _ alts) -- is dead. It usually is, but see #18227 , [Alt _ [co_var] rhs] <- alts , let Pair ty1 ty2 = coVarTypes co_var - the_co = mkUnivCo prov Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) - prov = CorePrepProv True -- True <=> kind homogeneous + the_co = mkUnivCo CorePrepProv Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) env' = extendCoVarEnv env co_var the_co = cpeRhsE env' rhs @@ -1491,12 +1445,33 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1614,6 +1589,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1977,6 +1990,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1987,6 +2005,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1748,7 +1748,7 @@ freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co freeNamesIfProv (IfacePluginProv _) = emptyNameSet -freeNamesIfProv (IfaceCorePrepProv _) = emptyNameSet +freeNamesIfProv IfaceCorePrepProv = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -402,7 +402,7 @@ data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String - | IfaceCorePrepProv Bool -- See defn of CorePrepProv + | IfaceCorePrepProv -- See defn of CorePrepProv {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,7 +624,7 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) go_prov co@(IfacePluginProv _) = co - go_prov co@(IfaceCorePrepProv _) = co + go_prov co at IfaceCorePrepProv = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1860,7 +1860,7 @@ pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) -pprIfaceUnivCoProv (IfaceCorePrepProv _) +pprIfaceUnivCoProv IfaceCorePrepProv = text "CorePrep" ------------------- @@ -2229,9 +2229,8 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a) = do putByte bh 3 put_ bh a - put_ bh (IfaceCorePrepProv a) = do + put_ bh IfaceCorePrepProv = do putByte bh 4 - put_ bh a get bh = do tag <- getByte bh @@ -2242,8 +2241,7 @@ instance Binary IfaceUnivCoProv where return $ IfaceProofIrrelProv a 3 -> do a <- get bh return $ IfacePluginProv a - 4 -> do a <- get bh - return (IfaceCorePrepProv a) + 4 -> do return IfaceCorePrepProv _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1520,7 +1520,7 @@ tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceCorePrepProv b) = return $ CorePrepProv b +tcIfaceUnivCoProv IfaceCorePrepProv = return CorePrepProv {- ************************************************************************ ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -447,7 +447,7 @@ stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr -mkStgCase scrut bndr ty alts | all isBndr alts = scrut +mkStgCase scrut bndr ty alts | all isBndr alts = scrut -- NB: Always true for empty Case! | otherwise = StgCase scrut bndr ty alts where ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -650,6 +650,9 @@ elimCase _ args bndr alt_ty alts -------------------------------------------------------------------------------- unariseAlts :: UnariseEnv -> AltType -> InId -> [StgAlt] -> UniqSM [StgAlt] +unariseAlts _ _ _ [] + = return [] -- See Note [Empty case alternatives] + unariseAlts rho (MultiValAlt n) bndr [GenStgAlt{ alt_con = DEFAULT , alt_bndrs = [] , alt_rhs = e}] ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -53,7 +53,6 @@ import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import Control.Monad ( unless, void ) import Control.Arrow ( first ) @@ -427,6 +426,8 @@ data GcPlan ------------------------------------- cgCase :: CgStgExpr -> Id -> AltType -> [CgStgAlt] -> FCode ReturnKind +cgCase e _ _ [] = cgExpr e -- See Note [Empty case alternatives] + {- Note [Scrutinising VoidRep] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1028,7 +1029,7 @@ cgIdApp fun_id args = do (text "TagCheck failed on entry in" <+> ppr mod <+> text "- value:" <> ppr fun_id <+> pdoc platform fun)) fun - EnterIt -> assert (null args) $ -- Discarding arguments + EnterIt -> assertPpr (null args) (ppr fun_id $$ ppr args) $ -- Discarding arguments emitEnter fun SlowCall -> do -- A slow function call via the RTS apply routines ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -571,6 +571,9 @@ genCase :: HasDebugCallStack -> LiveVars -> G (JStat, ExprResult) genCase ctx bnd e at alts l + | [] <- alts = genExpr ctx e + -- See Note [Empty case alternatives]; + -- we simply generate code for eval'ing the scrutinee | snd (isInlineExpr (ctxEvaluatedIds ctx) e) = do bndi <- identsForId bnd let ctx' = ctxSetTop bnd ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -156,7 +156,7 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyNameEnv - go_prov (CorePrepProv _) = emptyNameEnv + go_prov CorePrepProv = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1578,7 +1578,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co go_prov dv (PluginProv _) = return dv - go_prov dv (CorePrepProv _) = return dv + go_prov dv CorePrepProv = return dv go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T23083 where + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,42 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 27, types: 24, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 12, types: 13, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> GHC.Base.$ @GHC.Types.LiftedRep @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/469dbdf53edb300a888a90b6abf6193c4c804039...a60cd2757f45e341bbd6df34acc16fead945547a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/469dbdf53edb300a888a90b6abf6193c4c804039...a60cd2757f45e341bbd6df34acc16fead945547a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 16:37:17 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 18 Apr 2023 12:37:17 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 2 commits: STM: Acquire instead of seq-cst Message-ID: <643ec73d2186a_178e741a8a0ad8322245@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 53a3fe2f by Ben Gamari at 2023-04-18T12:36:06-04:00 STM: Acquire instead of seq-cst - - - - - e1bd66c4 by Ben Gamari at 2023-04-18T12:36:23-04:00 Comment - - - - - 2 changed files: - rts/STM.c - rts/include/stg/SMP.h Changes: ===================================== rts/STM.c ===================================== @@ -187,7 +187,7 @@ static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgTVar *s STG_UNUSED) { StgClosure *result; TRACE("%p : lock_tvar(%p)", trec, s); - result = SEQ_CST_LOAD(&s->current_value); + result = ACQUIRE_LOAD(&s->current_value); return result; } @@ -198,7 +198,7 @@ static void unlock_tvar(Capability *cap, StgBool force_update) { TRACE("%p : unlock_tvar(%p)", trec, s); if (force_update) { - StgClosure *old_value = SEQ_CST_LOAD(&s->current_value); + StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, old_value); } @@ -210,7 +210,7 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgClosure *expected) { StgClosure *result; TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); - result = SEQ_CST_LOAD(&s->current_value); + result = ACQUIRE_LOAD(&s->current_value); TRACE("%p : %s", trec, (result == expected) ? "success" : "failure"); return (result == expected); } @@ -231,7 +231,7 @@ static void lock_stm(StgTRecHeader *trec) { static void unlock_stm(StgTRecHeader *trec STG_UNUSED) { TRACE("%p : unlock_stm()", trec); ASSERT(smp_locked == trec); - SEQ_CST_STORE(&smp_locked, 0); + RELEASE_STORE(&smp_locked, 0); } static StgClosure *lock_tvar(Capability *cap STG_UNUSED, @@ -240,7 +240,7 @@ static StgClosure *lock_tvar(Capability *cap STG_UNUSED, StgClosure *result; TRACE("%p : lock_tvar(%p)", trec, s); ASSERT(smp_locked == trec); - result = SEQ_CST_LOAD(&s->current_value); + result = ACQUIRE_LOAD(&s->current_value); return result; } @@ -252,7 +252,7 @@ static void *unlock_tvar(Capability *cap, TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); ASSERT(smp_locked == trec); if (force_update) { - StgClosure *old_value = SEQ_CST_LOAD(&s->current_value); + StgClosure *old_value = ACQUIRE_LOAD(&s->current_value); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, old_value); } @@ -265,7 +265,7 @@ static StgBool cond_lock_tvar(Capability *cap STG_UNUSED, StgClosure *result; TRACE("%p : cond_lock_tvar(%p, %p)", trec, s, expected); ASSERT(smp_locked == trec); - result = SEQ_CST_LOAD(&s->current_value); + result = ACQUIRE_LOAD(&s->current_value); TRACE("%p : %d", result ? "success" : "failure"); return (result == expected); } @@ -313,7 +313,7 @@ static void unlock_tvar(Capability *cap, StgClosure *c, StgBool force_update STG_UNUSED) { TRACE("%p : unlock_tvar(%p, %p)", trec, s, c); - ASSERT(SEQ_CST_LOAD(&s->current_value) == (StgClosure *)trec); + ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); RELEASE_STORE(&s->current_value, c); dirty_TVAR(cap, s, (StgClosure *) trec); } @@ -377,7 +377,7 @@ static void unpark_waiters_on(Capability *cap, StgTVar *s) { StgTVarWatchQueue *trail; TRACE("unpark_waiters_on tvar=%p", s); // unblock TSOs in reverse order, to be a bit fairer (#2319) - for (q = SEQ_CST_LOAD(&s->first_watch_queue_entry), trail = q; + for (q = ACQUIRE_LOAD(&s->first_watch_queue_entry), trail = q; q != END_STM_WATCH_QUEUE; q = q -> next_queue_entry) { trail = q; @@ -534,16 +534,16 @@ static void build_watch_queue_entries_for_trec(Capability *cap, StgTVarWatchQueue *fq; s = e -> tvar; TRACE("%p : adding tso=%p to watch queue for tvar=%p", trec, tso, s); - ACQ_ASSERT(SEQ_CST_LOAD(&s->current_value) == (StgClosure *)trec); - NACQ_ASSERT(SEQ_CST_LOAD(&s->current_value) == e -> expected_value); - fq = SEQ_CST_LOAD(&s->first_watch_queue_entry); + ACQ_ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); + NACQ_ASSERT(ACQUIRE_LOAD(&s->current_value) == e -> expected_value); + fq = ACQUIRE_LOAD(&s->first_watch_queue_entry); q = alloc_stg_tvar_watch_queue(cap, (StgClosure*) tso); q -> next_queue_entry = fq; q -> prev_queue_entry = END_STM_WATCH_QUEUE; if (fq != END_STM_WATCH_QUEUE) { fq -> prev_queue_entry = q; } - SEQ_CST_STORE(&s->first_watch_queue_entry, q); + RELEASE_STORE(&s->first_watch_queue_entry, q); e -> new_value = (StgClosure *) q; dirty_TVAR(cap, s, (StgClosure *) fq); // we modified first_watch_queue_entry }); @@ -571,7 +571,7 @@ static void remove_watch_queue_entries_for_trec(Capability *cap, trec, q -> closure, s); - ACQ_ASSERT(SEQ_CST_LOAD(&s->current_value) == (StgClosure *)trec); + ACQ_ASSERT(ACQUIRE_LOAD(&s->current_value) == (StgClosure *)trec); nq = q -> next_queue_entry; pq = q -> prev_queue_entry; if (nq != END_STM_WATCH_QUEUE) { @@ -580,8 +580,8 @@ static void remove_watch_queue_entries_for_trec(Capability *cap, if (pq != END_STM_WATCH_QUEUE) { pq -> next_queue_entry = nq; } else { - ASSERT(SEQ_CST_LOAD(&s->first_watch_queue_entry) == q); - SEQ_CST_STORE(&s->first_watch_queue_entry, nq); + ASSERT(ACQUIRE_LOAD(&s->first_watch_queue_entry) == q); + RELEASE_STORE(&s->first_watch_queue_entry, nq); dirty_TVAR(cap, s, (StgClosure *) q); // we modified first_watch_queue_entry } free_stg_tvar_watch_queue(cap, q); @@ -729,7 +729,7 @@ static StgBool entry_is_read_only(TRecEntry *e) { static StgBool tvar_is_locked(StgTVar *s, StgTRecHeader *h) { StgClosure *c; StgBool result; - c = SEQ_CST_LOAD(&s->current_value); + c = ACQUIRE_LOAD(&s->current_value); result = (c == (StgClosure *) h); return result; } @@ -805,13 +805,13 @@ static StgBool validate_and_acquire_ownership (Capability *cap, // The memory ordering here must ensure that we have two distinct // reads to current_value, with the read from num_updates between // them. - if (SEQ_CST_LOAD(&s->current_value) != e -> expected_value) { + if (ACQUIRE_LOAD(&s->current_value) != e -> expected_value) { TRACE("%p : doesn't match", trec); result = false; BREAK_FOR_EACH; } e->num_updates = SEQ_CST_LOAD(&s->num_updates); - if (SEQ_CST_LOAD(&s->current_value) != e -> expected_value) { + if (ACQUIRE_LOAD(&s->current_value) != e -> expected_value) { TRACE("%p : doesn't match (race)", trec); result = false; BREAK_FOR_EACH; @@ -854,7 +854,7 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { // We must first load current_value then num_updates; this is inverse of // the order of the stores in stmCommitTransaction. - StgClosure *current_value = SEQ_CST_LOAD(&s->current_value); + StgClosure *current_value = ACQUIRE_LOAD(&s->current_value); StgInt num_updates = SEQ_CST_LOAD(&s->num_updates); // Note we need both checks and in this order as the TVar could be @@ -1188,7 +1188,7 @@ StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec) { unlock_tvar(cap, trec, s, e -> expected_value, false); } merge_update_into(cap, et, s, e -> expected_value, e -> new_value); - ACQ_ASSERT(s -> current_value != (StgClosure *)trec); + ACQ_ASSERT(ACQUIRE_LOAD(&s->current_value) != (StgClosure *)trec); }); } else { revert_ownership(cap, trec, false); ===================================== rts/include/stg/SMP.h ===================================== @@ -685,6 +685,12 @@ load_load_barrier(void) { // These are typically necessary only in very specific cases (e.g. WSDeque) // where the ordered operations aren't expressive enough to capture the desired // ordering. +// +// Additionally, it is preferable to use the *_FENCE_ON() forms, which turn into +// memory accesses when compiling for ThreadSanitizer (as ThreadSanitizer is +// otherwise unable to reason about fences). See Note [ThreadSanitizer] in +// TSANUtils.h. + #define ACQUIRE_FENCE() __atomic_thread_fence(__ATOMIC_ACQUIRE) #define RELEASE_FENCE() __atomic_thread_fence(__ATOMIC_RELEASE) #define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37471bae2a217b7fcb537142f768a503b979f0da...e1bd66c4aa70f2a0130820cbac48a017f76eacf9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37471bae2a217b7fcb537142f768a503b979f0da...e1bd66c4aa70f2a0130820cbac48a017f76eacf9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 23:33:58 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Tue, 18 Apr 2023 19:33:58 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <643f28e688d07_178e7420f97e30353674@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 5de3533e by Apoorv Ingle at 2023-04-18T18:32:41-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 3 changed files: - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Gen/App.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -851,6 +852,35 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +-- warnUnusedBindValue fun arg arg_ty +-- -- | is_gen_then (unLoc fun) +-- = warnDiscardedDoBindings arg arg_ty +warnUnusedBindValue fun arg arg_ty + | Just f <- fish_var fun + , is_gen_then f + = warnDiscardedDoBindings arg arg_ty + where + fish_var :: LHsExpr GhcTc -> Maybe (LIdP GhcTc) + fish_var (L _ (HsVar _ id)) = return id + fish_var (L _ (HsAppType _ e _ _)) = do e' <- fish_var e + return e' + fish_var (L _ (HsApp _ e _)) = do e' <- fish_var e + return e' + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do e' <- fish_var (L l e) + return e' + fish_var _ = Nothing + + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L (SrcSpanAnn _ l) f) = f `hasKey` thenMClassOpKey && isNoSrcSpan l + +warnUnusedBindValue _ _ _ = return () + + +-- is this expr a compiler generated (>>) + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -397,44 +397,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -38,10 +38,10 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5de3533e8d18a7a4562e0a310ae54ee8da406477 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5de3533e8d18a7a4562e0a310ae54ee8da406477 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 18 23:38:15 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Tue, 18 Apr 2023 19:38:15 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <643f29e77e9b6_178e7420f97e4435413@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 455ee46a by Apoorv Ingle at 2023-04-18T18:38:09-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 3 changed files: - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Gen/App.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -851,6 +852,35 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +-- warnUnusedBindValue fun arg arg_ty +-- -- | is_gen_then (unLoc fun) +-- = warnDiscardedDoBindings arg arg_ty +warnUnusedBindValue fun arg arg_ty + | Just f <- fish_var fun + , is_gen_then f + = warnDiscardedDoBindings arg arg_ty + where + fish_var :: LHsExpr GhcTc -> Maybe (LIdP GhcTc) + fish_var (L _ (HsVar _ id)) = return id + fish_var (L _ (HsAppType _ e _ _)) = do e' <- fish_var e + return e' + fish_var (L _ (HsApp _ e _)) = do e' <- fish_var e + return e' + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do e' <- fish_var (L l e) + return e' + fish_var _ = Nothing + + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L (SrcSpanAnn _ l) f) = f `hasKey` thenMClassOpKey && isNoSrcSpan l + +warnUnusedBindValue _ _ _ = return () + + +-- is this expr a compiler generated (>>) + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -38,10 +38,10 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/455ee46ab8b10e2025b37af69a80cf9f4a2faf4f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/455ee46ab8b10e2025b37af69a80cf9f4a2faf4f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 06:37:21 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Wed, 19 Apr 2023 02:37:21 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 2 commits: Printer: Add missing frame support Message-ID: <643f8c2192d9c_178e7427e3db3c3769ad@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 54f91e6a by Sven Tennie at 2023-04-19T06:26:09+00:00 Printer: Add missing frame support - - - - - e42e2f82 by Sven Tennie at 2023-04-19T06:36:41+00:00 Printer: More readable RET_FUN code - - - - - 1 changed file: - rts/Printer.c Changes: ===================================== rts/Printer.c ===================================== @@ -279,6 +279,45 @@ printClosure( const StgClosure *obj ) break; } + case CATCH_RETRY_FRAME: + { + StgCatchRetryFrame* frame = (StgCatchRetryFrame*)obj; + debugBelch("CATCH_RETRY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)frame)); + debugBelch(","); + printPtr((StgPtr)frame->first_code); + debugBelch(","); + printPtr((StgPtr)frame->alt_code); + debugBelch(")\n"); + break; + } + + case CATCH_STM_FRAME: + { + StgCatchSTMFrame* frame = (StgCatchSTMFrame*)obj; + debugBelch("CATCH_STM_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)frame)); + debugBelch(","); + printPtr((StgPtr)frame->code); + debugBelch(","); + printPtr((StgPtr)frame->handler); + debugBelch(")\n"); + break; + } + + case ATOMICALLY_FRAME: + { + StgAtomicallyFrame* frame = (StgAtomicallyFrame*)obj; + debugBelch("ATOMICALLY_FRAME("); + printPtr((StgPtr)GET_INFO((StgClosure *)frame)); + debugBelch(","); + printPtr((StgPtr)frame->code); + debugBelch(","); + printPtr((StgPtr)frame->result); + debugBelch(")\n"); + break; + } + case UNDERFLOW_FRAME: { StgUnderflowFrame* u = (StgUnderflowFrame*)obj; @@ -531,6 +570,9 @@ printStackChunk( StgPtr sp, StgPtr spBottom ) case UPDATE_FRAME: case CATCH_FRAME: + case CATCH_RETRY_FRAME: + case CATCH_STM_FRAME: + case ATOMICALLY_FRAME: case UNDERFLOW_FRAME: case STOP_FRAME: printClosure((StgClosure*)sp); @@ -664,17 +706,17 @@ printStackChunk( StgPtr sp, StgPtr spBottom ) debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, (int)fun_info->f.fun_type); switch (fun_info->f.fun_type) { case ARG_GEN: - printSmallBitmap(spBottom, sp+3, + printSmallBitmap(spBottom, &ret_fun->payload, BITMAP_BITS(fun_info->f.b.bitmap), BITMAP_SIZE(fun_info->f.b.bitmap)); break; case ARG_GEN_BIG: - printLargeBitmap(spBottom, sp+3, + printLargeBitmap(spBottom, &ret_fun->payload, GET_FUN_LARGE_BITMAP(fun_info), GET_FUN_LARGE_BITMAP(fun_info)->size); break; default: - printSmallBitmap(spBottom, sp+3, + printSmallBitmap(spBottom, &ret_fun->payload, BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]), BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type])); break; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dd9506c142071a615a5d9b9478b0327477490e9...e42e2f82e63ebd350dedfc1815f89e4a009d8506 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3dd9506c142071a615a5d9b9478b0327477490e9...e42e2f82e63ebd350dedfc1815f89e4a009d8506 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 07:09:09 2023 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Wed, 19 Apr 2023 03:09:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/b/disable-abi-test-nightly Message-ID: <643f939569803_178e7428684d2c3792e4@gitlab.mail> Bryan R pushed new branch wip/b/disable-abi-test-nightly at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/b/disable-abi-test-nightly You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 07:09:47 2023 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Wed, 19 Apr 2023 03:09:47 -0400 Subject: [Git][ghc/ghc][wip/b/disable-abi-test-nightly] CI: Disable abi-test-nightly Message-ID: <643f93bb4e98b_178e74287c509c37946d@gitlab.mail> Bryan R pushed to branch wip/b/disable-abi-test-nightly at Glasgow Haskell Compiler / GHC Commits: f271f274 by Bryan Richter at 2023-04-19T10:09:36+03:00 CI: Disable abi-test-nightly See #23269 - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -484,6 +484,9 @@ abi-test-nightly: paths: - out rules: + # This job is broken. Disabling it until some kind soul can finish its + # implementation. #23269 + - when: never - if: $NIGHTLY ############################################################ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f271f27426ea905475c8dfe8028d077ac0601cf6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f271f27426ea905475c8dfe8028d077ac0601cf6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 08:02:32 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 04:02:32 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] Try -V Message-ID: <643fa01811a71_178e7429709c603853ee@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: b46a92e8 by GHC GitLab CI at 2023-04-19T09:02:19+01:00 Try -V - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -520,7 +520,7 @@ function build_hadrian() { if [[ -n "${REINSTALL_GHC:-}" ]]; then run_hadrian build-cabal -V else - run_hadrian test:all_deps binary-dist -V + run_hadrian test:all_deps binary-dist -VV mv _build/bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz" fi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b46a92e80d0b04dee969a27361dc2435105224b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b46a92e80d0b04dee969a27361dc2435105224b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 09:05:20 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 05:05:20 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t22884 Message-ID: <643faed053a94_178e742a7bc7d8399032@gitlab.mail> Matthew Pickering pushed new branch wip/t22884 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t22884 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 09:42:41 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 05:42:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mp-ghci-opt Message-ID: <643fb7913257b_178e742b0f4558408038@gitlab.mail> Matthew Pickering pushed new branch wip/mp-ghci-opt at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mp-ghci-opt You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 09:52:10 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 05:52:10 -0400 Subject: [Git][ghc/ghc][wip/t22884] error messages: Don't display ghci specific hints for missing packages Message-ID: <643fb9caa8f9f_178e742b2a31884082e8@gitlab.mail> Matthew Pickering pushed to branch wip/t22884 at Glasgow Haskell Compiler / GHC Commits: 5dd2b0dd by GHC GitLab CI at 2023-04-19T10:51:54+01:00 error messages: Don't display ghci specific hints for missing packages I am unsure about whether the approach taken here is the best of most maintainable solution. I put it up here for review and comment. Fixes #22884 - - - - - 15 changed files: - compiler/GHC/Iface/Errors/Ppr.hs - ghc/GHCi/UI/Exception.hs - + testsuite/tests/package/T22884.hs - + testsuite/tests/package/T22884.stderr - + testsuite/tests/package/T22884_interactive.script - + testsuite/tests/package/T22884_interactive.stderr - testsuite/tests/package/T4806.stderr - testsuite/tests/package/T4806a.stderr - testsuite/tests/package/all.T - testsuite/tests/package/package01e.stderr - testsuite/tests/package/package06e.stderr - testsuite/tests/package/package07e.stderr - testsuite/tests/package/package08e.stderr - testsuite/tests/plugins/T11244.stderr - testsuite/tests/plugins/plugins03.stderr Changes: ===================================== compiler/GHC/Iface/Errors/Ppr.hs ===================================== @@ -19,6 +19,11 @@ module GHC.Iface.Errors.Ppr , missingInterfaceErrorReason , missingInterfaceErrorDiagnostic , readInterfaceErrorDiagnostic + + , lookingForHerald + , cantFindErrorX + , mayShowLocations + , pkgHiddenHint ) where @@ -130,26 +135,26 @@ cantFindError :: IfaceMessageOpts -> FindingModuleOrInterface -> CantFindInstalled -> SDoc -cantFindError opts = cantFindErrorX (pkg_hidden_hint (ifaceBuildingCabalPackage opts)) (mayShowLocations (ifaceShowTriedFiles opts)) +cantFindError opts = cantFindErrorX (pkgHiddenHint (const empty) (ifaceBuildingCabalPackage opts)) (mayShowLocations "-v" (ifaceShowTriedFiles opts)) where - pkg_hidden_hint using_cabal (Just pkg) - | using_cabal == YesBuildingCabalPackage - = text "Perhaps you need to add" <+> - quotes (ppr (unitPackageName pkg)) <+> - text "to the build-depends in your .cabal file." - -- MP: This is ghci specific, remove - | otherwise - = text "You can run" <+> - quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+> - text "to expose it." $$ - text "(Note: this unloads all the modules in the current scope.)" - pkg_hidden_hint _ Nothing = empty - -mayShowLocations :: Bool -> [FilePath] -> SDoc -mayShowLocations verbose files + +pkgHiddenHint :: (UnitInfo -> SDoc) -> BuildingCabalPackage + -> Maybe UnitInfo -> SDoc +pkgHiddenHint hint using_cabal (Just pkg) + | using_cabal == YesBuildingCabalPackage + = text "Perhaps you need to add" <+> + quotes (ppr (unitPackageName pkg)) <+> + text "to the build-depends in your .cabal file." + + | otherwise + = hint pkg +pkgHiddenHint _ _ Nothing = empty + +mayShowLocations :: String -> Bool -> [FilePath] -> SDoc +mayShowLocations option verbose files | null files = empty | not verbose = - text "Use -v (or `:set -v` in ghci) " <> + text "Use" <+> text option <+> text "to see a list of the files searched for." | otherwise = hang (text "Locations searched:") 2 $ vcat (map text files) @@ -286,17 +291,17 @@ interfaceErrorDiagnostic opts = \ case Can'tFindNameInInterface name relevant_tyThings -> missingDeclInInterface name relevant_tyThings Can'tFindInterface err looking_for -> + hangNotEmpty (lookingForHerald looking_for) 2 (missingInterfaceErrorDiagnostic opts err) + +lookingForHerald :: InterfaceLookingFor -> SDoc +lookingForHerald looking_for = case looking_for of - LookingForName {} -> - missingInterfaceErrorDiagnostic opts err - LookingForModule {} -> - missingInterfaceErrorDiagnostic opts err + LookingForName {} -> empty + LookingForModule {} -> empty LookingForHiBoot mod -> - hang (text "Could not find hi-boot interface for" <+> quotes (ppr mod) <> colon) - 2 (missingInterfaceErrorDiagnostic opts err) + text "Could not find hi-boot interface for" <+> quotes (ppr mod) <> colon LookingForSig sig -> - hang (text "Could not find interface file for signature" <+> quotes (ppr sig) <> colon) - 2 (missingInterfaceErrorDiagnostic opts err) + text "Could not find interface file for signature" <+> quotes (ppr sig) <> colon readInterfaceErrorDiagnostic :: ReadInterfaceError -> SDoc readInterfaceErrorDiagnostic = \ case ===================================== ghc/GHCi/UI/Exception.hs ===================================== @@ -10,8 +10,14 @@ import GHC.Driver.Session import GHC.Types.SourceError import GHC.Driver.Errors.Types import GHC.Types.Error +import GHC.Iface.Errors.Types +import GHC.Tc.Errors.Types +import GHC.Tc.Errors.Ppr +import GHC.Iface.Errors.Ppr import GHC.Driver.Config.Diagnostic import GHC.Driver.Errors +import GHC.Utils.Outputable +import GHC.Unit.State -- | Print the all diagnostics in a 'SourceError'. Specialised for GHCi error reporting -- for some error messages. @@ -24,14 +30,14 @@ printGhciException err = do liftIO $ printMessages logger print_config diag_opts (GHCiMessage <$> (srcErrorMessages err)) -newtype GHCiMessage = GHCiMessage { getGhciMessage :: GhcMessage } +newtype GHCiMessage = GHCiMessage { _getGhciMessage :: GhcMessage } instance Diagnostic GHCiMessage where type DiagnosticOpts GHCiMessage = DiagnosticOpts GhcMessage defaultDiagnosticOpts = defaultDiagnosticOpts @GhcMessage - diagnosticMessage opts (GHCiMessage msg) = diagnosticMessage opts msg + diagnosticMessage opts (GHCiMessage msg) = ghciDiagnosticMessage opts msg diagnosticReason (GHCiMessage msg) = diagnosticReason msg @@ -39,4 +45,38 @@ instance Diagnostic GHCiMessage where diagnosticCode (GHCiMessage msg) = diagnosticCode msg +-- Modifications to error messages which we want to display in GHCi +ghciDiagnosticMessage :: GhcMessageOpts -> GhcMessage -> DecoratedSDoc +ghciDiagnosticMessage ghc_opts msg = + case msg of + GhcTcRnMessage (TcRnInterfaceError err) -> + case ghciInterfaceError err of + Just sdoc -> mkSimpleDecorated sdoc + Nothing -> diagnosticMessage ghc_opts msg + GhcDriverMessage (DriverInterfaceError err) -> + case ghciInterfaceError err of + Just sdoc -> mkSimpleDecorated sdoc + Nothing -> diagnosticMessage ghc_opts msg + _ -> diagnosticMessage ghc_opts msg + where + opts = tcOptsIfaceOpts (tcMessageOpts ghc_opts) + ghciInterfaceError (Can'tFindInterface err looking_for) = + hangNotEmpty (lookingForHerald looking_for) 2 <$> ghciMissingInterfaceErrorDiagnostic err + ghciInterfaceError _ = Nothing + + ghciMissingInterfaceErrorDiagnostic reason = + case reason of + CantFindErr us module_or_interface cfi -> Just (pprWithUnitState us $ cantFindErrorX pkg_hidden_hint may_show_locations module_or_interface cfi) + _ -> Nothing + where + + may_show_locations = mayShowLocations ":set -v" (ifaceShowTriedFiles opts) + + pkg_hidden_hint = pkgHiddenHint hidden_msg (ifaceBuildingCabalPackage opts) + where + hidden_msg pkg = + text "You can run" <+> + quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+> + text "to expose it." $$ + text "(Note: this unloads all the modules in the current scope.)" ===================================== testsuite/tests/package/T22884.hs ===================================== @@ -0,0 +1,3 @@ +module T22884 where + +import Data.Text ===================================== testsuite/tests/package/T22884.stderr ===================================== @@ -0,0 +1,5 @@ + +T22884.hs:3:1: error: [GHC-87110] + Could not load module ‘Data.Text’. + It is a member of the hidden package ‘text-2.0.2’. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/T22884_interactive.script ===================================== @@ -0,0 +1,3 @@ +:set -hide-all-packages + +import Data.Text ===================================== testsuite/tests/package/T22884_interactive.stderr ===================================== @@ -0,0 +1,6 @@ + +: error: [GHC-87110] + Could not load module ‘Data.Text’. + It is a member of the hidden package ‘text-2.0.2’. + You can run ‘:set -package text’ to expose it. + (Note: this unloads all the modules in the current scope.) ===================================== testsuite/tests/package/T4806.stderr ===================================== @@ -3,4 +3,4 @@ T4806.hs:1:1: error: [GHC-87110] Could not load module ‘Data.Map’. It is a member of the package ‘containers-0.6.7’ which is ignored due to an -ignore-package flag - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/T4806a.stderr ===================================== @@ -4,4 +4,4 @@ T4806a.hs:1:1: error: [GHC-87110] It is a member of the package ‘containers-0.6.7’ which is unusable because the -ignore-package flag was used to ignore at least one of its dependencies: deepseq-1.4.8.1 template-haskell-2.20.0.0 - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/all.T ===================================== @@ -20,3 +20,5 @@ test('package10', normal, compile, ['-hide-all-packages -package "ghc (GHC test('T4806', normalise_version('containers'), compile_fail, ['-ignore-package containers']) test('T4806a', normalise_version('deepseq', 'containers'), compile_fail, ['-ignore-package deepseq']) +test('T22884', normalise_version('text'), compile_fail, ['-hide-package text']) +test('T22884_interactive', normalise_version('text'), ghci_script, ['T22884_interactive.script']) ===================================== testsuite/tests/package/package01e.stderr ===================================== @@ -2,13 +2,9 @@ package01e.hs:2:1: error: [GHC-87110] Could not load module ‘Data.Map’. It is a member of the hidden package ‘containers-0.6.7’. - You can run ‘:set -package containers’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package01e.hs:3:1: error: [GHC-87110] Could not load module ‘Data.IntMap’. It is a member of the hidden package ‘containers-0.6.7’. - You can run ‘:set -package containers’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package06e.stderr ===================================== @@ -2,13 +2,9 @@ package06e.hs:2:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package06e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package07e.stderr ===================================== @@ -5,25 +5,19 @@ package07e.hs:2:1: error: [GHC-61948] GHC.Hs.Type (needs flag -package-id ghc-9.7) GHC.Tc.Types (needs flag -package-id ghc-9.7) GHC.Hs.Syn.Type (needs flag -package-id ghc-9.7) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:4:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Utils’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:5:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package08e.stderr ===================================== @@ -5,25 +5,19 @@ package08e.hs:2:1: error: [GHC-61948] GHC.Hs.Type (needs flag -package-id ghc-9.7) GHC.Tc.Types (needs flag -package-id ghc-9.7) GHC.Hs.Syn.Type (needs flag -package-id ghc-9.7) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:4:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Utils’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:5:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/plugins/T11244.stderr ===================================== @@ -1,5 +1,3 @@ : Could not load module ‘RuleDefiningPlugin’. It is a member of the hidden package ‘rule-defining-plugin-0.1’. -You can run ‘:set -package rule-defining-plugin’ to expose it. -(Note: this unloads all the modules in the current scope.) -Use -v (or `:set -v` in ghci) to see a list of the files searched for. +Use -v to see a list of the files searched for. ===================================== testsuite/tests/plugins/plugins03.stderr ===================================== @@ -1,2 +1,2 @@ : Could not find module ‘Simple.NonExistentPlugin’. -Use -v (or `:set -v` in ghci) to see a list of the files searched for. +Use -v to see a list of the files searched for. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5dd2b0ddc3cbae767b09302781aa7fe52815e4b4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5dd2b0ddc3cbae767b09302781aa7fe52815e4b4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 11:00:56 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 07:00:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t23273 Message-ID: <643fc9e8936d4_178e742c3cd314431469@gitlab.mail> Matthew Pickering pushed new branch wip/t23273 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t23273 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 11:01:37 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 07:01:37 -0400 Subject: [Git][ghc/ghc][wip/t23273] hadrian: Pass haddock file arguments in a response file Message-ID: <643fca112102d_178e742c8f98104316df@gitlab.mail> Matthew Pickering pushed to branch wip/t23273 at Glasgow Haskell Compiler / GHC Commits: c6469c70 by Matthew Pickering at 2023-04-19T12:01:15+01:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 2 changed files: - hadrian/src/Builder.hs - hadrian/src/Settings/Builders/Haddock.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock {} -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6469c703e7603b4229788c3beb2c79b43b6812f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6469c703e7603b4229788c3beb2c79b43b6812f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 14:16:58 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 19 Apr 2023 10:16:58 -0400 Subject: [Git][ghc/ghc][wip/T23083] CorePrep: Eta expand arguments (#23083) Message-ID: <643ff7da455e6_178e74300223284610b5@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 62c23369 by Sebastian Graf at 2023-04-19T16:16:50+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 10 changed files: - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1047,16 +1047,16 @@ it off at source. -} {-# INLINE trivial_expr_fold #-} -trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r +trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> (CoreExpr -> r) -> CoreExpr -> r -- ^ The worker function for Note [exprIsTrivial] and Note [getIdFromTrivialExpr] -- This is meant to have the code of both functions in one place and make it -- easy to derive custom predicates. -- -- (trivial_expr_fold k_id k_triv k_not_triv e) --- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping) +-- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping W such that e = W[x]) -- * returns (k_lit x) if `e` is a trivial literal `l` (with trivial wrapping) -- * returns k_triv if `e` is a literal, type, or coercion (with trivial wrapping) --- * returns k_not_triv otherwise +-- * returns (k_not_triv e') if e' is not trivial (with trivial wrapping W such that e = W[e']) -- -- where "trivial wrapping" is -- * Type application or abstraction @@ -1073,10 +1073,10 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial] go (Cast e _) = go e go (Case e _ _ []) = go e -- See Note [Empty case is trivial] - go _ = k_not_triv + go e = k_not_triv e exprIsTrivial :: CoreExpr -> Bool -exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e +exprIsTrivial e = trivial_expr_fold (const True) (const True) True (const False) e {- Note [getIdFromTrivialExpr] @@ -1097,12 +1097,12 @@ T12076lit for an example where this matters. getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id -- See Note [getIdFromTrivialExpr] -getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic panic e +getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic (const panic) e where panic = pprPanic "getIdFromTrivialExpr" (ppr e) getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id -getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing Nothing e +getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing (const Nothing) e {- ********************************************************************* * * ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -552,9 +552,11 @@ coreToStgApp f args ticks = do -- --------------------------------------------------------------------------- getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg -getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic try_string e where panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + try_string (Lit l at LitString{}) = StgLitArg l -- string literals are not considered trivial, but atomic + try_string _ = panic coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1445,12 +1445,33 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1568,6 +1589,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1931,6 +1990,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1941,6 +2005,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +module T23083 where + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,42 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 27, types: 24, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 12, types: 13, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> GHC.Base.$ @GHC.Types.LiftedRep @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62c23369514a68c7f6903062722c800ff6c6b686 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62c23369514a68c7f6903062722c800ff6c6b686 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 14:17:30 2023 From: gitlab at gitlab.haskell.org (Finley McIlwaine (@FinleyMcIlwaine)) Date: Wed, 19 Apr 2023 10:17:30 -0400 Subject: [Git][ghc/ghc][wip/t21766] 154 commits: Bump Win32 to 2.13.4.0 Message-ID: <643ff7fa177b2_178e743002a7d046147d@gitlab.mail> Finley McIlwaine pushed to branch wip/t21766 at Glasgow Haskell Compiler / GHC Commits: 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 7f1685e3 by Finley McIlwaine at 2023-04-19T07:51:08-06:00 Restructure IPE buffer layout Reference ticket #21766 This commit restructures IPE buffer list entries to not contain references to their corresponding info tables. IPE buffer list nodes now point to two lists of equal length, one holding the list of info table pointers and one holding the corresponding entries for each info table. This will allow the entry data to be compressed without losing the references to the info tables. - - - - - 5d02dcb6 by Finley McIlwaine at 2023-04-19T07:51:08-06:00 Add IPE compression to configure Reference ticket #21766 Adds an `--enable-ipe-data-compreesion` flag to the configure script which will check for libzstd and set the appropriate flags to allow for IPE data compression in the compiler - - - - - 00eef96b by Finley McIlwaine at 2023-04-19T07:51:09-06:00 IPE data compression Reference ticket #21766 When IPE data compression is enabled, compress the emitted IPE buffer entries and decompress them in the RTS. - - - - - f9302df4 by Finley McIlwaine at 2023-04-19T07:51:09-06:00 Fix libzstd detection in configure and RTS Ensure that `HAVE_LIBZSTD` gets defined to either 0 or 1 in all cases and properly check that before IPE data decompression in the RTS. See ticket #21766. - - - - - 0e749e42 by Finley McIlwaine at 2023-04-19T07:51:09-06:00 Add note describing IPE data compression See ticket #21766 - - - - - f1ed5955 by Finley McIlwaine at 2023-04-19T07:51:09-06:00 Fix byte order of IPE data, fix IPE tests Make sure byte order of written IPE buffer entries matches target. Make sure the IPE-related tests properly access the fields of IPE buffer entry nodes with the new IPE layout. This commit also introduces checks to avoid importing modules if IPE compression is not enabled. See ticket #21766. - - - - - aa863333 by Finley McIlwaine at 2023-04-19T07:51:09-06:00 Fix IPE data decompression buffer allocation Capacity of buffers allocated for decompressed IPE data was incorrect due to a misuse of the `ZSTD_findFrameCompressedSize` function. Fix by always storing decompressed size of IPE data in IPE buffer list nodes and using `ZSTD_findFrameCompressedSize` to determine the size of the compressed data. See ticket #21766 - - - - - b4c21916 by Finley McIlwaine at 2023-04-19T07:51:09-06:00 Add optional dependencies to ./configure output Changes the configure script to indicate whether libnuma, libzstd, or libdw are being used as dependencies due to their optional features being enabled. - - - - - 9a483ba7 by Finley McIlwaine at 2023-04-19T07:57:43-06:00 Add IPE-enabled builds to CI - Adds an IPE job to the CI pipeline which is triggered by the ~IPE label - Introduces CI logic to enable IPE data compression - Enables uncompressed IPE data on debug CI job - Regenerates jobs.yaml MR https://gitlab.haskell.org/ghc/ci-images/-/merge_requests/112 on the images repository is meant to ensure that the proper images have libzstd-dev installed. - - - - - ab0fe323 by Finley McIlwaine at 2023-04-19T07:59:46-06:00 Update user's guide and release notes Add mention of IPE data compression to user's guide and the release notes for 9.8.1. Also note the impact compression has on binary size in both places. See ticket #21766 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4db6e54eb3986e22fd4135fcb261951b6de046bd...ab0fe323b235236798e6c2fd37b5ab409e0029ff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4db6e54eb3986e22fd4135fcb261951b6de046bd...ab0fe323b235236798e6c2fd37b5ab409e0029ff You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 14:37:50 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 10:37:50 -0400 Subject: [Git][ghc/ghc][wip/t23273] hadrian: Pass haddock file arguments in a response file Message-ID: <643ffcbea8a0f_178e7430575730464464@gitlab.mail> Matthew Pickering pushed to branch wip/t23273 at Glasgow Haskell Compiler / GHC Commits: 27a87a09 by GHC GitLab CI at 2023-04-19T15:37:43+01:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 2 changed files: - hadrian/src/Builder.hs - hadrian/src/Settings/Builders/Haddock.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock BuildPackage -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27a87a092751b0bdb2e6caadc062ee22c6e75a0d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/27a87a092751b0bdb2e6caadc062ee22c6e75a0d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 14:54:55 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 10:54:55 -0400 Subject: [Git][ghc/ghc][wip/t23273] hadrian: Pass haddock file arguments in a response file Message-ID: <644000bf728d1_178e7430ca51184724cb@gitlab.mail> Matthew Pickering pushed to branch wip/t23273 at Glasgow Haskell Compiler / GHC Commits: 1b5edccc by Matthew Pickering at 2023-04-19T15:54:41+01:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 2 changed files: - hadrian/src/Builder.hs - hadrian/src/Settings/Builders/Haddock.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock BuildPackage -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b5edccc52c2542531d4b47134845e4b2073a338 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b5edccc52c2542531d4b47134845e4b2073a338 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 15:01:38 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 19 Apr 2023 11:01:38 -0400 Subject: [Git][ghc/ghc][wip/t22884] 2 commits: Abstract cantFindError and turn Opt_BuildingCabal into a print-time option Message-ID: <6440025282f83_178e7430d3801c473069@gitlab.mail> Matthew Pickering pushed to branch wip/t22884 at Glasgow Haskell Compiler / GHC Commits: 01c5ccbf by Matthew Pickering at 2023-04-19T16:01:11+01:00 Abstract cantFindError and turn Opt_BuildingCabal into a print-time option * cantFindError is abstracted so that the parts which mention specific things about ghc/ghci are parameters. The intention being that GHC/GHCi can specify the right values to put here but otherwise display the same error message. * The BuildingCabalPackage argument from GenericMissing is removed and turned into a print-time option. The reason for the error is not dependent on whether `-fbuilding-cabal-package` is passed, so we don't want to store that in the error message. - - - - - baea3f58 by Matthew Pickering at 2023-04-19T16:01:15+01:00 error messages: Don't display ghci specific hints for missing packages I am unsure about whether the approach taken here is the best of most maintainable solution. I put it up here for review and comment. Fixes #22884 - - - - - 26 changed files: - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Iface/Errors/Types.hs - ghc/GHCi/UI/Exception.hs - testsuite/tests/driver/multipleHomeUnits/multipleHomeUnitsModuleVisibility.stderr - testsuite/tests/ghc-api/target-contents/TargetContents.stderr - testsuite/tests/ghc-e/should_run/T2636.stderr - testsuite/tests/module/mod1.stderr - testsuite/tests/module/mod2.stderr - + testsuite/tests/package/T22884.hs - + testsuite/tests/package/T22884.stderr - + testsuite/tests/package/T22884_interactive.script - + testsuite/tests/package/T22884_interactive.stderr - testsuite/tests/package/T4806.stderr - testsuite/tests/package/T4806a.stderr - testsuite/tests/package/all.T - testsuite/tests/package/package01e.stderr - testsuite/tests/package/package06e.stderr - testsuite/tests/package/package07e.stderr - testsuite/tests/package/package08e.stderr - testsuite/tests/perf/compiler/parsing001.stderr - testsuite/tests/plugins/T11244.stderr - testsuite/tests/plugins/plugins03.stderr - testsuite/tests/safeHaskell/safeLanguage/SafeLang07.stderr - testsuite/tests/typecheck/should_fail/tcfail082.stderr Changes: ===================================== compiler/GHC/Driver/Config/Diagnostic.hs ===================================== @@ -18,7 +18,7 @@ import GHC.Prelude import GHC.Utils.Outputable import GHC.Utils.Error (DiagOpts (..)) -import GHC.Driver.Errors.Types (GhcMessage, GhcMessageOpts (..), PsMessage, DriverMessage, DriverMessageOpts (..)) +import GHC.Driver.Errors.Types (GhcMessage, GhcMessageOpts (..), PsMessage, DriverMessage, DriverMessageOpts (..), checkBuildingCabalPackage) import GHC.Driver.Errors.Ppr () import GHC.Tc.Errors.Types import GHC.HsToCore.Errors.Types @@ -63,7 +63,8 @@ initDsMessageOpts _ = NoDiagnosticOpts initIfaceMessageOpts :: DynFlags -> DiagnosticOpts IfaceMessage initIfaceMessageOpts dflags = - IfaceMessageOpts { ifaceShowTriedFiles = verbosity dflags >= 3 } + IfaceMessageOpts { ifaceShowTriedFiles = verbosity dflags >= 3 + , ifaceBuildingCabalPackage = checkBuildingCabalPackage dflags } initDriverMessageOpts :: DynFlags -> DiagnosticOpts DriverMessage initDriverMessageOpts dflags = DriverMessageOpts (initPsMessageOpts dflags) (initIfaceMessageOpts dflags) ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -13,7 +13,6 @@ import GHC.Platform.Ways import GHC.Utils.Panic.Plain import GHC.Driver.Session import GHC.Driver.Env -import GHC.Driver.Errors.Types import GHC.Data.Maybe import GHC.Prelude import GHC.Unit @@ -80,32 +79,29 @@ cantFindInstalledErr unit_state mhome_unit profile mod_name find_result cannotFindModule :: HscEnv -> ModuleName -> FindResult -> MissingInterfaceError cannotFindModule hsc_env = cannotFindModule' - (hsc_dflags hsc_env) (hsc_unit_env hsc_env) (targetProfile (hsc_dflags hsc_env)) -cannotFindModule' :: DynFlags -> UnitEnv -> Profile -> ModuleName -> FindResult +cannotFindModule' :: UnitEnv -> Profile -> ModuleName -> FindResult -> MissingInterfaceError -cannotFindModule' dflags unit_env profile mod res = +cannotFindModule' unit_env profile mod res = CantFindErr (ue_units unit_env) FindingModule $ - cantFindErr (checkBuildingCabalPackage dflags) - unit_env + cantFindErr unit_env profile mod res cantFindErr - :: BuildingCabalPackage -- ^ Using Cabal? - -> UnitEnv + :: UnitEnv -> Profile -> ModuleName -> FindResult -> CantFindInstalled -cantFindErr _ _ _ mod_name (FoundMultiple mods) +cantFindErr _ _ mod_name (FoundMultiple mods) = CantFindInstalled mod_name (MultiplePackages mods) -cantFindErr using_cabal unit_env profile mod_name find_result +cantFindErr unit_env profile mod_name find_result = CantFindInstalled mod_name more_info where mhome_unit = ue_homeUnit unit_env @@ -133,7 +129,7 @@ cantFindErr using_cabal unit_env profile mod_name find_result -> NotAModule | otherwise - -> GenericMissing using_cabal + -> GenericMissing (map ((\uid -> (uid, lookupUnit (ue_units unit_env) uid))) pkg_hiddens) mod_hiddens unusables files _ -> panic "cantFindErr" ===================================== compiler/GHC/Iface/Errors/Ppr.hs ===================================== @@ -19,6 +19,11 @@ module GHC.Iface.Errors.Ppr , missingInterfaceErrorReason , missingInterfaceErrorDiagnostic , readInterfaceErrorDiagnostic + + , lookingForHerald + , cantFindErrorX + , mayShowLocations + , pkgHiddenHint ) where @@ -41,10 +46,12 @@ import GHC.Utils.Panic import GHC.Iface.Errors.Types data IfaceMessageOpts = IfaceMessageOpts { ifaceShowTriedFiles :: !Bool -- ^ Whether to show files we tried to look for or not when printing loader errors + , ifaceBuildingCabalPackage :: !BuildingCabalPackage } defaultIfaceMessageOpts :: IfaceMessageOpts -defaultIfaceMessageOpts = IfaceMessageOpts { ifaceShowTriedFiles = False } +defaultIfaceMessageOpts = IfaceMessageOpts { ifaceShowTriedFiles = False + , ifaceBuildingCabalPackage = NoBuildingCabalPackage } instance Diagnostic IfaceMessage where @@ -116,7 +123,7 @@ isAmbiguousInstalledReason _ = AoM_Missing isLoadOrFindReason :: CantFindInstalledReason -> FindOrLoad isLoadOrFindReason NotAModule {} = Find -isLoadOrFindReason (GenericMissing _ a b c _) | null a && null b && null c = Find +isLoadOrFindReason (GenericMissing a b c _) | null a && null b && null c = Find isLoadOrFindReason (ModuleSuggestion {}) = Find isLoadOrFindReason _ = Load @@ -124,8 +131,38 @@ data FindOrLoad = Find | Load data AmbiguousOrMissing = AoM_Ambiguous | AoM_Missing -cantFindError :: IfaceMessageOpts -> FindingModuleOrInterface -> CantFindInstalled -> SDoc -cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = +cantFindError :: IfaceMessageOpts + -> FindingModuleOrInterface + -> CantFindInstalled + -> SDoc +cantFindError opts = cantFindErrorX (pkgHiddenHint (const empty) (ifaceBuildingCabalPackage opts)) (mayShowLocations "-v" (ifaceShowTriedFiles opts)) + where + +pkgHiddenHint :: (UnitInfo -> SDoc) -> BuildingCabalPackage + -> Maybe UnitInfo -> SDoc +pkgHiddenHint hint using_cabal (Just pkg) + | using_cabal == YesBuildingCabalPackage + = text "Perhaps you need to add" <+> + quotes (ppr (unitPackageName pkg)) <+> + text "to the build-depends in your .cabal file." + + | otherwise + = hint pkg +pkgHiddenHint _ _ Nothing = empty + +mayShowLocations :: String -> Bool -> [FilePath] -> SDoc +mayShowLocations option verbose files + | null files = empty + | not verbose = + text "Use" <+> text option <+> + text "to see a list of the files searched for." + | otherwise = + hang (text "Locations searched:") 2 $ vcat (map text files) + +-- | General version of cantFindError which has some holes which allow GHC/GHCi to display slightly different +-- error messages. +cantFindErrorX :: (Maybe UnitInfo -> SDoc) -> ([FilePath] -> SDoc) -> FindingModuleOrInterface -> CantFindInstalled -> SDoc +cantFindErrorX pkg_hidden_hint mayShowLocations mod_or_interface (CantFindInstalled mod_name cfir) = let ambig = isAmbiguousInstalledReason cfir find_or_load = isLoadOrFindReason cfir ppr_what = prettyCantFindWhat find_or_load mod_or_interface ambig @@ -153,11 +190,11 @@ cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = text "There are files missing in the " <> quotes (ppr pkg) <+> text "package," $$ text "try running 'ghc-pkg check'." $$ - mayShowLocations verbose files + mayShowLocations files MissingPackageWayFiles build pkg files -> text "Perhaps you haven't installed the " <> text build <+> text "libraries for package " <> quotes (ppr pkg) <> char '?' $$ - mayShowLocations verbose files + mayShowLocations files ModuleSuggestion ms fps -> let pp_suggestions :: [ModuleSuggestion] -> SDoc @@ -199,7 +236,7 @@ cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = <+> ppr (mkUnit pkg)) | otherwise = empty - in pp_suggestions ms $$ mayShowLocations verbose fps + in pp_suggestions ms $$ mayShowLocations fps NotAModule -> text "It is not a module in the current program, or in any known package." CouldntFindInFiles fps -> vcat (map text fps) MultiplePackages mods @@ -213,14 +250,12 @@ cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = unambiguousPackage (Just xs) (m, ModOrigin (Just _) _ _ _) = Just (moduleUnit m : xs) unambiguousPackage _ _ = Nothing - GenericMissing using_cabal pkg_hiddens mod_hiddens unusables files -> - vcat (map (pkg_hidden using_cabal) pkg_hiddens) $$ + GenericMissing pkg_hiddens mod_hiddens unusables files -> + vcat (map pkg_hidden pkg_hiddens) $$ vcat (map mod_hidden mod_hiddens) $$ vcat (map unusable unusables) $$ - mayShowLocations verbose files + mayShowLocations files where - verbose = ifaceShowTriedFiles opts - pprMod (m, o) = text "it is bound as" <+> ppr m <+> text "by" <+> pprOrigin m o pprOrigin _ ModHidden = panic "cantFindErr: bound by mod hidden" @@ -233,26 +268,14 @@ cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = .ppr.mkUnit) res ++ if f then [text "a package flag"] else [] ) - pkg_hidden :: BuildingCabalPackage -> (Unit, Maybe UnitInfo) -> SDoc - pkg_hidden using_cabal (uid, uif) = + pkg_hidden :: (Unit, Maybe UnitInfo) -> SDoc + pkg_hidden (uid, uif) = text "It is a member of the hidden package" <+> quotes (ppr uid) --FIXME: we don't really want to show the unit id here we should -- show the source package id or installed package id if it's ambiguous - <> dot $$ pkg_hidden_hint using_cabal uif - - pkg_hidden_hint using_cabal (Just pkg) - | using_cabal == YesBuildingCabalPackage - = text "Perhaps you need to add" <+> - quotes (ppr (unitPackageName pkg)) <+> - text "to the build-depends in your .cabal file." - -- MP: This is ghci specific, remove - | otherwise - = text "You can run" <+> - quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+> - text "to expose it." $$ - text "(Note: this unloads all the modules in the current scope.)" - pkg_hidden_hint _ Nothing = empty + <> dot $$ pkg_hidden_hint uif + mod_hidden pkg = text "it is a hidden module in the package" <+> quotes (ppr pkg) @@ -262,31 +285,23 @@ cantFindError opts mod_or_interface (CantFindInstalled mod_name cfir) = <+> quotes (ppr pkg) $$ pprReason (text "which is") reason -mayShowLocations :: Bool -> [FilePath] -> SDoc -mayShowLocations verbose files - | null files = empty - | not verbose = - text "Use -v (or `:set -v` in ghci) " <> - text "to see a list of the files searched for." - | otherwise = - hang (text "Locations searched:") 2 $ vcat (map text files) interfaceErrorDiagnostic :: IfaceMessageOpts -> IfaceMessage -> SDoc interfaceErrorDiagnostic opts = \ case Can'tFindNameInInterface name relevant_tyThings -> missingDeclInInterface name relevant_tyThings Can'tFindInterface err looking_for -> + hangNotEmpty (lookingForHerald looking_for) 2 (missingInterfaceErrorDiagnostic opts err) + +lookingForHerald :: InterfaceLookingFor -> SDoc +lookingForHerald looking_for = case looking_for of - LookingForName {} -> - missingInterfaceErrorDiagnostic opts err - LookingForModule {} -> - missingInterfaceErrorDiagnostic opts err + LookingForName {} -> empty + LookingForModule {} -> empty LookingForHiBoot mod -> - hang (text "Could not find hi-boot interface for" <+> quotes (ppr mod) <> colon) - 2 (missingInterfaceErrorDiagnostic opts err) + text "Could not find hi-boot interface for" <+> quotes (ppr mod) <> colon LookingForSig sig -> - hang (text "Could not find interface file for signature" <+> quotes (ppr sig) <> colon) - 2 (missingInterfaceErrorDiagnostic opts err) + text "Could not find interface file for signature" <+> quotes (ppr sig) <> colon readInterfaceErrorDiagnostic :: ReadInterfaceError -> SDoc readInterfaceErrorDiagnostic = \ case ===================================== compiler/GHC/Iface/Errors/Types.hs ===================================== @@ -70,7 +70,7 @@ data CantFindInstalledReason | ModuleSuggestion [ModuleSuggestion] [FilePath] | NotAModule | CouldntFindInFiles [FilePath] - | GenericMissing BuildingCabalPackage + | GenericMissing [(Unit, Maybe UnitInfo)] [Unit] [(Unit, UnusableUnitReason)] [FilePath] | MultiplePackages [(Module, ModuleOrigin)] ===================================== ghc/GHCi/UI/Exception.hs ===================================== @@ -10,8 +10,14 @@ import GHC.Driver.Session import GHC.Types.SourceError import GHC.Driver.Errors.Types import GHC.Types.Error +import GHC.Iface.Errors.Types +import GHC.Tc.Errors.Types +import GHC.Tc.Errors.Ppr +import GHC.Iface.Errors.Ppr import GHC.Driver.Config.Diagnostic import GHC.Driver.Errors +import GHC.Utils.Outputable +import GHC.Unit.State -- | Print the all diagnostics in a 'SourceError'. Specialised for GHCi error reporting -- for some error messages. @@ -24,14 +30,14 @@ printGhciException err = do liftIO $ printMessages logger print_config diag_opts (GHCiMessage <$> (srcErrorMessages err)) -newtype GHCiMessage = GHCiMessage { getGhciMessage :: GhcMessage } +newtype GHCiMessage = GHCiMessage { _getGhciMessage :: GhcMessage } instance Diagnostic GHCiMessage where type DiagnosticOpts GHCiMessage = DiagnosticOpts GhcMessage defaultDiagnosticOpts = defaultDiagnosticOpts @GhcMessage - diagnosticMessage opts (GHCiMessage msg) = diagnosticMessage opts msg + diagnosticMessage opts (GHCiMessage msg) = ghciDiagnosticMessage opts msg diagnosticReason (GHCiMessage msg) = diagnosticReason msg @@ -39,4 +45,38 @@ instance Diagnostic GHCiMessage where diagnosticCode (GHCiMessage msg) = diagnosticCode msg +-- Modifications to error messages which we want to display in GHCi +ghciDiagnosticMessage :: GhcMessageOpts -> GhcMessage -> DecoratedSDoc +ghciDiagnosticMessage ghc_opts msg = + case msg of + GhcTcRnMessage (TcRnInterfaceError err) -> + case ghciInterfaceError err of + Just sdoc -> mkSimpleDecorated sdoc + Nothing -> diagnosticMessage ghc_opts msg + GhcDriverMessage (DriverInterfaceError err) -> + case ghciInterfaceError err of + Just sdoc -> mkSimpleDecorated sdoc + Nothing -> diagnosticMessage ghc_opts msg + _ -> diagnosticMessage ghc_opts msg + where + opts = tcOptsIfaceOpts (tcMessageOpts ghc_opts) + ghciInterfaceError (Can'tFindInterface err looking_for) = + hangNotEmpty (lookingForHerald looking_for) 2 <$> ghciMissingInterfaceErrorDiagnostic err + ghciInterfaceError _ = Nothing + + ghciMissingInterfaceErrorDiagnostic reason = + case reason of + CantFindErr us module_or_interface cfi -> Just (pprWithUnitState us $ cantFindErrorX pkg_hidden_hint may_show_locations module_or_interface cfi) + _ -> Nothing + where + + may_show_locations = mayShowLocations ":set -v" (ifaceShowTriedFiles opts) + + pkg_hidden_hint = pkgHiddenHint hidden_msg (ifaceBuildingCabalPackage opts) + where + hidden_msg pkg = + text "You can run" <+> + quotes (text ":set -package " <> ppr (unitPackageName pkg)) <+> + text "to expose it." $$ + text "(Note: this unloads all the modules in the current scope.)" ===================================== testsuite/tests/driver/multipleHomeUnits/multipleHomeUnitsModuleVisibility.stderr ===================================== @@ -2,4 +2,4 @@ module-visibility-import/MV.hs:5:1: error: [GHC-87110] Could not load module ‘MV2’. it is a hidden module in the package ‘mv’ - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/ghc-api/target-contents/TargetContents.stderr ===================================== @@ -18,7 +18,7 @@ B.hs:3:5: error: [GHC-88464] Variable not in scope: z A.hs:3:1: error: [GHC-87110] Could not find module ‘B’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. == Dep_DM_AB == Dep_Error_DM_AB @@ -27,7 +27,7 @@ B.hs:3:5: error: [GHC-88464] Variable not in scope: z A.hs:3:1: error: [GHC-87110] Could not find module ‘B’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. == Dep_MD_AB == Dep_Error_MD_AB ===================================== testsuite/tests/ghc-e/should_run/T2636.stderr ===================================== @@ -1,4 +1,4 @@ T2636.hs:1:1: error: [GHC-87110] Could not find module ‘MissingModule’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/module/mod1.stderr ===================================== @@ -1,4 +1,4 @@ mod1.hs:3:1: error: [GHC-87110] Could not find module ‘N’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/module/mod2.stderr ===================================== @@ -1,4 +1,4 @@ mod2.hs:3:1: error: [GHC-87110] Could not find module ‘N’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/T22884.hs ===================================== @@ -0,0 +1,3 @@ +module T22884 where + +import Data.Text ===================================== testsuite/tests/package/T22884.stderr ===================================== @@ -0,0 +1,5 @@ + +T22884.hs:3:1: error: [GHC-87110] + Could not load module ‘Data.Text’. + It is a member of the hidden package ‘text-2.0.2’. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/T22884_interactive.script ===================================== @@ -0,0 +1,3 @@ +:set -hide-all-packages + +import Data.Text ===================================== testsuite/tests/package/T22884_interactive.stderr ===================================== @@ -0,0 +1,6 @@ + +: error: [GHC-87110] + Could not load module ‘Data.Text’. + It is a member of the hidden package ‘text-2.0.2’. + You can run ‘:set -package text’ to expose it. + (Note: this unloads all the modules in the current scope.) ===================================== testsuite/tests/package/T4806.stderr ===================================== @@ -3,4 +3,4 @@ T4806.hs:1:1: error: [GHC-87110] Could not load module ‘Data.Map’. It is a member of the package ‘containers-0.6.7’ which is ignored due to an -ignore-package flag - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/T4806a.stderr ===================================== @@ -4,4 +4,4 @@ T4806a.hs:1:1: error: [GHC-87110] It is a member of the package ‘containers-0.6.7’ which is unusable because the -ignore-package flag was used to ignore at least one of its dependencies: deepseq-1.4.8.1 template-haskell-2.20.0.0 - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/all.T ===================================== @@ -20,3 +20,5 @@ test('package10', normal, compile, ['-hide-all-packages -package "ghc (GHC test('T4806', normalise_version('containers'), compile_fail, ['-ignore-package containers']) test('T4806a', normalise_version('deepseq', 'containers'), compile_fail, ['-ignore-package deepseq']) +test('T22884', normalise_version('text'), compile_fail, ['-hide-package text']) +test('T22884_interactive', normalise_version('text'), ghci_script, ['T22884_interactive.script']) ===================================== testsuite/tests/package/package01e.stderr ===================================== @@ -2,13 +2,9 @@ package01e.hs:2:1: error: [GHC-87110] Could not load module ‘Data.Map’. It is a member of the hidden package ‘containers-0.6.7’. - You can run ‘:set -package containers’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package01e.hs:3:1: error: [GHC-87110] Could not load module ‘Data.IntMap’. It is a member of the hidden package ‘containers-0.6.7’. - You can run ‘:set -package containers’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package06e.stderr ===================================== @@ -2,13 +2,9 @@ package06e.hs:2:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package06e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package07e.stderr ===================================== @@ -5,25 +5,19 @@ package07e.hs:2:1: error: [GHC-61948] GHC.Hs.Type (needs flag -package-id ghc-9.7) GHC.Tc.Types (needs flag -package-id ghc-9.7) GHC.Hs.Syn.Type (needs flag -package-id ghc-9.7) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:4:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Utils’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package07e.hs:5:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/package/package08e.stderr ===================================== @@ -5,25 +5,19 @@ package08e.hs:2:1: error: [GHC-61948] GHC.Hs.Type (needs flag -package-id ghc-9.7) GHC.Tc.Types (needs flag -package-id ghc-9.7) GHC.Hs.Syn.Type (needs flag -package-id ghc-9.7) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:3:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Type’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:4:1: error: [GHC-87110] Could not load module ‘GHC.Hs.Utils’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. package08e.hs:5:1: error: [GHC-87110] Could not load module ‘GHC.Types.Unique.FM’. It is a member of the hidden package ‘ghc-9.7’. - You can run ‘:set -package ghc’ to expose it. - (Note: this unloads all the modules in the current scope.) - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/perf/compiler/parsing001.stderr ===================================== @@ -1,4 +1,4 @@ parsing001.hs:3:1: error: [GHC-87110] Could not find module ‘Wibble’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/plugins/T11244.stderr ===================================== @@ -1,5 +1,3 @@ : Could not load module ‘RuleDefiningPlugin’. It is a member of the hidden package ‘rule-defining-plugin-0.1’. -You can run ‘:set -package rule-defining-plugin’ to expose it. -(Note: this unloads all the modules in the current scope.) -Use -v (or `:set -v` in ghci) to see a list of the files searched for. +Use -v to see a list of the files searched for. ===================================== testsuite/tests/plugins/plugins03.stderr ===================================== @@ -1,2 +1,2 @@ : Could not find module ‘Simple.NonExistentPlugin’. -Use -v (or `:set -v` in ghci) to see a list of the files searched for. +Use -v to see a list of the files searched for. ===================================== testsuite/tests/safeHaskell/safeLanguage/SafeLang07.stderr ===================================== @@ -4,4 +4,4 @@ SafeLang07.hs:2:14: warning: SafeLang07.hs:15:1: error: [GHC-87110] Could not find module ‘SafeLang07_A’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. ===================================== testsuite/tests/typecheck/should_fail/tcfail082.stderr ===================================== @@ -1,12 +1,12 @@ tcfail082.hs:2:1: error: [GHC-87110] Could not find module ‘Data82’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. tcfail082.hs:3:1: error: [GHC-87110] Could not find module ‘Inst82_1’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. tcfail082.hs:4:1: error: [GHC-87110] Could not find module ‘Inst82_2’. - Use -v (or `:set -v` in ghci) to see a list of the files searched for. + Use -v to see a list of the files searched for. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5dd2b0ddc3cbae767b09302781aa7fe52815e4b4...baea3f5869eb108e04b94cc3d3e958d243fa6026 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5dd2b0ddc3cbae767b09302781aa7fe52815e4b4...baea3f5869eb108e04b94cc3d3e958d243fa6026 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 16:16:33 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 19 Apr 2023 12:16:33 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] 32 commits: Add support for -debug in the testsuite Message-ID: <644013e185e89_178e74324e10244797b3@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 01eb5675 by Josh Meredith at 2023-04-19T16:13:14+00:00 JS: fix bounds checking (Issue 23123) * For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. * Range-based operations must also check both the start and end of the range for bounds * All indicies are valid for ranges of size zero, since they are essentially no-ops * For cases of ByteArray accesses (e.g. read as Int), the end index is (i * sizeof(type) + sizeof(type) - 1), while the previous implementation uses (i + sizeof(type) - 1). In the Int32 example, this is (i * 4 + 3) * IndexByteArrayOp_Word8As* primitives use byte array indicies (unlike the previous point), but now check both start and end indicies * Byte array copies now check if the arrays are the same by identity and then if the ranges overlap. - - - - - 30 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53fbf7770b7199397be405e5d13708722285d15e...01eb56758888aea5c754ac1023f5a780411b48a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/53fbf7770b7199397be405e5d13708722285d15e...01eb56758888aea5c754ac1023f5a780411b48a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 16:28:03 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 19 Apr 2023 12:28:03 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] 280 commits: Improve GHC.Tc.Gen.App.tcInstFun Message-ID: <644016939026_178e74325b539c480414@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Bodigrim at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Bodigrim at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 4f6a849f by Josh Meredith at 2023-04-19T16:27:47+00:00 Unboxed codebuffer implementation with pattern synonyms - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - .gitlab/test-metrics.sh - .gitmodules - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f132e85bf7b1c3ca46a28f692e0604f41371ebb6...4f6a849f4de75caf7619096b32a513c3672d4313 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f132e85bf7b1c3ca46a28f692e0604f41371ebb6...4f6a849f4de75caf7619096b32a513c3672d4313 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 16:29:17 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 19 Apr 2023 12:29:17 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] Apply 1 suggestion(s) to 1 file(s) Message-ID: <644016dd8a3e_178e74327200b048068c@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 69036ae3 by Sylvain Henry at 2023-04-19T16:29:15+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - libraries/base/jsbits/base.js Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -898,7 +898,11 @@ function h$mkdir(path, path_offset, mode) { try { h$fs.mkdirSync(d, {mode: mode}); } catch(e) { - h$errno = e.errno; + // we can't directly set errno code, because numbers may not match + // e.g. e.errno is -17 for EEXIST while we would expect -20 + // this is probably an inconsistency between nodejs using the native + // environment and everything else using Emscripten-provided headers. + h$setErrno(e); return -1; } return 0; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69036ae3dd07be53045301fdba05a1258e775371 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69036ae3dd07be53045301fdba05a1258e775371 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 16:50:04 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 19 Apr 2023 12:50:04 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] mkdir: add test Message-ID: <64401bbc978dd_178e7432ee6150485210@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 7d4d3c30 by Josh Meredith at 2023-04-19T16:49:51+00:00 mkdir: add test - - - - - 2 changed files: - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkDirExists.hs Changes: ===================================== libraries/base/tests/IO/all.T ===================================== @@ -152,3 +152,5 @@ test('T17510', expect_broken(17510), compile_and_run, ['']) test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) + +test('mkDirExists', normal, compile_and_run, ['']) ===================================== libraries/base/tests/IO/mkDirExists.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import System.Directory + +main :: IO () +main = do + createDirectory "foo" + createDirectory "foo" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d4d3c308c5495b9dfa7bdf0f803d6290687f3b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7d4d3c308c5495b9dfa7bdf0f803d6290687f3b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 17:14:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 19 Apr 2023 13:14:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Convert interface file loading errors into proper diagnostics Message-ID: <644021714cc82_178e743311b920489217@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 8efec989 by Sylvain Henry at 2023-04-19T13:14:17-04:00 JS: fix thread-related primops - - - - - dac93f4f by Bryan Richter at 2023-04-19T13:14:17-04:00 CI: Disable abi-test-nightly See #23269 - - - - - f2f06987 by Sylvain Henry at 2023-04-19T13:14:20-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Error.hs - compiler/ghc.cabal.in - docs/users_guide/hints.rst - ghc/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e05b0ee65fde4f220e51365648e8c497b2f2fa8e...f2f069877ea226532565298685893ae848b25c3c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e05b0ee65fde4f220e51365648e8c497b2f2fa8e...f2f069877ea226532565298685893ae848b25c3c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 19 22:39:15 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 19 Apr 2023 18:39:15 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/linear-core Message-ID: <64406d93d526_178e74389135385397df@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/linear-core at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/linear-core You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 00:04:50 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 19 Apr 2023 20:04:50 -0400 Subject: [Git][ghc/ghc][master] JS: fix thread-related primops Message-ID: <644081a2ed60b_178e743a1999a455108f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 6 changed files: - compiler/GHC/StgToJS/Prim.hs - libraries/base/tests/all.T - + libraries/base/tests/listThreads1.hs - + libraries/base/tests/listThreads1.stdout - rts/js/mem.js - rts/js/thread.js Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -925,7 +925,7 @@ genPrim prof bound ty op = case op of IsCurrentThreadBoundOp -> \[r] [] -> PrimInline $ r |= one_ NoDuplicateOp -> \[] [] -> PrimInline mempty -- don't need to do anything as long as we have eager blackholing ThreadStatusOp -> \[stat,cap,locked] [tid] -> PrimInline $ appT [stat, cap, locked] "h$threadStatus" [tid] - ListThreadsOp -> \[r] [] -> PrimInline $ r |= var "h$threads" + ListThreadsOp -> \[r] [] -> PrimInline $ appT [r] "h$listThreads" [] GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ===================================== libraries/base/tests/all.T ===================================== @@ -294,6 +294,7 @@ test('T19719', normal, compile_and_run, ['']) test('T20107', extra_run_opts('+RTS -M50M'), compile_and_run, ['-package bytestring']) test('T22816', normal, compile_and_run, ['']) test('trace', normal, compile_and_run, ['']) -test('listThreads', js_broken(22261), compile_and_run, ['']) +test('listThreads', normal, compile_and_run, ['']) +test('listThreads1', normal, compile_and_run, ['']) test('inits1tails1', normal, compile_and_run, ['']) test('CLC149', normal, compile, ['']) ===================================== libraries/base/tests/listThreads1.hs ===================================== @@ -0,0 +1,6 @@ +module Main where + +import GHC.Conc.Sync + +main :: IO () +main = listThreads >>= print ===================================== libraries/base/tests/listThreads1.stdout ===================================== @@ -0,0 +1 @@ +[ThreadId 1] ===================================== rts/js/mem.js ===================================== @@ -1455,11 +1455,3 @@ function h$pext64(src_b, src_a, mask_b, mask_a) { } RETURN_UBX_TUP2(dst_b, dst_a); } - -function h$getThreadLabel(t) { - if (t.label) { - RETURN_UBX_TUP2(1, t.label); - } else { - RETURN_UBX_TUP2(0, 0); - } -} ===================================== rts/js/thread.js ===================================== @@ -106,8 +106,8 @@ function h$Thread() { #endif } -function h$rts_getThreadId(t) { - return t.tid; +function h$rts_getThreadId(t) { // returns a CULLong + RETURN_UBX_TUP2((t.tid / Math.pow(2,32))>>>0, (t.tid & 0xFFFFFFFF)>>>0); } function h$cmp_thread(t1,t2) { @@ -121,13 +121,35 @@ function h$threadString(t) { if(t === null) { return ""; } else if(t.label) { - var str = h$decodeUtf8z(t.label[0], t.label[1]); + var str = h$decodeUtf8z(t.label, 0); return str + " (" + t.tid + ")"; } else { return (""+t.tid); } } +function h$getThreadLabel(t) { + if (t.label) { + RETURN_UBX_TUP2(1, t.label); + } else { + RETURN_UBX_TUP2(0, 0); + } +} + +function h$listThreads() { + var r = h$newArray(0,null); + + if (h$currentThread) r.push(h$currentThread); + + var threads_iter = h$threads.iter(); + while ((t = threads_iter()) !== null) r.push(t); + + var blocked_iter = h$blocked.iter(); + while ((t = blocked_iter.next()) !== null) r.push(t); + + return r; +} + function h$fork(a, inherit) { h$r1 = h$forkThread(a, inherit); return h$yield(); @@ -1134,7 +1156,7 @@ function h$main(a) { t.stack[8] = a; t.stack[9] = h$return; t.sp = 9; - t.label = [h$encodeUtf8("main"), 0]; + t.label = h$encodeUtf8("main"); h$wakeupThread(t); h$startMainLoop(); return t; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d442ac053f9ac7dbcc32318802daf686f377fe3d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d442ac053f9ac7dbcc32318802daf686f377fe3d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 00:05:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 19 Apr 2023 20:05:25 -0400 Subject: [Git][ghc/ghc][master] CI: Disable abi-test-nightly Message-ID: <644081c57d121_178e743a1999545544ca@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -484,6 +484,9 @@ abi-test-nightly: paths: - out rules: + # This job is broken. Disabling it until some kind soul can finish its + # implementation. #23269 + - when: never - if: $NIGHTLY ############################################################ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a96f90b20e9ea55bb305b20c73473ba75834f78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7a96f90b20e9ea55bb305b20c73473ba75834f78 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 00:06:07 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 19 Apr 2023 20:06:07 -0400 Subject: [Git][ghc/ghc][master] Testsuite: don't use obsolescent egrep (#22351) Message-ID: <644081efa0965_178e743a3a57205576dd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 4 changed files: - docs/users_guide/hints.rst - testsuite/tests/cabal/cabal01/Makefile - testsuite/tests/haddock/perf/Makefile - testsuite/tests/simplCore/should_compile/Makefile Changes: ===================================== docs/users_guide/hints.rst ===================================== @@ -153,7 +153,7 @@ Use ``SPECIALIZE`` pragmas: .. code-block:: sh - $ ghc --show-iface Foo.hi | egrep '^[a-z].*::.*=>' + $ ghc --show-iface Foo.hi | grep -E '^[a-z].*::.*=>' Strict functions are your dear friends: And, among other things, lazy pattern-matching is your enemy. ===================================== testsuite/tests/cabal/cabal01/Makefile ===================================== @@ -5,7 +5,7 @@ include $(TOP)/mk/test.mk # Find all the env variables starting with CI_ to unset them. # Otherwise, we might run into environment length limitations on Windows. # (See `xargs --show-limits`.) -VARS_TO_UNSET := $(shell env | grep ^CI_ | egrep -o '^[^=]+') +VARS_TO_UNSET := $(shell env | grep ^CI_ | grep -E -o '^[^=]+') unexport $(VARS_TO_UNSET) clean: ===================================== testsuite/tests/haddock/perf/Makefile ===================================== @@ -4,12 +4,12 @@ include $(TOP)/mk/test.mk # We accept a 5% increase in parser allocations due to -haddock haddock_parser_perf : - WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ - WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.05) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }" # Similarly for the renamer haddock_renamer_perf : - WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ - WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.20) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }" ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -61,7 +61,7 @@ T13367: T8832: $(RM) -f T8832.o T8832.hi - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | egrep '^[a-zA-Z0-9]+ =' + '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | grep -E '^[a-zA-Z0-9]+ =' T12603: $(RM) -f T12603.o T12603.hi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab6c1d295cd9f492838dbd481ecc2a66bbd17393 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab6c1d295cd9f492838dbd481ecc2a66bbd17393 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 06:42:45 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Thu, 20 Apr 2023 02:42:45 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Let ghc-heap depend on the current GHC / RTS version Message-ID: <6440dee5bce33_178e7440e786745743ab@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 87f9b668 by Sven Tennie at 2023-04-20T06:41:12+00:00 Let ghc-heap depend on the current GHC / RTS version It strongly depends on the structures in the RTS. Being compatible to other GHC versions introduces a lot of preprocessor special-case macros. - - - - - 12 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Settings/Default.hs - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc - libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/PeekProfInfo_ProfilingEnabled.hsc - libraries/ghc-heap/GHC/Exts/Stack.hs - libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/ghc-heap.cabal.in - libraries/ghci/ghci.cabal.in Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -87,7 +87,8 @@ Library exceptions == 0.10.*, stm, ghc-boot == @ProjectVersionMunged@, - ghc-heap == @ProjectVersionMunged@, + -- in-tree used for Stage >= 1, pre-built for Stage0 + ghc-heap, ghci == @ProjectVersionMunged@ if os(windows) ===================================== hadrian/src/Packages.hs ===================================== @@ -53,13 +53,20 @@ isGhcPackage = (`elem` ghcPackages) array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, - ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, + ghcCompact, ghcConfig, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, parsec, pretty, primitive, process, rts, runGhc, stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace :: Package + +-- | `Package` of the @ghc-heap@ library +-- +-- N.B.: As it strongly depends on structures of the RTS, needs to be built with +-- the GHC version to be built (>= @Stage1@) +ghcHeap:: Package + array = lib "array" base = lib "base" binary = lib "binary" ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -77,7 +77,6 @@ stage0Packages = do , cabalSyntax , cabal , compiler - , containers , directory , process , exceptions @@ -86,7 +85,6 @@ stage0Packages = do , runGhc , ghcBoot , ghcBootTh - , ghcHeap , ghci , ghcPkg , haddock @@ -132,6 +130,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcHeap , ghcBignum , ghcCompact , ghcPkg ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -88,18 +88,10 @@ class HasHeapRep (a :: TYPE rep) where -> IO Closure -- ^ Heap representation of the closure. -#if __GLASGOW_HASKELL__ >= 901 instance HasHeapRep (a :: TYPE ('BoxedRep 'Lifted)) where -#else -instance HasHeapRep (a :: TYPE 'LiftedRep) where -#endif getClosureData = getClosureDataFromHeapObject -#if __GLASGOW_HASKELL__ >= 901 instance HasHeapRep (a :: TYPE ('BoxedRep 'Unlifted)) where -#else -instance HasHeapRep (a :: TYPE 'UnliftedRep) where -#endif getClosureData x = getClosureDataFromHeapObject (unsafeCoerce# x) instance Int# ~ a => HasHeapRep (a :: TYPE 'IntRep) where @@ -369,9 +361,7 @@ getClosureDataFromHeapRepPrim getConDesc decodeCCS itbl heapRep pts = do { info = itbl , stack_size = FFIClosures.stack_size fields , stack_dirty = FFIClosures.stack_dirty fields -#if __GLASGOW_HASKELL__ >= 811 , stack_marking = FFIClosures.stack_marking fields -#endif }) | otherwise -> fail $ "Expected 0 ptr argument to STACK, found " ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -302,9 +302,7 @@ data GenClosure b { info :: !StgInfoTable , stack_size :: !Word32 -- ^ stack size in *words* , stack_dirty :: !Word8 -- ^ non-zero => dirty -#if __GLASGOW_HASKELL__ >= 811 , stack_marking :: !Word8 -#endif } ------------------------------------------------------------ ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc ===================================== @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module GHC.Exts.Heap.FFIClosures_ProfilingEnabled where @@ -99,9 +98,7 @@ unset bitMask w = w `xor` bitMask data StackFields = StackFields { stack_size :: Word32, stack_dirty :: Word8, -#if __GLASGOW_HASKELL__ >= 811 stack_marking :: Word8, -#endif stack_sp :: Addr## } @@ -110,9 +107,7 @@ peekStackFields :: Ptr a -> IO StackFields peekStackFields ptr = do stack_size' <- (#peek struct StgStack_, stack_size) ptr ::IO Word32 dirty' <- (#peek struct StgStack_, dirty) ptr -#if __GLASGOW_HASKELL__ >= 811 marking' <- (#peek struct StgStack_, marking) ptr -#endif Ptr sp' <- (#peek struct StgStack_, sp) ptr -- TODO decode the stack. @@ -120,8 +115,6 @@ peekStackFields ptr = do return StackFields { stack_size = stack_size', stack_dirty = dirty', -#if __GLASGOW_HASKELL__ >= 811 stack_marking = marking', -#endif stack_sp = sp' } ===================================== libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/PeekProfInfo_ProfilingEnabled.hsc ===================================== @@ -6,10 +6,6 @@ module GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled( , peekTopCCS ) where -#if __GLASGOW_HASKELL__ >= 811 - --- See [hsc and CPP workaround] - #define PROFILING #include "Rts.h" @@ -158,16 +154,3 @@ peekIndexTable loopBreakers costCenterCacheRef ptr = do -- | casts a @Ptr@ to an @Int@ ptrToInt :: Ptr a -> Int ptrToInt (Ptr a##) = I## (addr2Int## a##) - -#else -import Prelude -import Foreign - -import GHC.Exts.Heap.ProfInfo.Types - -peekStgTSOProfInfo :: (Ptr b -> IO (Maybe CostCentreStack)) -> Ptr a -> IO (Maybe StgTSOProfInfo) -peekStgTSOProfInfo _ _ = return Nothing - -peekTopCCS :: Ptr a -> IO (Maybe CostCentreStack) -peekTopCCS _ = return Nothing -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack.hs ===================================== @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -#if MIN_TOOL_VERSION_ghc(9,7,0) {-# LANGUAGE RecordWildCards #-} module GHC.Exts.Stack @@ -28,7 +26,3 @@ stackFrameSize (RetBCO {..}) = sizeStgClosure + 1 + length bcoArgs -- The one additional word is a pointer to the next stack chunk stackFrameSize (UnderflowFrame {}) = sizeStgClosure + 1 stackFrameSize _ = error "Unexpected stack frame type" - -#else -module GHC.Exts.Stack where -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc ===================================== @@ -1,10 +1,7 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module GHC.Exts.Stack.Constants where -#if MIN_TOOL_VERSION_ghc(9,7,0) - import Prelude #include "Rts.h" @@ -126,5 +123,3 @@ bytesToWords b = bytesInWord :: Int bytesInWord = (#const SIZEOF_VOID_P) - -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -#if MIN_TOOL_VERSION_ghc(9,7,0) {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleInstances #-} @@ -458,7 +456,3 @@ decodeStack (StackSnapshot stack#) = do go :: Maybe StackFrameLocation -> [StackFrameLocation] go Nothing = [] go (Just r) = r : go (advanceStackFrameLocation r) - -#else -module GHC.Exts.Stack.Decode where -#endif ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -12,7 +12,7 @@ description: and retrieving information about those data structures. build-type: Simple -tested-with: GHC==7.11 +tested-with: GHC==@ProjectVersionMunged@ source-repository head type: git ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -80,7 +80,8 @@ library deepseq == 1.4.*, filepath == 1.4.*, ghc-boot == @ProjectVersionMunged@, - ghc-heap == @ProjectVersionMunged@, + -- in-tree used for Stage >= 1, pre-built for Stage0 + ghc-heap, template-haskell == 2.20.*, transformers >= 0.5 && < 0.7 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f9b66867832399e4fd18459d617f2fc7c493e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f9b66867832399e4fd18459d617f2fc7c493e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 07:23:38 2023 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Thu, 20 Apr 2023 03:23:38 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/doc-typo Message-ID: <6440e87a1e638_178e74417379b857997d@gitlab.mail> Bryan R pushed new branch wip/doc-typo at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/doc-typo You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 07:35:14 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 20 Apr 2023 03:35:14 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] Apply 1 suggestion(s) to 1 file(s) Message-ID: <6440eb32250c1_178e74417e78e0592353@gitlab.mail> Sylvain Henry pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 0bc332e8 by Sylvain Henry at 2023-04-20T07:35:11+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - libraries/base/tests/IO/all.T Changes: ===================================== libraries/base/tests/IO/all.T ===================================== @@ -153,4 +153,4 @@ test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) -test('mkDirExists', normal, compile_and_run, ['']) +test('mkDirExists', exit_code(1), compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bc332e84ebb97effc0e35d48c604704d51ff32f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bc332e84ebb97effc0e35d48c604704d51ff32f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 08:38:05 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 20 Apr 2023 04:38:05 -0400 Subject: [Git][ghc/ghc][wip/T23071] 147 commits: Fix BCO creation setting caps when -j > -N Message-ID: <6440f9eda32b0_178e7442a45ed86062fd@gitlab.mail> Sylvain Henry pushed to branch wip/T23071 at Glasgow Haskell Compiler / GHC Commits: c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 063201e9 by Ben Gamari at 2023-04-20T08:38:00+00:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - e7d1306f by Ben Gamari at 2023-04-20T08:38:00+00:00 testsuite: Add test for #23071 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b6fb4408d14d948af89018d70de26fb7686e02d...e7d1306f4513da89d71ed8059403f05171657164 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b6fb4408d14d948af89018d70de26fb7686e02d...e7d1306f4513da89d71ed8059403f05171657164 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 08:48:05 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 04:48:05 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] 2 commits: Replace the implementation of CodeBuffers with unboxed types Message-ID: <6440fc45c1616_178e744311ff74608040@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 6eccf82c by Josh Meredith at 2023-04-20T08:44:11+00:00 Replace the implementation of CodeBuffers with unboxed types - - - - - 8414be5a by Josh Meredith at 2023-04-20T08:44:58+00:00 Use unboxed codebuffers in base - - - - - 8 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/Types.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,7 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +20,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +145,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let (# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +169,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let (# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let (# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/Types.hs ===================================== @@ -1,6 +1,9 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude, ExistentialQuantification #-} {-# OPTIONS_GHC -funbox-strict-fields #-} +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE PatternSynonyms, ViewPatterns #-} +{-# LANGUAGE UnboxedTuples, MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -17,11 +20,13 @@ ----------------------------------------------------------------------------- module GHC.IO.Encoding.Types ( - BufferCodec(..), + BufferCodec(.., BufferCodec, encode, recover, close, getState, setState), TextEncoding(..), TextEncoder, TextDecoder, CodeBuffer, EncodeBuffer, DecodeBuffer, - CodingProgress(..) + CodingProgress(..), + DecodeBuffer#, EncodeBuffer#, + DecodingBuffer#, EncodingBuffer# ) where import GHC.Base @@ -33,8 +38,8 @@ import GHC.IO.Buffer -- ----------------------------------------------------------------------------- -- Text encoders/decoders -data BufferCodec from to state = BufferCodec { - encode :: CodeBuffer from to, +data BufferCodec from to state = BufferCodec# { + encode# :: CodeBuffer# from to, -- ^ The @encode@ function translates elements of the buffer @from@ -- to the buffer @to at . It should translate as many elements as possible -- given the sizes of the buffers, including translating zero elements @@ -50,7 +55,7 @@ data BufferCodec from to state = BufferCodec { -- library in order to report translation errors at the point they -- actually occur, rather than when the buffer is translated. - recover :: Buffer from -> Buffer to -> IO (Buffer from, Buffer to), + recover# :: Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #), -- ^ The @recover@ function is used to continue decoding -- in the presence of invalid or unrepresentable sequences. This includes -- both those detected by @encode@ returning @InvalidSequence@ and those @@ -69,12 +74,12 @@ data BufferCodec from to state = BufferCodec { -- -- @since 4.4.0.0 - close :: IO (), + close# :: IO (), -- ^ Resources associated with the encoding may now be released. -- The @encode@ function may not be called again after calling -- @close at . - getState :: IO state, + getState# :: IO state, -- ^ Return the current state of the codec. -- -- Many codecs are not stateful, and in these case the state can be @@ -87,14 +92,22 @@ data BufferCodec from to state = BufferCodec { -- beginning), and if not, whether to use the big or little-endian -- encoding. - setState :: state -> IO () + setState# :: state -> IO () -- restore the state of the codec using the state from a previous -- call to 'getState'. } -type CodeBuffer from to = Buffer from -> Buffer to -> IO (CodingProgress, Buffer from, Buffer to) -type DecodeBuffer = CodeBuffer Word8 Char -type EncodeBuffer = CodeBuffer Char Word8 +type CodeBuffer from to = Buffer from -> Buffer to -> IO (CodingProgress, Buffer from, Buffer to) +type DecodeBuffer = CodeBuffer Word8 Char +type EncodeBuffer = CodeBuffer Char Word8 + +type CodeBuffer# from to = Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, CodingProgress, Buffer from, Buffer to #) +type DecodeBuffer# = CodeBuffer# Word8 Char +type EncodeBuffer# = CodeBuffer# Char Word8 + +type CodingBuffer# from to = State# RealWorld -> (# State# RealWorld, CodingProgress, Buffer from, Buffer to #) +type DecodingBuffer# = CodingBuffer# Word8 Char +type EncodingBuffer# = CodingBuffer# Char Word8 type TextDecoder state = BufferCodec Word8 CharBufElem state type TextEncoder state = BufferCodec CharBufElem Word8 state @@ -132,3 +145,29 @@ data CodingProgress = InputUnderflow -- ^ Stopped because the input contains in , Show -- ^ @since 4.4.0.0 ) +pattern BufferCodec :: CodeBuffer from to + -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) + -> IO () + -> IO state + -> (state -> IO ()) + -> BufferCodec from to state +pattern BufferCodec{encode, recover, close, getState, setState} <- + BufferCodec# (getEncode -> encode) (getRecover -> recover) close getState setState + where + BufferCodec e r c g s = BufferCodec# (mkEncode e) (mkRecover r) c g s + +getEncode :: CodeBuffer# from to -> CodeBuffer from to +getEncode e i o = IO $ \st -> + let !(# st', prog, i', o' #) = e i o st in (# st', (prog, i', o') #) + +getRecover :: (Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #)) + -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) +getRecover r i o = IO $ \st -> + let !(# st', i', o' #) = r i o st in (# st', (i', o') #) + +mkEncode :: CodeBuffer from to -> CodeBuffer# from to +mkEncode e i o st = let !(# st', (prog, i', o') #) = unIO (e i o) st in (# st', prog, i', o' #) + +mkRecover :: (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) + -> (Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #)) +mkRecover r i o st = let !(# st', (i', o') #) = unIO (r i o) st in (# st', i', o' #) ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let (# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let (# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let (# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let (# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f6a849f4de75caf7619096b32a513c3672d4313...8414be5aca1b92498c0027678cea7ecfcdfd1c5d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f6a849f4de75caf7619096b32a513c3672d4313...8414be5aca1b92498c0027678cea7ecfcdfd1c5d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 09:19:49 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 05:19:49 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] Apply 1 suggestion(s) to 1 file(s) Message-ID: <644103b58e21c_178e7443a7ef346287ee@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: ee9e4c4a by Sylvain Henry at 2023-04-20T09:19:47+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - rts/js/mem.js Changes: ===================================== rts/js/mem.js ===================================== @@ -1465,6 +1465,7 @@ function h$getThreadLabel(t) { } function h$checkOverlapByteArray(a1, o1, a2, o2, n) { + if (n == 0) return true; if (a1 == a2) { if (o1 < o2) { return o1 + n - 1 < o2; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee9e4c4afaca3322c7c789728dbfdffd3098d55f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee9e4c4afaca3322c7c789728dbfdffd3098d55f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 09:21:38 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 05:21:38 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] JS: fix bounds checking (Issue 23123) Message-ID: <64410422b5c7d_178e7443b08c84632261@gitlab.mail> Josh Meredith pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: 571b9295 by Josh Meredith at 2023-04-20T09:21:12+00:00 JS: fix bounds checking (Issue 23123) * For ByteArray-based bounds-checking, the JavaScript backend must use the `len` field, instead of the inbuild JavaScript `length` field. * Range-based operations must also check both the start and end of the range for bounds * All indicies are valid for ranges of size zero, since they are essentially no-ops * For cases of ByteArray accesses (e.g. read as Int), the end index is (i * sizeof(type) + sizeof(type) - 1), while the previous implementation uses (i + sizeof(type) - 1). In the Int32 example, this is (i * 4 + 3) * IndexByteArrayOp_Word8As* primitives use byte array indicies (unlike the previous point), but now check both start and end indicies * Byte array copies now check if the arrays are the same by identity and then if the ranges overlap. - - - - - 4 changed files: - compiler/GHC/StgToJS/Prim.hs - rts/js/mem.js - testsuite/tests/codeGen/should_fail/all.T - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -605,12 +605,12 @@ genPrim prof bound ty op = case op of SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i IndexByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a i $ jVar \t -> mconcat + PrimInline . boundsCheckedLen bound a i $ jVar \t -> mconcat [ t |= a .^ "arr" , ifBlockS (t .&&. t .! (i .<<. two_)) [ r1 |= t .! (i .<<. two_) .! zero_ @@ -621,31 +621,31 @@ genPrim prof bound ty op = case op of ] ] - IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_f32 a i - IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_f64 a i + IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_f32 a i + IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_f64 a i IndexByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a (Add i 3) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i - IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_i16 a i - IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ mconcat + IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i + IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_i16 a i + IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_u16 a i - IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i - IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ mconcat + IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_u16 a i + IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i + IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i ReadByteArrayOp_Addr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ @@ -655,66 +655,67 @@ genPrim prof bound ty op = case op of ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_f32 a i - ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_f64 a i + ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_f32 a i + ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_f64 a i ReadByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsChecked bound a (Add i 3) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_i32 a i ] - ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_i8 a i - ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_i16 a i - ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i + ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i + ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_i16 a i + ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ h |= read_i32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_u8 a i - ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_u16 a i - ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_u32 a i + ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i + ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_u16 a i + ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ h |= read_u32 a (Add (i .<<. one_) one_) , l |= read_u32 a (i .<<. one_) ] - WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e - WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e - WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e - WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_u32 a i e + WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e + WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e + WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e + WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_u32 a i e WriteByteArrayOp_Addr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_f32 a i e - WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 7) $ write_f64 a i e - WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e2 + WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_f32 a i e + WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ write_f64 a i e + WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e2 - WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_i8 a i e - WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_i16 a i e - WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i e + WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_i8 a i e + WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_i16 a i e + WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e WriteByteArrayOp_Int64 -> \[] [a,i,e1,e2] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ write_i32 a (Add (i .<<. one_) one_) e1 , write_u32 a (i .<<. one_) e2 ] - WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_u8 a i e - WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_u16 a i e - WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_u32 a i e + WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e + WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_u16 a i e + WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_u32 a i e WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat [ write_u32 a (Add (i .<<. one_) one_) h , write_u32 a (i .<<. one_) l ] CompareByteArraysOp -> \[r] [a1,o1,a2,o2,n] -> - PrimInline . boundsChecked bound a1 (Add o1 (Sub n 1)) - . boundsChecked bound a2 (Add o2 (Sub n 1)) + PrimInline . boundsCheckedRangeLen bound a1 o1 n + . boundsCheckedRangeLen bound a2 o2 n $ r |= app "h$compareByteArrays" [a1,o1,a2,o2,n] CopyByteArrayOp -> \[] [a1,o1,a2,o2,n] -> - PrimInline . boundsChecked bound a1 (Add o1 (Sub n 1)) - . boundsChecked bound a2 (Add o2 (Sub n 1)) + PrimInline . boundsCheckedRangeLen bound a1 o1 n + . boundsCheckedRangeLen bound a2 o2 n + . checkOverlapByteArray bound a1 o1 a2 o2 n $ appS "h$copyMutableByteArray" [a1,o1,a2,o2,n] CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs CopyMutableByteArrayNonOverlappingOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs @@ -725,20 +726,20 @@ genPrim prof bound ty op = case op of CopyAddrToAddrNonOverlappingOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs SetByteArrayOp -> \[] [a,o,n,v] -> - PrimInline . boundsChecked bound a (Add o (Sub n 1)) $ loopBlockS zero_ (.<. n) \i -> + PrimInline . boundsCheckedRangeLen bound a o n $ loopBlockS zero_ (.<. n) \i -> [ write_u8 a (Add o i) v , postIncrS i ] SetAddrRangeOp -> \[] xs@[_a,_o,_n,_v] -> genPrim prof bound ty SetByteArrayOp [] xs - AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_i32 a i - AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ write_i32 a i v - FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray Add r a i v - FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray Sub r a i v - FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BAnd r a i v - FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BOr r a i v - FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v - FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsChecked bound a (Add i 3) $ fetchOpByteArray BXor r a i v + AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i + AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i v + FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray Add r a i v + FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray Sub r a i v + FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BAnd r a i v + FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BOr r a i v + FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v + FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BXor r a i v ------------------------------- Addr# ------------------------------------------ @@ -1031,115 +1032,115 @@ genPrim prof bound ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , boundsChecked bound (a .^ "arr") x $ + , boundsCheckedLen bound (a .^ "arr") x $ ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_boff_f64 a i + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a i $ r |= read_boff_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> PrimInline $ jVar \x -> mconcat [ x |= i .<<. two_ - , boundsChecked bound (a .^ "arr") x $ + , boundsCheckedLen bound (a .^ "arr") x $ ifS (a .^ "arr" .&&. a .^ "arr" .! x) (mconcat [ r1 |= a .^ "arr" .! x .! zero_ , r2 |= a .^ "arr" .! x .! one_ ]) (mconcat [r1 |= null_, r2 |= one_]) ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 7) $ r |= read_boff_f64 a i + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> PrimInline $ mconcat [ r1 |= var "h$stablePtrBuf" , r2 |= read_boff_i32 a i ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ mconcat [ h |= read_boff_i32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 1) $ r |= read_boff_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsChecked bound a (Add i 7) $ mconcat + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ h |= read_boff_u32 a (Add i (Int 4)) , l |= read_boff_u32 a i ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsChecked bound a (Add i 3) $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a i $ write_boff_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_boff_i8 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> PrimInline $ mconcat [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , boundsChecked bound (a .^ "arr") (i .<<. two_) $ + , boundsCheckedLen bound (a .^ "arr") (i .<<. two_) $ a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) ] - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 7) $ write_boff_f64 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_boff_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e2 + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i -- then write the higher 4 bytes to i+4 - PrimInline . boundsChecked bound a i + PrimInline . boundsCheckedLen bound a i $ mconcat [ write_boff_i32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 1) $ write_boff_u16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline . boundsChecked bound a (Add i 7) + PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat [ write_boff_u32 a (Add i (Int 4)) h , write_boff_u32 a i l ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsChecked bound a (Add i 3) $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e - CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a i $ casOp read_i8 write_i8 r a i old new - CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 1) $ casOp read_i16 write_i16 r a i old new - CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsChecked bound a (Add i 3) $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ casOp read_i32 write_i32 r a i old new + CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a i $ casOp read_i8 write_i8 r a i old new + CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ casOp read_i16 write_i16 r a i old new + CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsChecked bound a (Add (i .<<. one_) one_) $ + CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsCheckedLen bound a (Add (i .<<. one_) one_) $ jVar \t_h t_l -> mconcat [ t_h |= read_i32 a (Add (i .<<. one_) one_) , t_l |= read_u32 a (i .<<. one_) , r_h |= t_h @@ -1466,17 +1467,76 @@ newByteArray :: JExpr -> JExpr -> JStat newByteArray tgt len = tgt |= app "h$newByteArray" [len] -boundsChecked :: Bool -- ^ Should we do bounds checking? - -> JExpr -- ^ Array - -> JExpr -- ^ Index - -> JStat -- ^ Result - -> JStat -boundsChecked False _ _ r = r -boundsChecked True xs i r = - ifS ((i .<. xs .^ "length") .&&. (i .>=. zero_)) +boundsChecked' + :: JExpr -- ^ Max index expression + -> Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsChecked' _ False _ r = r +boundsChecked' max_index True i r = + ifS ((i .>=. zero_) .&&. (i .<. max_index)) r $ + returnS (app "h$exitProcess" [Int 134]) + +-- | Bounds checking using ".length" property (Arrays) +boundsChecked + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsChecked do_check arr = boundsChecked' (arr .^ "length") do_check + +-- | Bounds checking using ".len" property (ByteArrays) +boundsCheckedLen + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +boundsCheckedLen do_check arr = boundsChecked' (arr .^ "len") do_check + +-- | Bounds checking on a range and using ".len" property (ByteArrays) +-- +-- Empty ranges trivially pass the check +boundsCheckedRangeLen + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JExpr -- ^ Range size + -> JStat -- ^ Result + -> JStat +boundsCheckedRangeLen False _ _ _ r = r +boundsCheckedRangeLen True xs i n r = + ifS (n .<. zero_) (returnS $ app "h$exitProcess" [Int 134]) $ + ifS (n .===. zero_) -- We can always fill zero elements, even if it seems out-of-bounds + r + (boundsCheckedLen True xs (Add i (Sub n 1)) (boundsCheckedLen True xs i r)) + +checkOverlapByteArray + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ First array + -> JExpr -- ^ First offset + -> JExpr -- ^ Second array + -> JExpr -- ^ Second offset + -> JExpr -- ^ Range size + -> JStat -- ^ Result + -> JStat +checkOverlapByteArray False _ _ _ _ _ r = r +checkOverlapByteArray True a1 o1 a2 o2 n r = + ifS (app "h$checkOverlapByteArray" [a1, o1, a2, o2, n]) r (returnS $ app "h$exitProcess" [Int 134]) +byteIndex16 :: JExpr -> JExpr +byteIndex16 i = Add 1 (Mul 2 i) + +byteIndex32 :: JExpr -> JExpr +byteIndex32 i = Add 3 (Mul 4 i) + +byteIndex64 :: JExpr -> JExpr +byteIndex64 i = Add 7 (Mul 8 i) + -- e|0 (32 bit signed integer truncation) required because of JS numbers. e|0 -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. -- So (x|0) * (y|0) can still return values outside of the Int32 range. You have ===================================== rts/js/mem.js ===================================== @@ -1463,3 +1463,15 @@ function h$getThreadLabel(t) { RETURN_UBX_TUP2(0, 0); } } + +function h$checkOverlapByteArray(a1, o1, a2, o2, n) { + if (n == 0) return true; + if (a1 == a2) { + if (o1 < o2) { + return o1 + n - 1 < o2; + } else { + return o2 + n - 1 < o1; + } + } + return true; +} ===================================== testsuite/tests/codeGen/should_fail/all.T ===================================== @@ -24,4 +24,3 @@ check_bounds_test('CheckBoundsCompareByteArray2') # Check first byte, 1st array check_bounds_test('CheckBoundsCompareByteArray3') # Check negative length check_bounds_test('CheckOverlapCopyByteArray') check_bounds_test('CheckOverlapCopyAddrToByteArray') - ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -229,4 +229,4 @@ test('T20640b', normal, compile_and_run, ['']) test('T22296',[only_ways(llvm_ways) ,unless(arch('x86_64'), skip)],compile_and_run,['']) test('T22798', normal, compile_and_run, ['-fregs-graph']) -test('CheckBoundsOK', js_broken(23123), compile_and_run, ['-fcheck-prim-bounds']) +test('CheckBoundsOK', js_broken(21142), compile_and_run, ['-fcheck-prim-bounds']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/571b929582095f208a8cd41280edb6c101023ed0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/571b929582095f208a8cd41280edb6c101023ed0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 09:57:12 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 05:57:12 -0400 Subject: [Git][ghc/ghc][wip/js-base_access] 2 commits: Change RunTest.inTreeCompilerArgs.ghcStage to account for cross-compilers Message-ID: <64410c787c731_178e74443f0e8c634772@gitlab.mail> Josh Meredith pushed to branch wip/js-base_access at Glasgow Haskell Compiler / GHC Commits: 2f3a74d2 by Josh Meredith at 2023-04-20T09:54:30+00:00 Change RunTest.inTreeCompilerArgs.ghcStage to account for cross-compilers - - - - - 6286e89b by Josh Meredith at 2023-04-20T09:57:00+00:00 Set the test RepPolyWrappedVar2 to js_broken(23280) - - - - - 2 changed files: - hadrian/src/Settings/Builders/RunTest.hs - testsuite/tests/rep-poly/all.T Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -105,7 +105,11 @@ inTreeCompilerArgs stg = do tables_next_to_code <- flag TablesNextToCode targetWithSMP <- targetSupportsSMP - let ghcStage = succStage stg + cross <- flag CrossCompiling + + let ghcStage + | cross, Stage1 <- stg = Stage1 + | otherwise = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', normal, compile, ['']) +test('RepPolyWrappedVar2', js_broken(23280), compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/737b258c858f39227b5a581bac84072602b4e0db...6286e89bcf73debe22dc54be13b348d099d0f7cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/737b258c858f39227b5a581bac84072602b4e0db...6286e89bcf73debe22dc54be13b348d099d0f7cc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 10:11:07 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 06:11:07 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: JS: fix thread-related primops Message-ID: <64410fbb6d649_178e74446cdfec64185f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - b2ee4388 by Matthew Pickering at 2023-04-20T06:10:54-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - d23b736f by tocic at 2023-04-20T06:10:55-04:00 Fix doc typo in GHC.Read.readList - - - - - 14 changed files: - .gitlab-ci.yml - compiler/GHC/StgToJS/Prim.hs - docs/users_guide/hints.rst - hadrian/src/Builder.hs - hadrian/src/Settings/Builders/Haddock.hs - libraries/base/GHC/Read.hs - libraries/base/tests/all.T - + libraries/base/tests/listThreads1.hs - + libraries/base/tests/listThreads1.stdout - rts/js/mem.js - rts/js/thread.js - testsuite/tests/cabal/cabal01/Makefile - testsuite/tests/haddock/perf/Makefile - testsuite/tests/simplCore/should_compile/Makefile Changes: ===================================== .gitlab-ci.yml ===================================== @@ -484,6 +484,9 @@ abi-test-nightly: paths: - out rules: + # This job is broken. Disabling it until some kind soul can finish its + # implementation. #23269 + - when: never - if: $NIGHTLY ############################################################ ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -925,7 +925,7 @@ genPrim prof bound ty op = case op of IsCurrentThreadBoundOp -> \[r] [] -> PrimInline $ r |= one_ NoDuplicateOp -> \[] [] -> PrimInline mempty -- don't need to do anything as long as we have eager blackholing ThreadStatusOp -> \[stat,cap,locked] [tid] -> PrimInline $ appT [stat, cap, locked] "h$threadStatus" [tid] - ListThreadsOp -> \[r] [] -> PrimInline $ r |= var "h$threads" + ListThreadsOp -> \[r] [] -> PrimInline $ appT [r] "h$listThreads" [] GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ===================================== docs/users_guide/hints.rst ===================================== @@ -153,7 +153,7 @@ Use ``SPECIALIZE`` pragmas: .. code-block:: sh - $ ghc --show-iface Foo.hi | egrep '^[a-z].*::.*=>' + $ ghc --show-iface Foo.hi | grep -E '^[a-z].*::.*=>' Strict functions are your dear friends: And, among other things, lazy pattern-matching is your enemy. ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock BuildPackage -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" ===================================== libraries/base/GHC/Read.hs ===================================== @@ -205,8 +205,8 @@ class Read a where -- | The method 'readList' is provided to allow the programmer to -- give a specialised way of parsing lists of values. -- For example, this is used by the predefined 'Read' instance of - -- the 'Char' type, where values of type 'String' should be are - -- expected to use double quotes, rather than square brackets. + -- the 'Char' type, where values of type 'String' are expected to + -- use double quotes, rather than square brackets. readList :: ReadS [a] -- | Proposed replacement for 'readsPrec' using new-style parsers (GHC only). ===================================== libraries/base/tests/all.T ===================================== @@ -294,6 +294,7 @@ test('T19719', normal, compile_and_run, ['']) test('T20107', extra_run_opts('+RTS -M50M'), compile_and_run, ['-package bytestring']) test('T22816', normal, compile_and_run, ['']) test('trace', normal, compile_and_run, ['']) -test('listThreads', js_broken(22261), compile_and_run, ['']) +test('listThreads', normal, compile_and_run, ['']) +test('listThreads1', normal, compile_and_run, ['']) test('inits1tails1', normal, compile_and_run, ['']) test('CLC149', normal, compile, ['']) ===================================== libraries/base/tests/listThreads1.hs ===================================== @@ -0,0 +1,6 @@ +module Main where + +import GHC.Conc.Sync + +main :: IO () +main = listThreads >>= print ===================================== libraries/base/tests/listThreads1.stdout ===================================== @@ -0,0 +1 @@ +[ThreadId 1] ===================================== rts/js/mem.js ===================================== @@ -1455,11 +1455,3 @@ function h$pext64(src_b, src_a, mask_b, mask_a) { } RETURN_UBX_TUP2(dst_b, dst_a); } - -function h$getThreadLabel(t) { - if (t.label) { - RETURN_UBX_TUP2(1, t.label); - } else { - RETURN_UBX_TUP2(0, 0); - } -} ===================================== rts/js/thread.js ===================================== @@ -106,8 +106,8 @@ function h$Thread() { #endif } -function h$rts_getThreadId(t) { - return t.tid; +function h$rts_getThreadId(t) { // returns a CULLong + RETURN_UBX_TUP2((t.tid / Math.pow(2,32))>>>0, (t.tid & 0xFFFFFFFF)>>>0); } function h$cmp_thread(t1,t2) { @@ -121,13 +121,35 @@ function h$threadString(t) { if(t === null) { return ""; } else if(t.label) { - var str = h$decodeUtf8z(t.label[0], t.label[1]); + var str = h$decodeUtf8z(t.label, 0); return str + " (" + t.tid + ")"; } else { return (""+t.tid); } } +function h$getThreadLabel(t) { + if (t.label) { + RETURN_UBX_TUP2(1, t.label); + } else { + RETURN_UBX_TUP2(0, 0); + } +} + +function h$listThreads() { + var r = h$newArray(0,null); + + if (h$currentThread) r.push(h$currentThread); + + var threads_iter = h$threads.iter(); + while ((t = threads_iter()) !== null) r.push(t); + + var blocked_iter = h$blocked.iter(); + while ((t = blocked_iter.next()) !== null) r.push(t); + + return r; +} + function h$fork(a, inherit) { h$r1 = h$forkThread(a, inherit); return h$yield(); @@ -1134,7 +1156,7 @@ function h$main(a) { t.stack[8] = a; t.stack[9] = h$return; t.sp = 9; - t.label = [h$encodeUtf8("main"), 0]; + t.label = h$encodeUtf8("main"); h$wakeupThread(t); h$startMainLoop(); return t; ===================================== testsuite/tests/cabal/cabal01/Makefile ===================================== @@ -5,7 +5,7 @@ include $(TOP)/mk/test.mk # Find all the env variables starting with CI_ to unset them. # Otherwise, we might run into environment length limitations on Windows. # (See `xargs --show-limits`.) -VARS_TO_UNSET := $(shell env | grep ^CI_ | egrep -o '^[^=]+') +VARS_TO_UNSET := $(shell env | grep ^CI_ | grep -E -o '^[^=]+') unexport $(VARS_TO_UNSET) clean: ===================================== testsuite/tests/haddock/perf/Makefile ===================================== @@ -4,12 +4,12 @@ include $(TOP)/mk/test.mk # We accept a 5% increase in parser allocations due to -haddock haddock_parser_perf : - WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ - WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.05) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }" # Similarly for the renamer haddock_renamer_perf : - WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ - WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ + WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7- ) ; \ awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.20) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }" ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -61,7 +61,7 @@ T13367: T8832: $(RM) -f T8832.o T8832.hi - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | egrep '^[a-zA-Z0-9]+ =' + '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | grep -E '^[a-zA-Z0-9]+ =' T12603: $(RM) -f T12603.o T12603.hi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2f069877ea226532565298685893ae848b25c3c...d23b736fb66c62fe1a6da08cf03431880e90980b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f2f069877ea226532565298685893ae848b25c3c...d23b736fb66c62fe1a6da08cf03431880e90980b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 10:19:17 2023 From: gitlab at gitlab.haskell.org (tocic (@tocic)) Date: Thu, 20 Apr 2023 06:19:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fix/base_ghc_typos Message-ID: <644111a55d9b4_178e7444e380c06473f8@gitlab.mail> tocic pushed new branch wip/fix/base_ghc_typos at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix/base_ghc_typos You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 11:17:05 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 07:17:05 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] 7 commits: Convert interface file loading errors into proper diagnostics Message-ID: <64411f319689c_178e7445b99048654722@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - b0b0cfca by Josh Meredith at 2023-04-20T11:17:03+00:00 Replace the implementation of CodeBuffers with unboxed types - - - - - b037bbb0 by Josh Meredith at 2023-04-20T11:17:03+00:00 Use unboxed codebuffers in base - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToJS/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Utils/Error.hs - compiler/ghc.cabal.in - docs/users_guide/hints.rst - ghc/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8414be5aca1b92498c0027678cea7ecfcdfd1c5d...b037bbb093c5d51520acdd332d5947811e36417e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8414be5aca1b92498c0027678cea7ecfcdfd1c5d...b037bbb093c5d51520acdd332d5947811e36417e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 11:27:42 2023 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Thu, 20 Apr 2023 07:27:42 -0400 Subject: [Git][ghc/ghc][wip/jsem] jsem: apply suggestions Message-ID: <644121aed9cc9_178e744617f76466359b@gitlab.mail> sheaf pushed to branch wip/jsem at Glasgow Haskell Compiler / GHC Commits: 5f5791f4 by sheaf at 2023-04-20T11:27:39+00:00 jsem: apply suggestions - - - - - 4 changed files: - compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/9.8.1-notes.rst - docs/users_guide/using.rst Changes: ===================================== compiler/GHC/Driver/MakeSem.hs ===================================== @@ -493,10 +493,8 @@ runJSemAbstractSem sem action = MC.mask \ unmask -> do MC.throwM e1 Right x -> cleanup $> x -{- -Note [Architecture of the Job Server] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +{- Note [Architecture of the Job Server] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In `-jsem` mode, the amount of parallelism that GHC can use is controlled by a system semaphore. We take resources from the semaphore when we need them, and give them back if we don't have enough to do. @@ -538,7 +536,6 @@ We only need to kill `acquireJob`, because `releaseJob` never blocks. Note [Eventlog Messages for jsem] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - It can be tricky to verify that the work is shared adequately across different processes. To help debug this, we output the values of `JobResource` to the eventlog whenever the global state changes. There are some scripts which can be used ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -787,9 +787,12 @@ class ContainsDynFlags t where -- | The type for the -jN argument, specifying that -j on its own represents -- using the number of machine processors. data ParMakeCount - = ParMakeThisMany Int -- -j - | ParMakeSemaphore FilePath --jsem - | ParMakeNumProcessors -- -j + -- | Use this many processors (@-j@ flag). + = ParMakeThisMany Int + -- | Use parallelism with as many processors as possible (@-j@ flag without an argument). + | ParMakeNumProcessors + -- | Use the specific semaphore @@ to control parallelism (@-jsem @ flag). + | ParMakeSemaphore FilePath ----------------------------------------------------------------------------- -- Accessors from 'DynFlags' ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -35,9 +35,10 @@ Compiler - Fix a bug in TH causing excessive calls to ``setNumCapabilities`` when ``-j`` is greater than ``-N``. See GHC ticket #23049. -- GHC Proposal `#540 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0540-jsem.rst`_ has been implemented. This adds the `-jsem`:ghc-flag: which instructs GHC to act - as a jobserver client when passed. This enables multiple GHC processes running - at once to share the system resources with each other via the system semaphore. +- GHC Proposal `#540 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0540-jsem.rst`_ has been implemented. + This adds the `-jsem`:ghc-flag: flag, which instructs GHC to act as a jobserver client. + This enables multiple GHC processes running at once to share the system resources with each other via the system semaphore + specified as an argument to that flag. GHCi ===================================== docs/users_guide/using.rst ===================================== @@ -799,12 +799,11 @@ There are two kinds of participants in the GHC Jobserver protocol: :category: misc Perform compilation in parallel when possible, coordinating with other - processes through the semaphore ⟨sem⟩. + processes through the semaphore ⟨sem⟩ (specified as a string). Error if the semaphore doesn't exist. - Use of ``-jsem`` will override use of `-j[⟨n⟩]`:ghc-flag:. - - + Use of ``-jsem`` will override use of :ghc-flag:``-j[⟨n⟩]``, + and vice-versa. .. _multi-home-units: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f5791f48087131db2740f86e824f3485a2d03dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f5791f48087131db2740f86e824f3485a2d03dd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 11:30:28 2023 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Thu, 20 Apr 2023 07:30:28 -0400 Subject: [Git][ghc/ghc][wip/jsem] 141 commits: Rename () into Unit, (, , ..., , ) into Tuple (#21294) Message-ID: <6441225419d2f_178e744628b9506727f1@gitlab.mail> sheaf pushed to branch wip/jsem at Glasgow Haskell Compiler / GHC Commits: a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 090fe02d by sheaf at 2023-04-20T13:30:10+02:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - .gitmodules - cabal.project-reinstall - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f5791f48087131db2740f86e824f3485a2d03dd...090fe02dc3dc4f4ad011ff88f09cb0237e27a6f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f5791f48087131db2740f86e824f3485a2d03dd...090fe02dc3dc4f4ad011ff88f09cb0237e27a6f0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 11:36:04 2023 From: gitlab at gitlab.haskell.org (Melanie Brown (@mixphix)) Date: Thu, 20 Apr 2023 07:36:04 -0400 Subject: [Git][ghc/ghc][wip/clc-86] 102 commits: Update and expand atomic modification Haddocks Message-ID: <644123a49944e_178e744635514c675646@gitlab.mail> Melanie Brown pushed to branch wip/clc-86 at Glasgow Haskell Compiler / GHC Commits: 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 0f975887 by Melanie Phoenix at 2023-04-20T07:34:47-04:00 . - - - - - 0356402d by Melanie Phoenix at 2023-04-20T07:35:54-04:00 fix instance MonadZip NonEmpty - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/294f2101d3f93b60e881bab2efada73f9dd35c89...0356402ddf971b5e364d73ec588708aaf5d156c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/294f2101d3f93b60e881bab2efada73f9dd35c89...0356402ddf971b5e364d73ec588708aaf5d156c9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 11:37:04 2023 From: gitlab at gitlab.haskell.org (Melanie Brown (@mixphix)) Date: Thu, 20 Apr 2023 07:37:04 -0400 Subject: [Git][ghc/ghc][wip/clc-86] add qualified Data.Functor import Message-ID: <644123e092626_178e744636d92c6758d9@gitlab.mail> Melanie Brown pushed to branch wip/clc-86 at Glasgow Haskell Compiler / GHC Commits: fdf0efb4 by Melanie Phoenix at 2023-04-20T07:37:01-04:00 add qualified Data.Functor import - - - - - 1 changed file: - libraries/base/Control/Monad/Zip.hs Changes: ===================================== libraries/base/Control/Monad/Zip.hs ===================================== @@ -20,6 +20,7 @@ module Control.Monad.Zip where import Control.Monad (liftM, liftM2) import Data.Functor.Identity +import Data.Functor qualified import Data.Monoid import Data.Ord ( Down(..) ) import Data.Proxy View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdf0efb47723253029c9ee0aa82a840dbbeb02b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fdf0efb47723253029c9ee0aa82a840dbbeb02b9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 12:27:49 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Thu, 20 Apr 2023 08:27:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T21278 Message-ID: <64412fc5e129a_178e7447316310678810@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T21278 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T21278 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 14:26:37 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Thu, 20 Apr 2023 10:26:37 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/minor-docs Message-ID: <64414b9dcda_178e74496724586918ed@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/minor-docs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/minor-docs You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 14:35:16 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Thu, 20 Apr 2023 10:35:16 -0400 Subject: [Git][ghc/ghc][wip/minor-docs] Minor doc fixes Message-ID: <64414da47525c_178e74496f84906974a4@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/minor-docs at Glasgow Haskell Compiler / GHC Commits: 83664b5a by Krzysztof Gogolewski at 2023-04-20T16:35:04+02:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - 5 changed files: - .gitignore - docs/users_guide/exts/multiway_if.rst - docs/users_guide/javascript.rst - docs/users_guide/phases.rst - docs/users_guide/using-warnings.rst Changes: ===================================== .gitignore ===================================== @@ -115,6 +115,7 @@ _darcs/ /compiler/ghc.cabal.old /distrib/configure.ac /distrib/ghc.iss +/docs/index.html /docs/man /docs/users_guide/.log /docs/users_guide/users_guide ===================================== docs/users_guide/exts/multiway_if.rst ===================================== @@ -51,3 +51,11 @@ except that the semi-colons between guards in a multi-way if are optional. So it is not necessary to line up all the guards at the same column; this is consistent with the way guards work in function definitions and case expressions. + +Note that multi-way if supports guards other than boolean conditions: :: + + if | parseNumbers settings + , Just (exponent, mantissa) <- decomposeNumber str + , let (integralPart, fractionPart) = parse mantissa + , integralPart >= 0 = ... + | otherwise = ... ===================================== docs/users_guide/javascript.rst ===================================== @@ -1,4 +1,4 @@ -.. _ffi-javascript +.. _ffi-javascript: FFI and the JavaScript Backend ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ look like: js_add :: Int -> Int -> Int JSVal -^^^^^ +~~~~~ The JavaScript backend has a concept of an untyped 'plain' JavaScript value, under the guise of the type ``JSVal``. Values having this type @@ -47,7 +47,7 @@ It also contains functions for working with objects: * ``getProp :: JSVal -> String -> JSVal`` - object field access JavaScript FFI Types -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ Some types are able to be used directly in the type signatures of foreign exports, without conversion to a ``JSVal``. We saw in the first example @@ -75,7 +75,7 @@ for the Haskell `Bool` type: type_error :: Bool -> Bool JavaScript Callbacks -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The JavaScript execution model is based around callback functions, and GHC's JavaScript backend implements these as a type in order to support @@ -146,7 +146,7 @@ passed as an ``Int`` to a ``Callback`` that accepts a ``JSVal``: releaseCallback add3 Callbacks as Foreign Exports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JavaScript callbacks allow for a sort of FFI exports via FFI imports. To do this, a global JavaScript variable is set, and that global variable can then ===================================== docs/users_guide/phases.rst ===================================== @@ -247,13 +247,6 @@ the following flags: Pass ⟨option⟩ to the linker when merging object files. In the case of a standard ``ld``-style linker this should generally include the ``-r`` flag. -.. ghc-flag:: -optdll ⟨option⟩ - :shortdesc: pass ⟨option⟩ to the DLL generator - :type: dynamic - :category: phase-options - - Pass ⟨option⟩ to the DLL generator. - .. ghc-flag:: -optwindres ⟨option⟩ :shortdesc: pass ⟨option⟩ to ``windres``. :type: dynamic ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -2358,7 +2358,7 @@ of ``-W(no-)*``. :since: 9.6.1 - As explained in :ref:`undecidable_instances`, when using + As explained in :ref:`undecidable-instances`, when using :extension:`UndecidableInstances` it is possible for GHC to construct non-terminating evidence for certain superclass constraints. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/83664b5aca556ad0433183958fee6b640fc5eb48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/83664b5aca556ad0433183958fee6b640fc5eb48 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 14:48:34 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Thu, 20 Apr 2023 10:48:34 -0400 Subject: [Git][ghc/ghc][wip/sized-literals] 636 commits: testsuite: Mark T16392 as fragile on windows Message-ID: <644150c285069_178e74497c3a006977a0@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/sized-literals at Glasgow Haskell Compiler / GHC Commits: 5e047eff by Matthew Pickering at 2022-12-20T15:12:04+00:00 testsuite: Mark T16392 as fragile on windows See #22649 - - - - - 703a4665 by M Farkas-Dyck at 2022-12-20T21:14:46-05:00 Scrub some partiality in `GHC.Cmm.Info.Build`: `doSRTs` takes a `[(CAFSet, CmmDecl)]` but truly wants a `[(CAFSet, CmmStatics)]`. - - - - - 9736ab74 by Matthew Pickering at 2022-12-20T21:15:22-05:00 packaging: Fix upload_ghc_libs.py script This change reflects the changes where .cabal files are now generated by hadrian rather than ./configure. Fixes #22518 - - - - - 7c6de18d by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Drop uses of AC_PROG_CC_C99 As noted in #22566, this macro is deprecated as of autoconf-2.70 `AC_PROG_CC` now sets `ac_cv_prog_cc_c99` itself. Closes #22566. - - - - - 36c5d98e by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Use AS_HELP_STRING instead of AC_HELP_STRING The latter has been deprecated. See #22566. - - - - - befe6ff8 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: fix various usages of head and tail - - - - - 666d0ba7 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: avoid head and tail in parseCallEscape and around - - - - - 5d96fd50 by Bodigrim at 2022-12-20T21:16:37-05:00 Make GHC.Driver.Main.hscTcRnLookupRdrName to return NonEmpty - - - - - 3ce2ab94 by Bodigrim at 2022-12-21T06:17:56-05:00 Allow transformers-0.6 in ghc, ghci, ghc-bin and hadrian - - - - - 954de93a by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule haskeline to HEAD (to allow transformers-0.6) - - - - - cefbeec3 by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule transformers to 0.6.0.4 - - - - - b4730b62 by Bodigrim at 2022-12-21T06:17:56-05:00 Fix tests T13253 imports MonadTrans, which acquired a quantified constraint in transformers-0.6, thus increase in allocations Metric Increase: T13253 - - - - - 0be75261 by Simon Peyton Jones at 2022-12-21T06:18:32-05:00 Abstract over the right free vars Fix #22459, in two ways: (1) Make the Specialiser not create a bogus specialisation if it is presented by strangely polymorphic dictionary. See Note [Weird special case in SpecDict] in GHC.Core.Opt.Specialise (2) Be more careful in abstractFloats See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. So (2) stops creating the excessively polymorphic dictionary in abstractFloats, while (1) stops crashing if some other pass should nevertheless create a weirdly polymorphic dictionary. - - - - - df7bc6b3 by Ying-Ruei Liang (TheKK) at 2022-12-21T14:31:54-05:00 rts: explicitly store return value of ccall checkClosure to prevent type error (#22617) - - - - - e193e537 by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. - - - - - 3d55d8ab by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 - - - - - ceb2e9b9 by Ben Gamari at 2022-12-21T15:26:08-05:00 configure: Bump version to 9.6 - - - - - fb4d36c4 by Ben Gamari at 2022-12-21T15:27:49-05:00 base: Bump version to 4.18 Requires various submodule bumps. - - - - - 93ee7e90 by Ben Gamari at 2022-12-21T15:27:49-05:00 ghc-boot: Fix bootstrapping - - - - - fc3a2232 by Ben Gamari at 2022-12-22T13:45:06-05:00 Bump GHC version to 9.7 - - - - - 914f7fe3 by Andreas Klebinger at 2022-12-22T23:36:10-05:00 Don't consider large byte arrays/compact regions pinned. Workaround for #22255 which showed how treating large/compact regions as pinned could cause segfaults. - - - - - 32b32d7f by Matthew Pickering at 2022-12-22T23:36:46-05:00 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 - - - - - b3ddf803 by Ben Gamari at 2022-12-22T23:37:23-05:00 rts: Drop paths from configure from cabal file A long time ago we would rely on substitutions from the configure script to inject paths of the include and library directories of libffi and libdw. However, now these are instead handled inside Hadrian when calling Cabal's `configure` (see the uses of `cabalExtraDirs` in Hadrian's `Settings.Packages.packageArgs`). While the occurrences in the cabal file were redundant, they did no harm. However, since b5c714545abc5f75a1ffdcc39b4bfdc7cd5e64b4 they have no longer been interpolated. @mpickering noticed the suspicious uninterpolated occurrence of `@FFIIncludeDir@` in #22595, prompting this commit to finally remove them. - - - - - b2c7523d by Ben Gamari at 2022-12-22T23:37:59-05:00 Bump libffi-tarballs submodule We will now use libffi-3.4.4. - - - - - 3699a554 by Alan Zimmerman at 2022-12-22T23:38:35-05:00 EPA: Make EOF position part of AnnsModule Closes #20951 Closes #19697 - - - - - 99757ce8 by Sylvain Henry at 2022-12-22T23:39:13-05:00 JS: fix support for -outputdir (#22641) The `-outputdir` option wasn't correctly handled with the JS backend because the same code path was used to handle both objects produced by the JS backend and foreign .js files. Now we clearly distinguish the two in the pipeline, fixing the bug. - - - - - 02ed7d78 by Simon Peyton Jones at 2022-12-22T23:39:49-05:00 Refactor mkRuntimeError This patch fixes #22634. Because we don't have TYPE/CONSTRAINT polymorphism, we need two error functions rather than one. I took the opportunity to rname runtimeError to impossibleError, to line up with mkImpossibleExpr, and avoid confusion with the genuine runtime-error-constructing functions. - - - - - 35267f07 by Ben Gamari at 2022-12-22T23:40:32-05:00 base: Fix event manager shutdown race on non-Linux platforms During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this. - - - - - 317f45c1 by Simon Peyton Jones at 2022-12-22T23:41:07-05:00 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 - - - - - 14b2e3d3 by Ben Gamari at 2022-12-22T23:41:42-05:00 rts/m32: Fix sanity checking Previously we would attempt to clear pages which were marked as read-only. Fix this. - - - - - 16a1bcd1 by Matthew Pickering at 2022-12-23T09:15:24+00:00 ci: Move wasm pipelines into nightly rather than master See #22664 for the changes which need to be made to bring one of these back to the validate pipeline. - - - - - 18d2acd2 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. - - - - - 11241efa by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix segment list races - - - - - 602455c9 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. - - - - - 9d63b160 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. - - - - - 26837523 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that mutable fields have acquire barrier - - - - - 8093264a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. - - - - - 387d4fcc by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make segment state updates atomic - - - - - 543cae00 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. - - - - - c9936718 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. - - - - - 0cd31f7d by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. - - - - - d3fe110a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. - - - - - ab6cf893 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. - - - - - 36c9f23c by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). - - - - - aebef31c by doyougnu at 2022-12-23T19:10:09-05:00 add GHC.Utils.Binary.foldGet' and use for Iface A minor optimization to remove lazy IO and a lazy accumulator strictify foldGet' IFace.Binary: use strict foldGet' remove superfluous bang - - - - - 5eb357d9 by Ben Gamari at 2022-12-24T00:41:05-05:00 compiler: Ensure that GHC toolchain is first in search path As noted in #22561, it is important that GHC's toolchain look first for its own headers and libraries to ensure that the system's are not found instead. If this happens things can break in surprising ways (e.g. see #22561). - - - - - cbaebfb9 by Matthew Pickering at 2022-12-24T00:41:40-05:00 head.hackage: Use slow-validate bindist for linting jobs This enables the SLOW_VALIDATE env var for the linting head.hackage jobs, namely the jobs enabled manually, by the label or on the nightly build now use the deb10-numa-slow-validate bindist which has assertions enabled. See #22623 for a ticket which was found by using this configuration already! The head.hackage jobs triggered by upstream CI are now thusly: hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. Runs head.hackage with -dlint and a slow-validate bindist hackage-label-lint: Trigged on MRs with "user-facing" label, runs the slow-validate head.hackage build with -dlint. nightly-hackage-lint: Runs automatically on nightly pipelines with slow-validate + dlint config. nightly-hackage-perf: Runs automaticaly on nightly pipelines with release build and eventlogging enabled. release-hackage-lint: Runs automatically on release pipelines with -dlint on a release bindist. - - - - - f4850f36 by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Don't run abi-test-nightly on release jobs The test is not configured to get the correct dependencies for the release pipelines (and indeed stops the release pipeline being run at all) - - - - - c264b06b by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Run head.hackage jobs on upstream-testing branch rather than master This change allows less priviledged users to trigger head.hackage jobs because less permissions are needed to trigger jobs on the upstream-testing branch, which is not protected. There is a CI job which updates upstream-testing each hour to the state of the master branch so it should always be relatively up-to-date. - - - - - 63b97430 by Ben Gamari at 2022-12-24T00:42:16-05:00 llvmGen: Fix relaxed ordering Previously I used LLVM's `unordered` ordering for the C11 `relaxed` ordering. However, this is wrong and should rather use the LLVM `monotonic` ordering. Fixes #22640 - - - - - f42ba88f by Ben Gamari at 2022-12-24T00:42:16-05:00 gitlab-ci: Introduce aarch64-linux-llvm job This nightly job will ensure that we don't break the LLVM backend on AArch64/Linux by bootstrapping GHC. This would have caught #22640. - - - - - 6d62f6bf by Matthew Pickering at 2022-12-24T00:42:51-05:00 Store RdrName rather than OccName in Holes In #20472 it was pointed out that you couldn't defer out of scope but the implementation collapsed a RdrName into an OccName to stuff it into a Hole. This leads to the error message for a deferred qualified name dropping the qualification which affects the quality of the error message. This commit adds a bit more structure to a hole, so a hole can replace a RdrName without losing information about what that RdrName was. This is important when printing error messages. I also added a test which checks the Template Haskell deferral of out of scope qualified names works properly. Fixes #22130 - - - - - 3c3060e4 by Richard Eisenberg at 2022-12-24T17:34:19+00:00 Drop support for kind constraints. This implements proposal 547 and closes ticket #22298. See the proposal and ticket for motivation. Compiler perf improves a bit Metrics: compile_time/bytes allocated ------------------------------------- CoOpt_Singletons(normal) -2.4% GOOD T12545(normal) +1.0% T13035(normal) -13.5% GOOD T18478(normal) +0.9% T9872d(normal) -2.2% GOOD geo. mean -0.2% minimum -13.5% maximum +1.0% Metric Decrease: CoOpt_Singletons T13035 T9872d - - - - - 6d7d4393 by Ben Gamari at 2022-12-24T21:09:56-05:00 hadrian: Ensure that linker scripts are used when merging objects In #22527 @rui314 inadvertantly pointed out a glaring bug in Hadrian's implementation of the object merging rules: unlike the old `make` build system we utterly failed to pass the needed linker scripts. Fix this. - - - - - a5bd0eb8 by Bodigrim at 2022-12-24T21:10:34-05:00 Document infelicities of instance Ord Double and workarounds - - - - - 62b9a7b2 by Zubin Duggal at 2023-01-03T12:22:11+00:00 Force the Docs structure to prevent leaks in GHCi with -haddock without -fwrite-interface Involves adding many new NFData instances. Without forcing Docs, references to the TcGblEnv for each module are retained by the Docs structure. Usually these are forced when the ModIface is serialised but not when we aren't writing the interface. - - - - - 21bedd84 by Facundo Domínguez at 2023-01-03T23:27:30-05:00 Explain the auxiliary functions of permutations - - - - - 32255d05 by Matthew Pickering at 2023-01-04T11:58:42+00:00 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. - - - - - e640940c by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Fix computation of tables_next_to_code for outOfTreeCompiler This copy-pasto was introduced in de5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b - - - - - 15bee123 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 - - - - - fec6638e by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. - - - - - 3dc05726 by Matthew Pickering at 2023-01-04T11:58:42+00:00 check-exact: Fix build with -Werror - - - - - 53a6ae7a by Matthew Pickering at 2023-01-04T11:58:42+00:00 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 - - - - - 32e264c1 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 - - - - - be9dd9b0 by Matthew Pickering at 2023-01-04T11:58:42+00:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 - - - - - 00dc5106 by Matthew Pickering at 2023-01-04T14:32:45-05:00 sphinx: Use modern syntax for extlinks This fixes the following build error: ``` Command line: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build -b man -d /private/tmp/extra-dir-55768274273/.doctrees-man -n -w /private/tmp/extra-dir-55768274273/.log docs/users_guide /private/tmp/extra-dir-55768274273 ===> Command failed with error code: 2 Exception occurred: File "/opt/homebrew/Cellar/sphinx-doc/6.0.0/libexec/lib/python3.11/site-packages/sphinx/ext/extlinks.py", line 101, in role title = caption % part ~~~~~~~~^~~~~~ TypeError: not all arguments converted during string formatting ``` I tested on Sphinx-5.1.1 and Sphinx-6.0.0 Thanks for sterni for providing instructions about how to test using sphinx-6.0.0. Fixes #22690 - - - - - 541aedcd by Krzysztof Gogolewski at 2023-01-05T10:48:34-05:00 Misc cleanup - Remove unused uniques and hs-boot declarations - Fix types of seq and unsafeCoerce# - Remove FastString/String roundtrip in JS - Use TTG to enforce totality - Remove enumeration in Heap/Inspect; the 'otherwise' clause serves the primitive types well. - - - - - 22bb8998 by Alan Zimmerman at 2023-01-05T10:49:09-05:00 EPA: Do not collect comments from end of file In Parser.y semis1 production triggers for the virtual semi at the end of the file. This is detected by it being zero length. In this case, do not extend the span being used to gather comments, so any final comments are allocated at the module level instead. - - - - - 9e077999 by Vladislav Zavialov at 2023-01-05T23:01:55-05:00 HsToken in TypeArg (#19623) Updates the haddock submodule. - - - - - b2a2db04 by Matthew Pickering at 2023-01-05T23:02:30-05:00 Revert "configure: Drop uses of AC_PROG_CC_C99" This reverts commit 7c6de18dd3151ead954c210336728e8686c91de6. Centos7 using a very old version of the toolchain (autotools-2.69) where the behaviour of these macros has not yet changed. I am reverting this without haste as it is blocking the 9.6 branch. Fixes #22704 - - - - - 28f8c0eb by Luite Stegeman at 2023-01-06T18:16:24+09:00 Add support for sized literals in the bytecode interpreter. The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945 - - - - - ac39e8e9 by Matthew Pickering at 2023-01-06T13:47:00-05:00 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 - - - - - c306d939 by Matthew Pickering at 2023-01-06T22:08:53-05:00 ci: Upgrade darwin, windows and freebsd CI to use GHC-9.4.3 Fixes #22599 - - - - - 0db496ff by Matthew Pickering at 2023-01-06T22:08:53-05:00 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 2459c358 by Ben Gamari at 2023-01-06T22:09:29-05:00 rts: MUT_VAR is not a StgMutArrPtrs There was previously a comment claiming that the MUT_VAR closure type had the layout of StgMutArrPtrs. - - - - - 6206cb92 by Simon Peyton Jones at 2023-01-07T12:14:40-05:00 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 - - - - - a960ca81 by Matthew Pickering at 2023-01-07T12:15:15-05:00 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s - - - - - 73484710 by Matthew Pickering at 2023-01-07T12:15:15-05:00 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. - - - - - 8c0ea25f by Matthew Pickering at 2023-01-07T12:15:15-05:00 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes - - - - - 365b3045 by Matthew Pickering at 2023-01-09T02:36:20-05:00 Disable split sections on aarch64-deb10 build See #22722 Failure on this job: https://gitlab.haskell.org/ghc/ghc/-/jobs/1287852 ``` Unexpected failures: /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T10828.run T10828 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T13123.run T13123 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T20590.run T20590 [exit code non-0] (ext-interp) Appending 232 stats to file: /builds/ghc/ghc/performance-metrics.tsv ``` ``` Compile failed (exit code 1) errors were: data family D_0 a_1 :: * -> * data instance D_0 GHC.Types.Int GHC.Types.Bool :: * where DInt_2 :: D_0 GHC.Types.Int GHC.Types.Bool data E_3 where MkE_4 :: a_5 -> E_3 data Foo_6 a_7 b_8 where MkFoo_9, MkFoo'_10 :: a_11 -> Foo_6 a_11 b_12 newtype Bar_13 :: * -> GHC.Types.Bool -> * where MkBar_14 :: a_15 -> Bar_13 a_15 b_16 data T10828.T (a_0 :: *) where T10828.MkT :: forall (a_1 :: *) . a_1 -> a_1 -> T10828.T a_1 T10828.MkC :: forall (a_2 :: *) (b_3 :: *) . (GHC.Types.~) a_2 GHC.Types.Int => {T10828.foo :: a_2, T10828.bar :: b_3} -> T10828.T GHC.Types.Int T10828.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: (do TyConI dec <- runQ $ reify (mkName "T") runIO $ putStrLn (pprint dec) >> hFlush stdout d <- runQ $ [d| data T' a :: Type where MkT' :: a -> a -> T' a MkC' :: forall a b. (a ~ Int) => {foo :: a, bar :: b} -> T' Int |] runIO $ putStrLn (pprint d) >> hFlush stdout ....) *** unexpected failure for T10828(ext-interp) =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] Compile failed (exit code 1) errors were: T13123.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data GADT where MkGADT :: forall k proxy (a :: k). proxy a -> GADT |]) *** unexpected failure for T13123(ext-interp) =====> 7100 of 9215 [0, 2, 0] =====> 7100 of 9215 [0, 2, 0] =====> 7200 of 9215 [0, 2, 0] Compile failed (exit code 1) errors were: T20590.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data T where MkT :: forall a. a -> T |]) *** unexpected failure for T20590(ext-interp) ``` Looks fairly worrying to me. - - - - - 965a2735 by Alan Zimmerman at 2023-01-09T02:36:20-05:00 EPA: exact print HsDocTy To match ghc-exactprint https://github.com/alanz/ghc-exactprint/pull/121 - - - - - 5d65773e by John Ericson at 2023-01-09T20:39:27-05:00 Remove RTS hack for configuring See the brand new Note [Undefined symbols in the RTS] for additional details. - - - - - e3fff751 by Sebastian Graf at 2023-01-09T20:40:02-05:00 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite - - - - - d53f6f4d by Oleg Grenrus at 2023-01-09T21:11:02-05:00 Add safe list indexing operator: !? With Joachim's amendments. Implements https://github.com/haskell/core-libraries-committee/issues/110 - - - - - cfaf1ad7 by Nicolas Trangez at 2023-01-09T21:11:03-05:00 rts, tests: limit thread name length to 15 bytes On Linux, `pthread_setname_np` (or rather, the kernel) only allows for thread names up to 16 bytes, including the terminating null byte. This commit adds a note pointing this out in `createOSThread`, and fixes up two instances where a thread name of more than 15 characters long was used (in the RTS, and in a test-case). Fixes: #22366 Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/22366 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22366#note_460796 - - - - - 64286132 by Matthew Pickering at 2023-01-09T21:11:03-05:00 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 - - - - - 4724e8d1 by Matthew Pickering at 2023-01-09T21:11:04-05:00 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 - - - - - 2e926b88 by Georgi Lyubenov at 2023-01-09T21:11:07-05:00 Fix outdated link to Happy section on sequences - - - - - 146a1458 by Matthew Pickering at 2023-01-09T21:11:07-05:00 Revert "NCG(x86): Compile add+shift as lea if possible." This reverts commit 20457d775885d6c3df020d204da9a7acfb3c2e5a. See #22666 and #21777 - - - - - 6e6adbe3 by Jade Lovelace at 2023-01-11T00:55:30-05:00 Fix tcPluginRewrite example - - - - - faa57138 by Jade Lovelace at 2023-01-11T00:55:31-05:00 fix missing haddock pipe - - - - - 0470ea7c by Florian Weimer at 2023-01-11T00:56:10-05:00 m4/fp_leading_underscore.m4: Avoid implicit exit function declaration And switch to a new-style function definition. Fixes build issues with compilers that do not accept implicit function declarations. - - - - - b2857df4 by HaskellMouse at 2023-01-11T00:56:52-05:00 Added a new warning about compatibility with RequiredTypeArguments This commit introduces a new warning that indicates code incompatible with future extension: RequiredTypeArguments. Enabling this extension may break some code and the warning will help to make it compatible in advance. - - - - - 5f17e21a by Ben Gamari at 2023-01-11T00:57:27-05:00 testsuite: Drop testheapalloced.c As noted in #22414, this file (which appears to be a benchmark for characterising the one-step allocator's MBlock cache) is currently unreferenced. Remove it. Closes #22414. - - - - - bc125775 by Vladislav Zavialov at 2023-01-11T00:58:03-05:00 Introduce the TypeAbstractions language flag GHC Proposals #448 "Modern scoped type variables" and #425 "Invisible binders in type declarations" introduce a new language extension flag: TypeAbstractions. Part of the functionality guarded by this flag has already been implemented, namely type abstractions in constructor patterns, but it was guarded by a combination of TypeApplications and ScopedTypeVariables instead of a dedicated language extension flag. This patch does the following: * introduces a new language extension flag TypeAbstractions * requires TypeAbstractions for @a-syntax in constructor patterns instead of TypeApplications and ScopedTypeVariables * creates a User's Guide page for TypeAbstractions and moves the "Type Applications in Patterns" section there To avoid a breaking change, the new flag is implied by ScopedTypeVariables and is retroactively added to GHC2021. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 083f7015 by Krzysztof Gogolewski at 2023-01-11T00:58:38-05:00 Misc cleanup - Remove unused mkWildEvBinder - Use typeTypeOrConstraint - more symmetric and asserts that that the type is Type or Constraint - Fix escape sequences in Python; they raise a deprecation warning with -Wdefault - - - - - aed1974e by Richard Eisenberg at 2023-01-11T08:30:42+00:00 Refactor the treatment of loopy superclass dicts This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows. - - - - - 300bcc15 by HaskellMouse at 2023-01-11T13:43:36-05:00 Parse qualified terms in type signatures This commit allows qualified terms in type signatures to pass the parser and to be cathced by renamer with more informative error message. Adds a few tests. Fixes #21605 - - - - - 964284fc by Simon Peyton Jones at 2023-01-11T13:44:12-05:00 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. - - - - - f7ceafc9 by Krzysztof Gogolewski at 2023-01-11T22:36:59-05:00 Add 'docWithStyle' to improve codegen This new combinator docWithStyle :: IsOutput doc => doc -> (PprStyle -> SDoc) -> doc let us remove the need for code to be polymorphic in HDoc when not used in code style. Metric Decrease: ManyConstructors T13035 T1969 - - - - - b3be0d18 by Simon Peyton Jones at 2023-01-11T22:37:35-05:00 Fix finaliseArgBoxities for OPAQUE function We never do worker wrapper for OPAQUE functions, so we must zap the unboxing info during strictness analysis. This patch fixes #22502 - - - - - db11f358 by Ben Gamari at 2023-01-12T07:49:04-05:00 Revert "rts: Drop racy assertion" The logic here was inverted. Reverting the commit to avoid confusion when examining the commit history. This reverts commit b3eacd64fb36724ed6c5d2d24a81211a161abef1. - - - - - 3242139f by Ben Gamari at 2023-01-12T07:49:04-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 9ffd5d57 by Ben Gamari at 2023-01-12T07:49:41-05:00 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. - - - - - 905d0b6e by Sebastian Graf at 2023-01-12T15:51:47-05:00 Fix contification with stable unfoldings (#22428) Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with a `JoinArity` that reflects the number of join point binders around the body for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by `occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`. I adjusted `Note [Join points and unfoldings/rules]` and `Note [Adjusting right-hand sides]` to account for the new machinery. I also wrote a new `Note [Join arity prediction based on joinRhsArity]` and refer to it when we combine `TailUsageDetails` for a recursive RHS. I also renamed * `occAnalLam` to `occAnalLamTail` * `adjustRhsUsage` to `adjustTailUsage` * a few other less important functions and properly documented the that each call of `occAnalLamTail` must pair up with `adjustTailUsage`. I removed `Note [Unfoldings and join points]` because it was redundant with `Note [Occurrences in stable unfoldings]`. While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed `NodeDetails` called `SimpleNodeDetails`. Fixes #22428. The refactoring seems to have quite beneficial effect on ghc/alloc performance: ``` CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2% T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6% T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2% T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0% T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5% T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6% T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9% T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD geo. mean -0.6% minimum -2.4% maximum -0.0% ``` Metric Decrease: CoOpt_Read T10421 T12150 T12425 T13056 T18698a T18698b T21839c T21839r T9961 - - - - - a1491c87 by Andreas Klebinger at 2023-01-12T15:52:23-05:00 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. - - - - - 8acfe930 by Cheng Shao at 2023-01-12T15:53:00-05:00 Change MSYSTEM to CLANG64 uniformly - - - - - 73bc162b by M Farkas-Dyck at 2023-01-12T15:53:42-05:00 Make `GHC.Tc.Errors.Reporter` take `NonEmpty ErrorItem` rather than `[ErrorItem]`, which lets us drop some panics. Also use the `BasicMismatch` constructor rather than `mkBasicMismatchMsg`, which lets us drop the "-Wno-incomplete-record-updates" flag. - - - - - 1b812b69 by Oleg Grenrus at 2023-01-12T15:54:21-05:00 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general - - - - - c79b2b65 by Matthew Pickering at 2023-01-12T15:54:58-05:00 Don't run hadrian-multi on fast-ci label Fixes #22667 - - - - - 9a3d6add by Bodigrim at 2023-01-13T00:46:36-05:00 Bump submodule bytestring to 0.11.4.0 Metric Decrease: T21839c T21839r - - - - - df33c13c by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Bump Darwin bootstrap toolchain This updates the bootstrap compiler on Darwin from 8.10.7 to 9.2.5, ensuring that we have the fix for #21964. - - - - - 756a66ec by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Pass -w to cabal update Due to cabal#8447, cabal-install 3.8.1.0 requires a compiler to run `cabal update`. - - - - - 1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump hsc2hs submodule - - - - - d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump process submodule - - - - - 84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: Bump DOCKER_REV - - - - - d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: enable xz parallel compression for x64 jobs - - - - - d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: use in-image emsdk for js jobs - - - - - 93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings - Add a ghc environment including prebuilt dependencies to the nix-shell. Get rid of the ad hoc cabal cache and all dependencies are now downloaded from the nixos binary cache. - Make gen_ci.hs a cabal package with HLS integration, to make future hacking of gen_ci.hs easier. - Fix some ghc/hlint warnings after I got HLS to work. - For the lint-ci-config job, do a shallow clone to save a few minutes of unnecessary git checkout time. - - - - - 8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: source the toolchain env file in wasm jobs - - - - - 87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: add wasm ci jobs via gen_ci.hs - There is one regular wasm job run in validate pipelines - Additionally, int-native/unreg wasm jobs run in nightly/release pipelines Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml. - - - - - b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00 wasm ci: Remove wasm release jobs This removes the wasm release jobs, as we do not yet intend to distribute these binaries. - - - - - 496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. - - - - - 7a9a1042 by Andreas Klebinger at 2023-01-16T20:48:19-05:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 33b58f77 by sheaf at 2023-01-16T20:48:57-05:00 Hadrian: generalise &%> to avoid warnings This patch introduces a more general version of &%> that works with general traversable shapes, instead of lists. This allows us to pass along the information that the length of the list of filepaths passed to the function exactly matches the length of the input list of filepath patterns, avoiding pattern match warnings. Fixes #22430 - - - - - 8c7a991c by Andreas Klebinger at 2023-01-16T20:49:34-05:00 Add regression test for #22611. A case were a function used to fail to specialize, but now does. - - - - - 6abea760 by Andreas Klebinger at 2023-01-16T20:50:10-05:00 Mark maximumBy/minimumBy as INLINE. The RHS was too large to inline which often prevented the overhead of the Maybe from being optimized away. By marking it as INLINE we can eliminate the overhead of both the maybe and are able to unpack the accumulator when possible. Fixes #22609 - - - - - 99d151bb by Matthew Pickering at 2023-01-16T20:50:50-05:00 ci: Bump CACHE_REV so that ghc-9.6 branch and HEAD have different caches Having the same CACHE_REV on both branches leads to issues where the darwin toolchain is different on ghc-9.6 and HEAD which leads to long darwin build times. In general we should ensure that each branch has a different CACHE_REV. - - - - - 6a5845fb by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in source-tarball job This fixes errors of the form: ``` fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc inferred 9.7.20230113 checking for GHC Git commit id... fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc ``` - - - - - 4afb952c by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't build aarch64-deb10-llvm job on release pipelines Closes #22721 - - - - - 8039feb9 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in test-bootstrap job - - - - - 0b358d0c by Matthew Pickering at 2023-01-16T20:51:25-05:00 rel_eng: Add release engineering scripts into ghc tree It is better to keep these scripts in the tree as they depend on the CI configuration and so on. By keeping them in tree we can keep them up-to-date as the CI config changes and also makes it easier to backport changes to the release script between release branches in future. The final motivation is that it makes generating GHCUp metadata possible. - - - - - 28cb2ed0 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't use complicated image or clone in not-interruptible job This job exists only for the meta-reason of not allowing nightly pipelines to be cancelled. It was taking two minutes to run as in order to run "true" we would also clone the whole GHC repo. - - - - - eeea59bb by Matthew Pickering at 2023-01-16T20:51:26-05:00 Add scripts to generate ghcup metadata on nightly and release pipelines 1. A python script in .gitlab/rel_eng/mk-ghcup-metadata which generates suitable metadata for consumption by GHCUp for the relevant pipelines. - The script generates the metadata just as the ghcup maintainers want, without taking into account platform/library combinations. It is updated manually when the mapping changes. - The script downloads the bindists which ghcup wants to distribute, calculates the hash and generates the yaml in the correct structure. - The script is documented in the .gitlab/rel_eng/mk-ghcup-metadata/README.mk file 1a. The script requires us to understand the mapping from platform -> job. To choose the preferred bindist for each platform the .gitlab/gen_ci.hs script is modified to allow outputting a metadata file which answers the question about which job produces the bindist which we want to distribute to users for a specific platform. 2. Pipelines to run on nightly and release jobs to generate metadata - ghcup-metadata-nightly: Generates metadata which points directly to artifacts in the nightly job. - ghcup-metadata-release: Generates metadata suitable for inclusion directly in ghcup by pointing to the downloads folder where the bindist will be uploaded to. 2a. Trigger jobs which test the generated metadata in the downstream `ghccup-ci` repo. See that repo for documentation about what is tested and how but essentially we test in a variety of clean images that ghcup can download and install the bindists we say exist in our metadata. - - - - - 97bd4d8c by Bodigrim at 2023-01-16T20:52:04-05:00 Bump submodule parsec to 3.1.16.1 - - - - - 97ac8230 by Alan Zimmerman at 2023-01-16T20:52:39-05:00 EPA: Add annotation for 'type' in DataDecl Closes #22765 - - - - - dbbab95d by Ben Gamari at 2023-01-17T06:36:06-05:00 compiler: Small optimisation of assertM In #22739 @AndreasK noticed that assertM performed the action to compute the asserted predicate regardless of whether DEBUG is enabled. This is inconsistent with the other assertion operations and general convention. Fix this. Closes #22739. - - - - - fc02f3bb by Viktor Dukhovni at 2023-01-17T06:36:47-05:00 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 - - - - - 003b6d44 by Simon Peyton Jones at 2023-01-17T16:33:05-05:00 Document the semantics of pattern bindings a bit better This MR is in response to the discussion on #22719 - - - - - f4d50baf by Vladislav Zavialov at 2023-01-17T16:33:41-05:00 Hadrian: fix warnings (#22783) This change fixes the following warnings when building Hadrian: src/Hadrian/Expression.hs:38:10: warning: [-Wredundant-constraints] src/Hadrian/Expression.hs:84:13: warning: [-Wtype-equality-requires-operators] src/Hadrian/Expression.hs:84:21: warning: [-Wtype-equality-requires-operators] src/Hadrian/Haskell/Cabal/Parse.hs:67:1: warning: [-Wunused-imports] - - - - - 06036d93 by Sylvain Henry at 2023-01-18T01:55:10-05:00 testsuite: req_smp --> req_target_smp, req_ghc_smp See #22630 and !9552 This commit: - splits req_smp into req_target_smp and req_ghc_smp - changes the testsuite driver to calculate req_ghc_smp - changes a handful of tests to use req_target_smp instead of req_smp - changes a handful of tests to use req_host_smp when needed The problem: - the problem this solves is the ambiguity surrounding req_smp - on master req_smp was used to express the constraint that the program being compiled supports smp _and_ that the host RTS (i.e., the RTS used to compile the program) supported smp. Normally that is fine, but in cross compilation this is not always the case as was discovered in #22630. The solution: - Differentiate the two constraints: - use req_target_smp to say the RTS the compiled program is linked with (and the platform) supports smp - use req_host_smp to say the RTS the host is linked with supports smp WIP: fix req_smp (target vs ghc) add flag to separate bootstrapper split req_smp -> req_target_smp and req_ghc_smp update tests smp flags cleanup and add some docstrings only set ghc_with_smp to bootstrapper on S1 or CC Only set ghc_with_smp to bootstrapperWithSMP of when testing stage 1 and cross compiling test the RTS in config/ghc not hadrian re-add ghc_with_smp fix and align req names fix T11760 to use req_host_smp test the rts directly, avoid python 3.5 limitation test the compiler in a try block align out of tree and in tree withSMP flags mark failing tests as host req smp testsuite: req_host_smp --> req_ghc_smp Fix ghc vs host, fix ghc_with_smp leftover - - - - - ee9b78aa by Krzysztof Gogolewski at 2023-01-18T01:55:45-05:00 Use -Wdefault when running Python testdriver (#22727) - - - - - e9c0537c by Vladislav Zavialov at 2023-01-18T01:56:22-05:00 Enable -Wstar-is-type by default (#22759) Following the plan in GHC Proposal #143 "Remove the * kind syntax", which states: In the next release (or 3 years in), enable -fwarn-star-is-type by default. The "next release" happens to be 9.6.1 I also moved the T21583 test case from should_fail to should_compile, because the only reason it was failing was -Werror=compat in our test suite configuration. - - - - - 4efee43d by Ryan Scott at 2023-01-18T01:56:59-05:00 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. - - - - - f891a442 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. - - - - - b13c6ea5 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. - - - - - c45a5fff by Cheng Shao at 2023-01-18T07:28:37-05:00 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. - - - - - b4c14c4b by Luite Stegeman at 2023-01-18T14:21:42-05:00 Add PrimCallConv support to GHCi This adds support for calling Cmm code from bytecode using the native calling convention, allowing modules that use `foreign import prim` to be loaded and debugged in GHCi. This patch introduces a new `PRIMCALL` bytecode instruction and a helper stack frame `stg_primcall`. The code is based on the existing functionality for dealing with unboxed tuples in bytecode, which has been generalised to handle arbitrary calls. Fixes #22051 - - - - - d0a63ef8 by Adam Gundry at 2023-01-18T14:22:26-05:00 Refactor warning flag parsing to add missing flags This adds `-Werror=<group>` and `-fwarn-<group>` flags for warning groups as well as individual warnings. Previously these were defined on an ad hoc basis so for example we had `-Werror=compat` but not `-Werror=unused-binds`, whereas we had `-fwarn-unused-binds` but not `-fwarn-compat`. Fixes #22182. - - - - - 7ed1b8ef by Adam Gundry at 2023-01-18T14:22:26-05:00 Minor corrections to comments - - - - - 5389681e by Adam Gundry at 2023-01-18T14:22:26-05:00 Revise warnings documentation in user's guide - - - - - ab0d5cda by Adam Gundry at 2023-01-18T14:22:26-05:00 Move documentation of deferred type error flags out of warnings section - - - - - eb5a6b91 by John Ericson at 2023-01-18T22:24:10-05:00 Give the RTS it's own configure script Currently it doesn't do much anything, we are just trying to introduce it without breaking the build. Later, we will move functionality from the top-level configure script over to it. We need to bump Cabal for https://github.com/haskell/cabal/pull/8649; to facilitate and existing hack of skipping some configure checks for the RTS we now need to skip just *part* not *all* of the "post configure" hook, as running the configure script (which we definitely want to do) is also implemented as part of the "post configure" hook. But doing this requires exposing functionality that wasn't exposed before. - - - - - 32ab07bf by Bodigrim at 2023-01-18T22:24:51-05:00 ghc package does not have to depend on terminfo - - - - - 981ff7c4 by Bodigrim at 2023-01-18T22:24:51-05:00 ghc-pkg does not have to depend on terminfo - - - - - f058e367 by Ben Gamari at 2023-01-18T22:25:27-05:00 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. - - - - - 154889db by Ryan Scott at 2023-01-18T22:26:03-05:00 Add regression test for #22151 Issue #22151 was coincidentally fixed in commit aed1974e92366ab8e117734f308505684f70cddf (`Refactor the treatment of loopy superclass dicts`). This adds a regression test to ensure that the issue remains fixed. Fixes #22151. - - - - - 14b5982a by Andrei Borzenkov at 2023-01-18T22:26:43-05:00 Fix printing of promoted MkSolo datacon (#22785) Problem: In 2463df2f, the Solo data constructor was renamed to MkSolo, and Solo was turned into a pattern synonym for backwards compatibility. Since pattern synonyms can not be promoted, the old code that pretty-printed promoted single-element tuples started producing ill-typed code: t :: Proxy ('Solo Int) This fails with "Pattern synonym ‘Solo’ used as a type" The solution is to track the distinction between type constructors and data constructors more carefully when printing single-element tuples. - - - - - 1fe806d3 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add hi_core flavour transformer The hi_core flavour transformer enables -fwrite-if-simplified-core for stage1 libraries, which emit core into interface files to make it possible to restart code generation. Building boot libs with it makes it easier to use GHC API to prototype experimental backends that needs core/stg at link time. - - - - - 317cad26 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add missing docs for recently added flavour transformers - - - - - 658f4446 by Ben Gamari at 2023-01-23T04:49:23-05:00 gitlab-ci: Add Rocky8 jobs Addresses #22268. - - - - - a83ec778 by Vladislav Zavialov at 2023-01-23T04:49:58-05:00 Set "since: 9.8" for TypeAbstractions and -Wterm-variable-capture These flags did not make it into the 9.6 release series, so the "since" annotations must be corrected. - - - - - fec7c2ea by Alan Zimmerman at 2023-01-23T04:50:33-05:00 EPA: Add SourceText to HsOverLabel To be able to capture string literals with possible escape codes as labels. Close #22771 - - - - - 3efd1e99 by Ben Gamari at 2023-01-23T04:51:08-05:00 template-haskell: Bump version to 2.20.0.0 Updates `text` and `exceptions` submodules for bounds bumps. Addresses #22767. - - - - - 0900b584 by Cheng Shao at 2023-01-23T04:51:45-05:00 hadrian: disable alloca for in-tree GMP on wasm32 When building in-tree GMP for wasm32, disable its alloca usage, since it may potentially cause stack overflow (e.g. #22602). - - - - - db0f1bfd by Cheng Shao at 2023-01-23T04:52:21-05:00 Bump process submodule Includes a critical fix for wasm32, see https://github.com/haskell/process/pull/272 for details. Also changes the existing cross test to include process stuff and avoid future regression here. - - - - - 9222b167 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Fix subdir for windows bindist - - - - - 9a9bec57 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Remove viPostRemove field from generated metadata This has been removed from the downstream metadata. - - - - - 82884ce0 by Simon Peyton Jones at 2023-01-23T04:53:32-05:00 Fix #22742 runtimeRepLevity_maybe was panicing unnecessarily; and the error printing code made use of the case when it should return Nothing rather than panicing. For some bizarre reason perf/compiler/T21839r shows a 10% bump in runtime peak-megagbytes-used, on a single architecture (alpine). See !9753 for commentary, but I'm going to accept it. Metric Increase: T21839r - - - - - 2c6deb18 by Bryan Richter at 2023-01-23T14:12:22+02:00 codeowners: Add Ben, Matt, and Bryan to CI - - - - - eee3bf05 by Matthew Craven at 2023-01-23T21:46:41-05:00 Do not collect compile-time metrics for T21839r ...the testsuite doesn't handle this properly since it also collects run-time metrics. Compile-time metrics for this test are already tracked via T21839c. Metric Decrease: T21839r - - - - - 1d1dd3fb by Matthew Pickering at 2023-01-24T05:37:52-05:00 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 - - - - - 7bfb30f9 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 - - - - - 69500dd4 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 - - - - - 336b2b1c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 - - - - - 6469fea7 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 - - - - - 06cc0a95 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 - - - - - 4fe9eaff by Matthew Pickering at 2023-01-24T05:37:52-05:00 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 - - - - - ada29f5c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p - - - - - be701cc6 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. - - - - - 34d2d463 by Krzysztof Gogolewski at 2023-01-24T05:38:32-05:00 Fix Lint check for duplicate external names Lint was checking for duplicate external names by calling removeDups, which needs a comparison function that is passed to Data.List.sortBy. But the comparison was not a valid ordering - it returned LT if one of the names was not external. For example, the previous implementation won't find a duplicate in [M.x, y, M.x]. Instead, we filter out non-external names before looking for duplicates. - - - - - 1c050ed2 by Matthew Pickering at 2023-01-24T05:39:08-05:00 Add test for T22671 This was fixed by b13c6ea5 Closes #22671 - - - - - 05e6a2d9 by Tom Ellis at 2023-01-24T12:10:52-05:00 Clarify where `f` is defined - - - - - d151546e by Cheng Shao at 2023-01-24T12:11:29-05:00 CmmToC: fix CmmRegOff for 64-bit register on a 32-bit target We used to print the offset value to a platform word sized integer. This is incorrect when the offset is negative (e.g. output of cmm constant folding) and the register is 64-bit but on a 32-bit target, and may lead to incorrect runtime result (e.g. #22607). The fix is simple: just treat it as a proper MO_Add, with the correct width info inferred from the register itself. Metric Increase: T12707 T13379 T4801 T5321FD T5321Fun - - - - - e5383a29 by Wander Hillen at 2023-01-24T20:02:26-05:00 Allow waiting for timerfd to be interrupted during rts shutdown - - - - - 1957eda1 by Ryan Scott at 2023-01-24T20:03:01-05:00 Restore Compose's Read/Show behavior to match Read1/Show1 instances Fixes #22816. - - - - - 30972827 by Matthew Pickering at 2023-01-25T03:54:14-05:00 docs: Update INSTALL.md Removes references to make. Fixes #22480 - - - - - bc038c3b by Cheng Shao at 2023-01-25T03:54:50-05:00 compiler: fix handling of MO_F_Neg in wasm NCG In the wasm NCG, we used to compile MO_F_Neg to 0.0-x. It was an oversight, there actually exists f32.neg/f64.neg opcodes in the wasm spec and those should be used instead! The old behavior almost works, expect when GHC compiles the -0.0 literal, which will incorrectly become 0.0. - - - - - e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. - - - - - 48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. - - - - - 288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. - - - - - 2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00 configure: support "windows" as an OS - - - - - 13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00 Fix in-scope set in specImports Nothing deep here; I had failed to bring some floated dictionary binders into scope. Exposed by -fspecialise-aggressively Fixes #22715. - - - - - b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00 ci: Disable HLint job due to excessive runtime The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91 Now the CI job will build the stage0 compiler before it generates the necessary RTS headers. We either need to: * Fix the linting rules so they take much less time * Revert the commit * Remove the linting of base from the hlint job * Remove the hlint job This is highest priority as it is affecting all CI pipelines. For now I am just disabling the job because there are many more pressing matters at hand. Ticket #22830 - - - - - 1bd32a35 by Sylvain Henry at 2023-01-26T12:34:21-05:00 Factorize hptModulesBelow Create and use moduleGraphModulesBelow in GHC.Unit.Module.Graph that doesn't need anything from the driver to be used. - - - - - 1262d3f8 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 - - - - - e27eb80c by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 - - - - - 3d004d5a by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 - - - - - f2a0fea0 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 - - - - - 5640cb1d by Sylvain Henry at 2023-01-26T12:35:36-05:00 Hadrian: fix doc generation Was missing dependencies on files generated by templates (e.g. ghc.cabal) - - - - - 3e827c3f by Richard Eisenberg at 2023-01-26T20:06:53-05:00 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. Close #22519. - - - - - b3ef5c89 by doyougnu at 2023-01-26T20:07:48-05:00 tryFillBuffer: strictify more speculative bangs - - - - - d0d7ba0f by Vladislav Zavialov at 2023-01-26T20:08:25-05:00 base: NoImplicitPrelude in Data.Void and Data.Kind This change removes an unnecessary dependency on Prelude from two modules in the base package. - - - - - fa1db923 by Matthew Pickering at 2023-01-26T20:09:00-05:00 ci: Add ubuntu18_04 nightly and release jobs This adds release jobs for ubuntu18_04 which uses glibc 2.27 which is older than the 2.28 which is used by Rocky8 bindists. Ticket #22268 - - - - - 807310a1 by Matthew Pickering at 2023-01-26T20:09:00-05:00 rel-eng: Add missing rocky8 bindist We intend to release rocky8 bindist so the fetching script needs to know about them. - - - - - c7116b10 by Ben Gamari at 2023-01-26T20:09:35-05:00 base: Make changelog proposal references more consistent Addresses #22773. - - - - - 6932cfc7 by Sylvain Henry at 2023-01-26T20:10:27-05:00 Fix spurious change from !9568 - - - - - e480fbc2 by Ben Gamari at 2023-01-27T05:01:24-05:00 rts: Use C11-compliant static assertion syntax Previously we used `static_assert` which is only available in C23. By contrast, C11 only provides `_Static_assert`. Fixes #22777 - - - - - 2648c09c by Andrei Borzenkov at 2023-01-27T05:02:07-05:00 Replace errors from badOrigBinding with new one (#22839) Problem: in 02279a9c the type-level [] syntax was changed from a built-in name to an alias for the GHC.Types.List constructor. badOrigBinding assumes that if a name is not built-in then it must have come from TH quotation, but this is not necessarily the case with []. The outdated assumption in badOrigBinding leads to incorrect error messages. This code: data [] Fails with "Cannot redefine a Name retrieved by a Template Haskell quote: []" Unfortunately, there is not enough information in RdrName to directly determine if the name was constructed via TH or by the parser, so this patch changes the error message instead. It unifies TcRnIllegalBindingOfBuiltIn and TcRnNameByTemplateHaskellQuote into a new error TcRnBindingOfExistingName and changes its wording to avoid guessing the origin of the name. - - - - - 545bf8cf by Matthew Pickering at 2023-01-27T14:58:53+00:00 Revert "base: NoImplicitPrelude in Data.Void and Data.Kind" Fixes CI errors of the form. ``` ===> Command failed with error code: 1 ghc: panic! (the 'impossible' happened) GHC version 9.7.20230127: lookupGlobal Failed to load interface for ‘GHC.Num.BigNat’ There are files missing in the ‘ghc-bignum’ package, try running 'ghc-pkg check'. Use -v (or `:set -v` in ghci) to see a list of the files searched for. Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Tc/Utils/Env.hs:154:32 in ghc:GHC.Tc.Utils.Env CallStack (from HasCallStack): panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` This reverts commit d0d7ba0fb053ebe7f919a5932066fbc776301ccd. The module now lacks a dependency on GHC.Num.BigNat which it implicitly depends on. It is causing all CI jobs to fail so we revert without haste whilst the patch can be fixed. Fixes #22848 - - - - - 638277ba by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Detect family instance orphans correctly We were treating a type-family instance as a non-orphan if there was a type constructor on its /right-hand side/ that was local. Boo! Utterly wrong. With this patch, we correctly check the /left-hand side/ instead! Fixes #22717 - - - - - 46a53bb2 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Report family instance orphans correctly This fixes the fact that we were not reporting orphan family instances at all. The fix here is easy, but touches a bit of code. I refactored the code to be much more similar to the way that class instances are done: - Add a fi_orphan field to FamInst, like the is_orphan field in ClsInst - Make newFamInst initialise this field, just like newClsInst - And make newFamInst report a warning for an orphan, just like newClsInst - I moved newFamInst from GHC.Tc.Instance.Family to GHC.Tc.Utils.Instantiate, just like newClsInst. - I added mkLocalFamInst to FamInstEnv, just like mkLocalClsInst in InstEnv - TcRnOrphanInstance and SuggestFixOrphanInstance are now parametrised over class instances vs type/data family instances. Fixes #19773 - - - - - faa300fb by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in STG This patch removes some orphan instances in the STG namespace by introducing the GHC.Stg.Lift.Types module, which allows various type family instances to be moved to GHC.Stg.Syntax, avoiding orphan instances. - - - - - 0f25a13b by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in the parser This moves Anno instances for PatBuilder from GHC.Parser.PostProcess to GHC.Parser.Types to avoid orphans. - - - - - 15750d33 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Accept an orphan declaration (sadly) This accepts the orphan type family instance type instance DsForeignHook = ... in GHC.HsToCore.Types. See Note [The Decoupling Abstract Data Hack] in GHC.Driver.Hooks - - - - - c9967d13 by Zubin Duggal at 2023-01-27T23:55:31-05:00 bindist configure: Fail if find not found (#22691) - - - - - ad8cfed4 by John Ericson at 2023-01-27T23:56:06-05:00 Put hadrian bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. - - - - - d0ddc01b by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Introduce threaded2_sanity way Incredibly, we previously did not have a single way which would test the threaded RTS with multiple capabilities and the sanity-checker enabled. - - - - - 38ad8351 by Ben Gamari at 2023-01-27T23:56:42-05:00 rts: Relax Messages assertion `doneWithMsgThrowTo` was previously too strict in asserting that the `Message` is locked. Specifically, it failed to consider that the `Message` may not be locked if we are deleting all threads during RTS shutdown. - - - - - a9fe81af by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Fix race in UnliftedTVar2 Previously UnliftedTVar2 would fail when run with multiple capabilities (and possibly even with one capability) as it would assume that `killThread#` would immediately kill the "increment" thread. Also, refactor the the executable to now succeed with no output and fails with an exit code. - - - - - 8519af60 by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Make listThreads more robust Previously it was sensitive to the labels of threads which it did not create (e.g. the IO manager event loop threads). Fix this. - - - - - 55a81995 by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix non-atomic mutation of enabled_capabilities - - - - - b5c75f1d by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix C++ compilation issues Make the RTS compilable with a C++ compiler by inserting necessary casts. - - - - - c261b62f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix typo "tracingAddCapabilities" was mis-named - - - - - 77fdbd3f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Drop long-dead fallback definitions for INFINITY & NAN These are no longer necessary since we now compile as C99. - - - - - 56c1bd98 by Ben Gamari at 2023-01-28T02:57:59-05:00 Revert "CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043)" This reverts commit 99aca26b652603bc62953157a48e419f737d352d. - - - - - b3a3534b by nineonine at 2023-01-28T02:57:59-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043. - - - - - 082b7d43 by Oleg Grenrus at 2023-01-28T02:58:38-05:00 Add Foldable1 Solo instance - - - - - 50b1e2e8 by Andrei Borzenkov at 2023-01-28T02:59:18-05:00 Convert diagnostics in GHC.Rename.Bind to proper TcRnMessage (#20115) I removed all occurrences of TcRnUnknownMessage in GHC.Rename.Bind module. Instead, these TcRnMessage messages were introduced: TcRnMultipleFixityDecls TcRnIllegalPatternSynonymDecl TcRnIllegalClassBiding TcRnOrphanCompletePragma TcRnEmptyCase TcRnNonStdGuards TcRnDuplicateSigDecl TcRnMisplacedSigDecl TcRnUnexpectedDefaultSig TcRnBindInBootFile TcRnDuplicateMinimalSig - - - - - 3330b819 by Matthew Pickering at 2023-01-28T02:59:54-05:00 hadrian: Fix library-dirs, dynamic-library-dirs and static-library-dirs in inplace .conf files Previously we were just throwing away the contents of the library-dirs fields but really we have to do the same thing as for include-dirs, relativise the paths into the current working directory and maintain any extra libraries the user has specified. Now the relevant section of the rts.conf file looks like: ``` library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib library-dirs-static: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib dynamic-library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib ``` Fixes #22209 - - - - - c9ad8852 by Bodigrim at 2023-01-28T03:00:33-05:00 Document differences between Data.{Monoid,Semigroup}.{First,Last} - - - - - 7e11c6dc by Cheng Shao at 2023-01-28T03:01:09-05:00 compiler: fix subword literal narrowing logic in the wasm NCG This patch fixes the W8/W16 literal narrowing logic in the wasm NCG, which used to lower it to something like i32.const -1, without properly zeroing-out the unused higher bits. Fixes #22608. - - - - - 6ea2aa02 by Cheng Shao at 2023-01-28T03:01:46-05:00 compiler: fix lowering of CmmBlock in the wasm NCG The CmmBlock datacon was not handled in lower_CmmLit, since I thought it would have been eliminated after proc-point splitting. Turns out it still occurs in very rare occasions, and this patch is needed to fix T9329 for wasm. - - - - - 2b62739d by Bodigrim at 2023-01-28T17:16:11-05:00 Assorted changes to avoid Data.List.{head,tail} - - - - - 78c07219 by Cheng Shao at 2023-01-28T17:16:48-05:00 compiler: properly handle ForeignHints in the wasm NCG Properly handle ForeignHints of ccall arguments/return value, insert sign extends and truncations when handling signed subwords. Fixes #22852. - - - - - 8bed166b by Ben Gamari at 2023-01-30T05:06:26-05:00 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. - - - - - da468391 by Cheng Shao at 2023-01-30T05:07:03-05:00 compiler: fix data section alignment in the wasm NCG Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size. - - - - - 08ba8720 by Andreas Klebinger at 2023-01-30T21:18:45-05:00 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- - - - - - 20598ef6 by Ryan Scott at 2023-01-30T21:19:20-05:00 Handle `type data` properly in tyThingParent_maybe Unlike most other data constructors, data constructors declared with `type data` are represented in `TyThing`s as `ATyCon` rather than `ADataCon`. The `ATyCon` case in `tyThingParent_maybe` previously did not consider the possibility of the underlying `TyCon` being a promoted data constructor, which led to the oddities observed in #22817. This patch adds a dedicated special case in `tyThingParent_maybe`'s `ATyCon` case for `type data` data constructors to fix these oddities. Fixes #22817. - - - - - 2f145052 by Ryan Scott at 2023-01-30T21:19:56-05:00 Fix two bugs in TypeData TH reification This patch fixes two issues in the way that `type data` declarations were reified with Template Haskell: * `type data` data constructors are now properly reified using `DataConI`. This is accomplished with a special case in `reifyTyCon`. Fixes #22818. * `type data` type constructors are now reified in `reifyTyCon` using `TypeDataD` instead of `DataD`. Fixes #22819. - - - - - d0f34f25 by Simon Peyton Jones at 2023-01-30T21:20:35-05:00 Take account of loop breakers in specLookupRule The key change is that in GHC.Core.Opt.Specialise.specLookupRule we were using realIdUnfolding, which ignores the loop-breaker flag. When given a loop breaker, rule matching therefore looped infinitely -- #22802. In fixing this I refactored a bit. * Define GHC.Core.InScopeEnv as a data type, and use it. (Previously it was a pair: hard to grep for.) * Put several functions returning an IdUnfoldingFun into GHC.Types.Id, namely idUnfolding alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun and use them. (The are all loop-breaker aware.) - - - - - de963cb6 by Matthew Pickering at 2023-01-30T21:21:11-05:00 ci: Remove FreeBSD job from release pipelines We no longer attempt to build or distribute this release - - - - - f26d27ec by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Add check to make sure that release jobs are downloaded by fetch-gitlab This check makes sure that if a job is a prefixed by "release-" then the script downloads it and understands how to map the job name to the platform. - - - - - 7619c0b4 by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Fix the name of the ubuntu-* jobs These were not uploaded for alpha1 Fixes #22844 - - - - - 68eb8877 by Matthew Pickering at 2023-01-30T21:21:11-05:00 gen_ci: Only consider release jobs for job metadata In particular we do not have a release job for FreeBSD so the generation of the platform mapping was failing. - - - - - b69461a0 by Jason Shipman at 2023-01-30T21:21:50-05:00 User's guide: Clarify overlapping instance candidate elimination This commit updates the user's guide section on overlapping instance candidate elimination to use "or" verbiage instead of "either/or" in regards to the current pair of candidates' being overlappable or overlapping. "Either IX is overlappable, or IY is overlapping" can cause confusion as it suggests "Either IX is overlappable, or IY is overlapping, but not both". This was initially discussed on this Discourse topic: https://discourse.haskell.org/t/clarification-on-overlapping-instance-candidate-elimination/5677 - - - - - 7cbdaad0 by Matthew Pickering at 2023-01-31T07:53:53-05:00 Fixes for cabal-reinstall CI job * Allow filepath to be reinstalled * Bump some version bounds to allow newer versions of libraries * Rework testing logic to avoid "install --lib" and package env files Fixes #22344 - - - - - fd8f32bf by Cheng Shao at 2023-01-31T07:54:29-05:00 rts: prevent potential divide-by-zero when tickInterval=0 This patch fixes a few places in RtsFlags.c that may result in divide-by-zero error when tickInterval=0, which is the default on wasm. Fixes #22603. - - - - - 085a6db6 by Joachim Breitner at 2023-01-31T07:55:05-05:00 Update note at beginning of GHC.Builtin.NAmes some things have been renamed since it was written, it seems. - - - - - 7716cbe6 by Cheng Shao at 2023-01-31T07:55:41-05:00 testsuite: use tgamma for cg007 gamma is a glibc-only deprecated function, use tgamma instead. It's required for fixing cg007 when testing the wasm unregisterised codegen. - - - - - 19c1fbcd by doyougnu at 2023-01-31T13:08:03-05:00 InfoTableProv: ShortText --> ShortByteString - - - - - 765fab98 by doyougnu at 2023-01-31T13:08:03-05:00 FastString: add fastStringToShorText - - - - - a83c810d by Simon Peyton Jones at 2023-01-31T13:08:38-05:00 Improve exprOkForSpeculation for classops This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord - - - - - f83374f8 by Krzysztof Gogolewski at 2023-01-31T13:09:14-05:00 Support "unusable UNPACK pragma" warning with -O0 Fixes #11270 - - - - - a2d814dc by Ben Gamari at 2023-01-31T13:09:50-05:00 configure: Always create the VERSION file Teach the `configure` script to create the `VERSION` file. This will serve as the stable interface to allow the user to determine the version number of a working tree. Fixes #22322. - - - - - 5618fc21 by sheaf at 2023-01-31T15:51:06-05:00 Cmm: track the type of global registers This patch tracks the type of Cmm global registers. This is needed in order to lint uses of polymorphic registers, such as SIMD vector registers that can be used both for floating-point and integer values. This changes allows us to refactor VanillaReg to not store VGcPtr, as that information is instead stored in the type of the usage of the register. Fixes #22297 - - - - - 78b99430 by sheaf at 2023-01-31T15:51:06-05:00 Revert "Cmm Lint: relax SIMD register assignment check" This reverts commit 3be48877, which weakened a Cmm Lint check involving SIMD vectors. Now that we keep track of the type a global register is used at, we can restore the original stronger check. - - - - - be417a47 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. - - - - - 30989d13 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. - - - - - 7566fd9d by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. - - - - - 2cb500a5 by Ben Gamari at 2023-01-31T15:51:45-05:00 testsuite: Add regression test for #22798 - - - - - 03d693b2 by Ben Gamari at 2023-01-31T15:52:32-05:00 Revert "Hadrian: fix doc generation" This is too large of a hammer. This reverts commit 5640cb1d84d3cce4ce0a9e90d29b2b20d2b38c2f. - - - - - f838815c by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Sphinx docs require templated cabal files The package-version discovery logic in `doc/users_guide/package_versions.py` uses packages' cabal files to determine package versions. Teach Sphinx about these dependencies in cases where the cabal files are generated by templates. - - - - - 2e48c19a by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Refactor templating logic This refactors Hadrian's autoconf-style templating logic to be explicit about which interpolation variables should be substituted in which files. This clears the way to fix #22714 without incurring rule cycles. - - - - - 93f0e3c4 by Ben Gamari at 2023-01-31T15:52:33-05:00 hadrian: Substitute LIBRARY_*_VERSION variables This teaches Hadrian to substitute the `LIBRARY_*_VERSION` variables in `libraries/prologue.txt`, fixing #22714. Fixes #22714. - - - - - 22089f69 by Ben Gamari at 2023-01-31T20:46:27-05:00 Bump transformers submodule to 0.6.0.6 Fixes #22862. - - - - - f0eefa3c by Cheng Shao at 2023-01-31T20:47:03-05:00 compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCG Currently, the wasm NCG has an implicit assumption: all CmmSwitch scrutinees are 32-bit integers. This is not always true; #22864 is one counter-example with a 64-bit scrutinee. This patch fixes the logic by explicitly converting the scrutinee to a word that can be used as a br_table operand. Fixes #22871. Also includes a regression test. - - - - - 9f95db54 by Simon Peyton Jones at 2023-02-01T08:55:08+00:00 Improve treatment of type applications in patterns This patch fixes a subtle bug in the typechecking of type applications in patterns, e.g. f (MkT @Int @a x y) = ... See Note [Type applications in patterns] in GHC.Tc.Gen.Pat. This fixes #19847, #22383, #19577, #21501 - - - - - 955a99ea by Simon Peyton Jones at 2023-02-01T12:31:23-05:00 Treat existentials correctly in dubiousDataConInstArgTys Consider (#22849) data T a where MkT :: forall k (t::k->*) (ix::k). t ix -> T @k a Then dubiousDataConInstArgTys MkT [Type, Foo] should return [Foo (ix::Type)] NOT [Foo (ix::k)] A bit of an obscure case, but it's an outright bug, and the fix is easy. - - - - - 0cc16aaf by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump supported LLVM range from 10 through 15 to 11 through 16 LLVM 15 turns on the new pass manager by default, which we have yet to migrate to so for new we pass the `-enable-new-pm-0` flag in our llvm-passes flag. LLVM 11 was the first version to support the `-enable-new-pm` flag so we bump the lowest supported version to 11. Our CI jobs are using LLVM 12 so they should continue to work despite this bump to the lower bound. Fixes #21936 - - - - - f94f1450 by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump DOCKER_REV to use alpine image without LLVM installed alpine_3_12 only supports LLVM 10, which is now outside the supported version range. - - - - - 083e26ed by Matthew Pickering at 2023-02-01T17:43:21-05:00 Remove tracing OPTIONS_GHC These were accidentally left over from !9542 - - - - - 354aa47d by Teo Camarasu at 2023-02-01T17:44:00-05:00 doc: fix gcdetails_block_fragmentation_bytes since annotation - - - - - 61ce5bf6 by Jaro Reinders at 2023-02-02T00:15:30-05:00 compiler: Implement higher order patterns in the rule matcher This implements proposal 555 and closes ticket #22465. See the proposal and ticket for motivation. The core changes of this patch are in the GHC.Core.Rules.match function and they are explained in the Note [Matching higher order patterns]. - - - - - 394b91ce by doyougnu at 2023-02-02T00:16:10-05:00 CI: JavaScript backend runs testsuite This MR runs the testsuite for the JS backend. Note that this is a temporary solution until !9515 is merged. Key point: The CI runs hadrian on the built cross compiler _but not_ on the bindist. Other Highlights: - stm submodule gets a bump to mark tests as broken - several tests are marked as broken or are fixed by adding more - conditions to their test runner instance. List of working commit messages: CI: test cross target _and_ emulator CI: JS: Try run testsuite with hadrian JS.CI: cleanup and simplify hadrian invocation use single bracket, print info JS CI: remove call to test_compiler from hadrian don't build haddock JS: mark more tests as broken Tracked in https://gitlab.haskell.org/ghc/ghc/-/issues/22576 JS testsuite: don't skip sum_mod test Its expected to fail, yet we skipped it which automatically makes it succeed leading to an unexpected success, JS testsuite: don't mark T12035j as skip leads to an unexpected pass JS testsuite: remove broken on T14075 leads to unexpected pass JS testsuite: mark more tests as broken JS testsuite: mark T11760 in base as broken JS testsuite: mark ManyUnbSums broken submodules: bump process and hpc for JS tests Both submodules has needed tests skipped or marked broken for th JS backend. This commit now adds these changes to GHC. See: HPC: https://gitlab.haskell.org/hpc/hpc/-/merge_requests/21 Process: https://github.com/haskell/process/pull/268 remove js_broken on now passing tests separate wasm and js backend ci test: T11760: add threaded, non-moving only_ways test: T10296a add req_c T13894: skip for JS backend tests: jspace, T22333: mark as js_broken(22573) test: T22513i mark as req_th stm submodule: mark stm055, T16707 broken for JS tests: js_broken(22374) on unpack_sums_6, T12010 dont run diff on JS CI, cleanup fixup: More CI cleanup fix: align text to master fix: align exceptions submodule to master CI: Bump DOCKER_REV Bump to ci-images commit that has a deb11 build with node. Required for !9552 testsuite: mark T22669 as js_skip See #22669 This test tests that .o-boot files aren't created when run in using the interpreter backend. Thus this is not relevant for the JS backend. testsuite: mark T22671 as broken on JS See #22835 base.testsuite: mark Chan002 fragile for JS see #22836 revert: submodule process bump bump stm submodule New hash includes skips for the JS backend. testsuite: mark RnPatternSynonymFail broken on JS Requires TH: - see !9779 - and #22261 compiler: GHC.hs ifdef import Utils.Panic.Plain - - - - - 1ffe770c by Cheng Shao at 2023-02-02T09:40:38+00:00 docs: 9.6 release notes for wasm backend - - - - - 0ada4547 by Matthew Pickering at 2023-02-02T11:39:44-05:00 Disable unfolding sharing for interface files with core definitions Ticket #22807 pointed out that the RHS sharing was not compatible with -fignore-interface-pragmas because the flag would remove unfoldings from identifiers before the `extra-decls` field was populated. For the 9.6 timescale the only solution is to disable this sharing, which will make interface files bigger but this is acceptable for the first release of `-fwrite-if-simplified-core`. For 9.8 it would be good to fix this by implementing #20056 due to the large number of other bugs that would fix. I also improved the error message in tc_iface_binding to avoid the "no match in record selector" error but it should never happen now as the entire sharing logic is disabled. Also added the currently broken test for #22807 which could be fixed by !6080 Fixes #22807 - - - - - 7e2d3eb5 by lrzlin at 2023-02-03T05:23:27-05:00 Enable tables next to code for LoongArch64 - - - - - 2931712a by Wander Hillen at 2023-02-03T05:24:06-05:00 Move pthread and timerfd ticker implementations to separate files - - - - - 41c4baf8 by Ben Gamari at 2023-02-03T05:24:44-05:00 base: Fix Note references in GHC.IO.Handle.Types - - - - - 31358198 by Bodigrim at 2023-02-03T05:25:22-05:00 Bump submodule containers to 0.6.7 Metric Decrease: ManyConstructors T10421 T12425 T12707 T13035 T13379 T15164 T1969 T783 T9198 T9961 WWRec - - - - - 8feb9301 by Ben Gamari at 2023-02-03T05:25:59-05:00 gitlab-ci: Eliminate redundant ghc --info output Previously ci.sh would emit the output of `ghc --info` every time it ran when using the nix toolchain. This produced a significant amount of noise. See #22861. - - - - - de1d1512 by Ryan Scott at 2023-02-03T14:07:30-05:00 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` - - - - - 48e39195 by Tamar Christina at 2023-02-03T14:07:30-05:00 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. - - - - - b2bb3e62 by Ben Gamari at 2023-02-03T14:07:30-05:00 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - bf3f88a1 by Andreas Klebinger at 2023-02-03T14:08:07-05:00 Fix CallerCC potentially shadowing other cost centres. Add a CallerCC cost centre flavour for cost centres added by the CallerCC pass. This avoids potential accidental shadowing between CCs added by user annotations and ones added by CallerCC. - - - - - faea4bcd by j at 2023-02-03T14:08:47-05:00 Disable several ignore-warning flags in genapply. - - - - - 25537dfd by Ben Gamari at 2023-02-04T04:12:57-05:00 Revert "Use fix-sized bit-fiddling primops for fixed size boxed types" This reverts commit 4512ad2d6a8e65ea43c86c816411cb13b822f674. This was never applied to master/9.6 originally. (cherry picked from commit a44bdc2720015c03d57f470b759ece7fab29a57a) - - - - - 7612dc71 by Krzysztof Gogolewski at 2023-02-04T04:13:34-05:00 Minor refactor * Introduce refactorDupsOn f = refactorDups (comparing f) * Make mkBigTupleCase and coreCaseTuple monadic. Every call to those functions was preceded by calling newUniqueSupply. * Use mkUserLocalOrCoVar, which is equivalent to combining mkLocalIdOrCoVar with mkInternalName. - - - - - 5a54ac0b by Bodigrim at 2023-02-04T18:48:32-05:00 Fix colors in emacs terminal - - - - - 3c0f0c6d by Bodigrim at 2023-02-04T18:49:11-05:00 base changelog: move entries which were not backported to ghc-9.6 to base-4.19 section - - - - - b18fbf52 by Josh Meredith at 2023-02-06T07:47:57+00:00 Update JavaScript fileStat to match Emscripten layout - - - - - 6636b670 by Sylvain Henry at 2023-02-06T09:43:21-05:00 JS: replace "js" architecture with "javascript" Despite Cabal supporting any architecture name, `cabal --check` only supports a few built-in ones. Sadly `cabal --check` is used by Hackage hence using any non built-in name in a package (e.g. `arch(js)`) is rejected and the package is prevented from being uploaded on Hackage. Luckily built-in support for the `javascript` architecture was added for GHCJS a while ago. In order to allow newer `base` to be uploaded on Hackage we make the switch from `js` to `javascript` architecture. Fixes #22740. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 77a8234c by Luite Stegeman at 2023-02-06T09:43:59-05:00 Fix marking async exceptions in the JS backend Async exceptions are posted as a pair of the exception and the thread object. This fixes the marking pass to correctly follow the two elements of the pair. Potentially fixes #22836 - - - - - 3e09cf82 by Jan Hrček at 2023-02-06T09:44:38-05:00 Remove extraneous word in Roles user guide - - - - - b17fb3d9 by sheaf at 2023-02-07T10:51:33-05:00 Don't allow . in overloaded labels This patch removes . from the list of allowed characters in a non-quoted overloaded label, as it was realised this steals syntax, e.g. (#.). Users who want this functionality will have to add quotes around the label, e.g. `#"17.28"`. Fixes #22821 - - - - - 5dce04ee by romes at 2023-02-07T10:52:10-05:00 Update kinds in comments in GHC.Core.TyCon Use `Type` instead of star kind (*) Fix comment with incorrect kind * to have kind `Constraint` - - - - - 92916194 by Ben Gamari at 2023-02-07T10:52:48-05:00 Revert "Use fix-sized equality primops for fixed size boxed types" This reverts commit 024020c38126f3ce326ff56906d53525bc71690c. This was never applied to master/9.6 originally. See #20405 for why using these primops is a bad idea. (cherry picked from commit b1d109ad542e4c37ae5af6ace71baf2cb509d865) - - - - - c1670c6b by Sylvain Henry at 2023-02-07T21:25:18-05:00 JS: avoid head/tail and unpackFS - - - - - a9912de7 by Krzysztof Gogolewski at 2023-02-07T21:25:53-05:00 testsuite: Fix Python warnings (#22856) - - - - - 9ee761bf by sheaf at 2023-02-08T14:40:40-05:00 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 - - - - - 7eac2468 by Matthew Pickering at 2023-02-08T14:41:17-05:00 Revert "Don't keep exit join points so much" This reverts commit caced75765472a1a94453f2e5a439dba0d04a265. It seems the patch "Don't keep exit join points so much" is causing wide-spread regressions in the bytestring library benchmarks. If I revert it then the 9.6 numbers are better on average than 9.4. See https://gitlab.haskell.org/ghc/ghc/-/issues/22893#note_479525 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T12150 T13386 T13719 T21839c T3294 parsing001 ------------------------- - - - - - 633f2799 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: remove config.use_threads This patch simplifies the testsuite driver by removing the use_threads config field. It's just a degenerate case of threads=1. - - - - - ca6673e3 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: use concurrent.futures.ThreadPoolExecutor in the driver The testsuite driver used to create one thread per test case, and explicitly use semaphore and locks for rate limiting and synchronization. This is a bad practice in any language, and occasionally may result in livelock conditions (e.g. #22889). This patch uses concurrent.futures.ThreadPoolExecutor for scheduling test case runs, which is simpler and more robust. - - - - - f22cce70 by Alan Zimmerman at 2023-02-08T18:42:51-05:00 EPA: Comment between module and where should be in header comments Do not apply the heuristic to associate a comment with a prior declaration for the first declaration in the file. Closes #22919 - - - - - d69ecac2 by Josh Meredith at 2023-02-09T03:24:05-05:00 JS generated refs: update testsuite conditions - - - - - 2ea1a6bc by sheaf at 2023-02-09T03:24:44-05:00 Bump transformers to 0.6.1.0 This allows us to avoid orphans for Foldable1 instances, fixing #22898. Updates transformers submodule. - - - - - d9d0c28d by konsumlamm at 2023-02-09T14:07:48-05:00 Update `Data.List.singleton` doc comment - - - - - fe9cd6ef by Ben Gamari at 2023-02-09T14:08:23-05:00 gitlab-template: Emphasize `user facing` label My sense is that the current mention of the ~"user facing" label is overlooked by many MR authors. Let's move this point up in the list to make it more likely that it is seen. Also rephrase some of the points. - - - - - e45eb828 by Simon Peyton Jones at 2023-02-10T06:51:28-05:00 Refactor the simplifier a bit to fix #22761 The core change in this commit, which fixes #22761, is that * In a Core rule, ru_rhs is always occ-analysed. This means adding a couple of calls to occurAnalyseExpr when building a Rule, in * GHC.Core.Rules.mkRule * GHC.Core.Opt.Simplify.Iteration.simplRules But diagosing the bug made me stare carefully at the code of the Simplifier, and I ended up doing some only-loosely-related refactoring. * I think that RULES could be lost because not every code path did addBndrRules * The code around lambdas was very convoluted It's mainly moving deck chairs around, but I like it more now. - - - - - 11e0cacb by Rebecca Turner at 2023-02-10T06:52:09-05:00 Detect the `mold` linker Enables support for the `mold` linker by rui314. - - - - - 59556235 by parsonsmatt at 2023-02-10T09:53:11-05:00 Add Lift instance for Fixed - - - - - c44e5f30 by Sylvain Henry at 2023-02-10T09:53:51-05:00 Testsuite: decrease length001 timeout for JS (#22921) - - - - - 133516af by Zubin Duggal at 2023-02-10T09:54:27-05:00 compiler: Use NamedFieldPuns for `ModIface_` and `ModIfaceBackend` `NFData` instances This is a minor refactor that makes it easy to add and remove fields from `ModIface_` and `ModIfaceBackend`. Also change the formatting to make it clear exactly which fields are fully forced with `rnf` - - - - - 1e9eac1c by Matthew Pickering at 2023-02-13T11:36:41+01:00 Refresh profiling docs I went through the whole of the profiling docs and tried to amend them to reflect current best practices and tooling. In particular I removed some old references to tools such as hp2any and replaced them with references to eventlog2html. - - - - - da208b9a by Matthew Pickering at 2023-02-13T11:36:41+01:00 docs: Add section about profiling and foreign calls Previously there was no documentation for how foreign calls interacted with the profiler. This can be quite confusing for users so getting it into the user guide is the first step to a potentially better solution. See the ticket for more insightful discussion. Fixes #21764 - - - - - 081640f1 by Bodigrim at 2023-02-13T12:51:52-05:00 Document that -fproc-alignment was introduced only in GHC 8.6 - - - - - 16adc349 by Sven Tennie at 2023-02-14T11:26:31-05:00 Add clangd flag to include generated header files This enables clangd to correctly check C files that import Rts.h. (The added include directory contains ghcautoconf.h et. al.) - - - - - c399ccd9 by amesgen at 2023-02-14T11:27:14-05:00 Mention new `Foreign.Marshal.Pool` implementation in User's Guide - - - - - b9282cf7 by Ben Gamari at 2023-02-14T11:27:50-05:00 upload_ghc_libs: More control over which packages to operate on Here we add a `--skip` flag to `upload_ghc_libs`, making it easier to limit which packages to upload. This is often necessary when one package is not uploadable (e.g. see #22740). - - - - - aa3a262d by PHO at 2023-02-14T11:28:29-05:00 Assume platforms support rpaths if they use either ELF or Mach-O Not only Linux, Darwin, and FreeBSD support rpaths. Determine the usability of rpaths based on the object format, not on OS. - - - - - 47716024 by PHO at 2023-02-14T11:29:09-05:00 RTS linker: Improve compatibility with NetBSD 1. Hint address to NetBSD mmap(2) has a different semantics from that of Linux. When a hint address is provided, mmap(2) searches for a free region at or below the hint but *never* above it. This means we can't reliably search for free regions incrementally on the userland, especially when ASLR is enabled. Let the kernel do it for us if we don't care where the mapped address is going to be. 2. NetBSD not only hates to map pages as rwx, but also disallows to switch pages from rw- to r-x unless the intention is declared when pages are initially requested. This means we need a new MemoryAccess mode for pages that are going to be changed to r-x. - - - - - 11de324a by Li-yao Xia at 2023-02-14T11:29:49-05:00 base: Move changelog entry to its place - - - - - 75930424 by Ben Gamari at 2023-02-14T11:30:27-05:00 nativeGen/AArch64: Emit Atomic{Read,Write} inline Previously the AtomicRead and AtomicWrite operations were emitted as out-of-line calls. However, these tend to be very important for performance, especially the RELAXED case (which only exists for ThreadSanitizer checking). Fixes #22115. - - - - - d6411d6c by Andreas Klebinger at 2023-02-14T11:31:04-05:00 Fix some correctness issues around tag inference when targeting the bytecode generator. * Let binders are now always assumed untagged for bytecode. * Imported referenced are now always assumed to be untagged for bytecode. Fixes #22840 - - - - - 9fb4ca89 by sheaf at 2023-02-14T11:31:49-05:00 Introduce warning for loopy superclass solve Commit aed1974e completely re-engineered the treatment of loopy superclass dictionaries in instance declarations. Unfortunately, it has the potential to break (albeit in a rather minor way) user code. To alleviate migration concerns, this commit re-introduces the old behaviour. Any reliance on this old behaviour triggers a warning, controlled by `-Wloopy-superclass-solve`. The warning text explains that GHC might produce bottoming evidence, and provides a migration strategy. This allows us to provide a graceful migration period, alerting users when they are relying on this unsound behaviour. Fixes #22912 #22891 #20666 #22894 #22905 - - - - - 1928c7f3 by Cheng Shao at 2023-02-14T11:32:26-05:00 rts: make it possible to change mblock size on 32-bit targets The MBLOCK_SHIFT macro must be the single source of truth for defining the mblock size, and changing it should only affect performance, not correctness. This patch makes it truly possible to reconfigure mblock size, at least on 32-bit targets, by fixing places which implicitly relied on the previous MBLOCK_SHIFT constant. Fixes #22901. - - - - - 78aa3b39 by Simon Hengel at 2023-02-14T11:33:06-05:00 Update outdated references to notes - - - - - e8baecd2 by meooow25 at 2023-02-14T11:33:49-05:00 Documentation: Improve Foldable1 documentation * Explain foldrMap1, foldlMap1, foldlMap1', and foldrMap1' in greater detail, the text is mostly adapted from documentation of Foldable. * Describe foldr1, foldl1, foldl1' and foldr1' in terms of the above functions instead of redoing the full explanation. * Small updates to documentation of fold1, foldMap1 and toNonEmpty, again adapting from Foldable. * Update the foldMap1 example to lists instead of Sum since this is recommended for lazy right-associative folds. Fixes #22847 - - - - - 85a1a575 by romes at 2023-02-14T11:34:25-05:00 fix: Mark ghci Prelude import as implicit Fixes #22829 In GHCi, we were creating an import declaration for Prelude but we were not setting it as an implicit declaration. Therefore, ghci's import of Prelude triggered -Wmissing-import-lists. Adds regression test T22829 to testsuite - - - - - 3b019a7a by Cheng Shao at 2023-02-14T11:35:03-05:00 compiler: fix generateCgIPEStub for no-tables-next-to-code builds generateCgIPEStub already correctly implements the CmmTick finding logic for when tables-next-to-code is on/off, but it used the wrong predicate to decide when to switch between the two. Previously it switches based on whether the codegen is unregisterised, but there do exist registerised builds that disable tables-next-to-code! This patch corrects that problem. Fixes #22896. - - - - - 08c0822c by doyougnu at 2023-02-15T00:16:39-05:00 docs: release notes, user guide: add js backend Follow up from #21078 - - - - - 79d8fd65 by Bryan Richter at 2023-02-15T00:17:15-05:00 Allow failure in nightly-x86_64-linux-deb10-no_tntc-validate See #22343 - - - - - 9ca51f9e by Cheng Shao at 2023-02-15T00:17:53-05:00 rts: add the rts_clearMemory function This patch adds the rts_clearMemory function that does its best to zero out unused RTS memory for a wasm backend use case. See the comment above rts_clearMemory() prototype declaration for more detailed explanation. Closes #22920. - - - - - 26df73fb by Oleg Grenrus at 2023-02-15T22:20:57-05:00 Add -single-threaded flag to force single threaded rts This is the small part of implementing https://github.com/ghc-proposals/ghc-proposals/pull/240 - - - - - 631c6c72 by Cheng Shao at 2023-02-16T06:43:09-05:00 docs: add a section for the wasm backend Fixes #22658 - - - - - 1878e0bd by Bryan Richter at 2023-02-16T06:43:47-05:00 tests: Mark T12903 fragile everywhere See #21184 - - - - - b9420eac by Bryan Richter at 2023-02-16T06:43:47-05:00 Mark all T5435 variants as fragile See #22970. - - - - - df3d94bd by Sylvain Henry at 2023-02-16T06:44:33-05:00 Testsuite: mark T13167 as fragile for JS (#22921) - - - - - 324e925b by Sylvain Henry at 2023-02-16T06:45:15-05:00 JS: disable debugging info for heap objects - - - - - 518af814 by Josh Meredith at 2023-02-16T10:16:32-05:00 Factor JS Rts generation for h$c{_,0,1,2} into h$c{n} and improve name caching - - - - - 34cd308e by Ben Gamari at 2023-02-16T10:17:08-05:00 base: Note move of GHC.Stack.CCS.whereFrom to GHC.InfoProv in changelog Fixes #22883. - - - - - 12965aba by Simon Peyton Jones at 2023-02-16T10:17:46-05:00 Narrow the dont-decompose-newtype test Following #22924 this patch narrows the test that stops us decomposing newtypes. The key change is the use of noGivenNewtypeReprEqs in GHC.Tc.Solver.Canonical.canTyConApp. We went to and fro on the solution, as you can see in #22924. The result is carefully documented in Note [Decomoposing newtype equalities] On the way I had revert most of commit 3e827c3f74ef76d90d79ab6c4e71aa954a1a6b90 Author: Richard Eisenberg <rae at cs.brynmawr.edu> Date: Mon Dec 5 10:14:02 2022 -0500 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. It turns out that (a) 3e827c3f makes GHC behave worse on some recursive newtypes (see one of the tests on this commit) (b) the finer-grained test (namely noGivenNewtypeReprEqs) renders 3e827c3f unnecessary - - - - - 5b038888 by Bodigrim at 2023-02-16T10:18:24-05:00 Documentation: add an example of SPEC usage - - - - - 681e0e8c by sheaf at 2023-02-16T14:09:56-05:00 No default finalizer exception handler Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680 - - - - - b3ac17ad by Matthew Pickering at 2023-02-16T14:10:31-05:00 unicode: Don't inline bitmap in generalCategory generalCategory contains a huge literal string but is marked INLINE, this will duplicate the string into any use site of generalCategory. In particular generalCategory is used in functions like isSpace and the literal gets inlined into this function which makes it massive. https://github.com/haskell/core-libraries-committee/issues/130 Fixes #22949 ------------------------- Metric Decrease: T4029 T18304 ------------------------- - - - - - 8988eeef by sheaf at 2023-02-16T20:32:27-05:00 Expand synonyms in RoughMap We were failing to expand type synonyms in the function GHC.Core.RoughMap.typeToRoughMatchLookupTc, even though the RoughMap infrastructure crucially relies on type synonym expansion to work. This patch adds the missing type-synonym expansion. Fixes #22985 - - - - - 3dd50e2f by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Add test artifact Add the released testsuite tarball to the generated ghcup metadata. - - - - - c6a967d9 by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Use Ubuntu and Rocky bindists Prefer to use the Ubuntu 20.04 and 18.04 binary distributions on Ubuntu and Linux Mint. Prefer to use the Rocky 8 binary distribution on unknown distributions. - - - - - be0b7209 by Matthew Pickering at 2023-02-17T09:37:16+00:00 Add INLINABLE pragmas to `generic*` functions in Data.OldList These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129 - - - - - a203ad85 by Sylvain Henry at 2023-02-17T15:59:16-05:00 Merge libiserv with ghci `libiserv` serves no purpose. As it depends on `ghci` and doesn't have more dependencies than the `ghci` package, its code could live in the `ghci` package too. This commit also moves most of the code from the `iserv` program into the `ghci` package as well so that it can be reused. This is especially useful for the implementation of TH for the JS backend (#22261, !9779). - - - - - 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Bodigrim at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Bodigrim at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - 7edf681e by Ben Orchard at 2023-04-20T16:47:45+02:00 WIP: Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - 21 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - + .gitlab/gen-ci.cabal - .gitlab/gen_ci.hs - + .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/hello.hs - + .gitlab/hie.yaml - .gitlab/jobs.yaml - .gitlab/merge_request_templates/merge-request.md - + .gitlab/rel_eng/default.nix - + .gitlab/rel_eng/fetch-gitlab-artifacts/.gitignore - + .gitlab/rel_eng/fetch-gitlab-artifacts/README.mkd - + .gitlab/rel_eng/fetch-gitlab-artifacts/default.nix - + .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - + .gitlab/rel_eng/fetch-gitlab-artifacts/setup.py - + .gitlab/rel_eng/mk-ghcup-metadata/.gitignore - + .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - + .gitlab/rel_eng/mk-ghcup-metadata/default.nix The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ffbd331fd5d9fc85e37ce80e25a6c2250ea9d15d...7edf681e1f4ccb781f9cef684a86f420c647aa09 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ffbd331fd5d9fc85e37ce80e25a6c2250ea9d15d...7edf681e1f4ccb781f9cef684a86f420c647aa09 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 14:57:48 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 20 Apr 2023 10:57:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ghcup-metadata-nightly Message-ID: <644152ec4ec8d_178e744a00dea46981a4@gitlab.mail> Matthew Pickering pushed new branch wip/ghcup-metadata-nightly at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghcup-metadata-nightly You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 15:00:42 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 20 Apr 2023 11:00:42 -0400 Subject: [Git][ghc/ghc][wip/ghcup-metadata-nightly] ghcup metadata Message-ID: <6441539a70325_178e744a00dea46983e0@gitlab.mail> Matthew Pickering pushed to branch wip/ghcup-metadata-nightly at Glasgow Haskell Compiler / GHC Commits: 3e1fa4dc by GHC GitLab CI at 2023-04-20T15:59:19+01:00 ghcup metadata - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -999,7 +999,7 @@ project-version: - . ./version.sh # Download existing ghcup metadata - - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#wget -c wget "https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-0.0.7.yaml" + - nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#wget -c wget "https://gitlab.haskell.org/ghc/ghcup-metadata/-/raw/main/ghcup-0.0.7.yaml" - .gitlab/generate_job_metadata @@ -1012,42 +1012,72 @@ ghcup-metadata-nightly: extends: .ghcup-metadata # Explicit needs for validate pipeline because we only need certain bindists needs: - - job: nightly-x86_64-linux-fedora33-release - artifacts: false - - job: nightly-x86_64-linux-centos7-validate - artifacts: false - - job: nightly-x86_64-linux-ubuntu20_04-validate - artifacts: false - - job: nightly-x86_64-linux-ubuntu18_04-validate - artifacts: false - - job: nightly-x86_64-linux-rocky8-validate - artifacts: false - - job: nightly-x86_64-darwin-validate - artifacts: false - - job: nightly-aarch64-darwin-validate - artifacts: false - - job: nightly-x86_64-windows-validate - artifacts: false - - job: nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static - artifacts: false - - job: nightly-x86_64-linux-deb9-validate - artifacts: false - - job: nightly-i386-linux-deb9-validate - artifacts: false - - job: nightly-x86_64-linux-deb10-validate - artifacts: false - - job: nightly-aarch64-linux-deb10-validate - artifacts: false - - job: nightly-x86_64-linux-deb11-validate - artifacts: false - - job: source-tarball - artifacts: false + # - job: nightly-x86_64-linux-fedora33-release + # artifacts: false + # - job: nightly-x86_64-linux-centos7-validate + # artifacts: false + # - job: nightly-x86_64-linux-ubuntu20_04-validate + # artifacts: false + # - job: nightly-x86_64-linux-ubuntu18_04-validate + # artifacts: false + # - job: nightly-x86_64-linux-rocky8-validate + # artifacts: false + # - job: nightly-x86_64-darwin-validate + # artifacts: false + # - job: nightly-aarch64-darwin-validate + # artifacts: false + # - job: nightly-x86_64-windows-validate + # artifacts: false + # - job: nightly-x86_64-linux-alpine3_12-int_native-validate+fully_static + # artifacts: false + # - job: nightly-x86_64-linux-deb9-validate + # artifacts: false + # - job: nightly-i386-linux-deb9-validate + # artifacts: false + # - job: nightly-x86_64-linux-deb10-validate + # artifacts: false + # - job: nightly-aarch64-linux-deb10-validate + # artifacts: false + # - job: nightly-x86_64-linux-deb11-validate + # artifacts: false + # - job: source-tarball + # artifacts: false - job: project-version script: - - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" + # - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" + - cp ghcup-0.0.7.yaml metadata_test.yaml rules: - if: $NIGHTLY +# Update the +ghcup-metadata-nightly-push: + stage: deploy + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-fedora33:$DOCKER_REV" + dependencies: null + tags: + - x86_64-linux + variables: + BUILD_FLAVOUR: default + GIT_SUBMODULE_STRATEGY: "none" + needs: + - job: ghcup-metadata-nightly + artifacts: true + script: + - git config user.email "ghc-ci at gitlab-haskell.org" + - git config user.name "GHC GitLab CI" + - git clone git at gitlab.haskell.org:ghc/ghcup-metadata.git + - cp metadata_test.yaml ghcup-metadata/ghcup-0.0.7.yaml + - cd ghcup-metadata + - echo "" >> ghcup-0.0.7.yaml + - git remote add gitlab_origin https://oauth2:$PROJECT_PUSH_TOKEN at gitlab.haskell.org/ghc/ghcup-metadata.git + - git add . + - git commit -m "Update metadata" + - git push gitlab_origin HEAD:main -o ci.skip + rules: + - if: $NIGHTLY + # - if: $CI_PIPELINE_SOURCE == "schedule" + + ghcup-metadata-release: # No explicit needs for release pipeline as we assume we need everything and everything will pass. extends: .ghcup-metadata View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e1fa4dc78878febd243f24d7a8b7ccf26bd1b65 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e1fa4dc78878febd243f24d7a8b7ccf26bd1b65 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 15:01:23 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 11:01:23 -0400 Subject: [Git][ghc/ghc][master] hadrian: Pass haddock file arguments in a response file Message-ID: <644153c325bd_178e744a03c7407032b0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 2 changed files: - hadrian/src/Builder.hs - hadrian/src/Settings/Builders/Haddock.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock BuildPackage -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f15b0ce530bece8b242941a446fd381614bdd3cf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f15b0ce530bece8b242941a446fd381614bdd3cf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 15:02:06 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 11:02:06 -0400 Subject: [Git][ghc/ghc][master] Fix doc typo in GHC.Read.readList Message-ID: <644153eeb39b3_178e744a269ba87067c9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 1 changed file: - libraries/base/GHC/Read.hs Changes: ===================================== libraries/base/GHC/Read.hs ===================================== @@ -205,8 +205,8 @@ class Read a where -- | The method 'readList' is provided to allow the programmer to -- give a specialised way of parsing lists of values. -- For example, this is used by the predefined 'Read' instance of - -- the 'Char' type, where values of type 'String' should be are - -- expected to use double quotes, rather than square brackets. + -- the 'Char' type, where values of type 'String' are expected to + -- use double quotes, rather than square brackets. readList :: ReadS [a] -- | Proposed replacement for 'readsPrec' using new-style parsers (GHC only). View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7012ec2facc632fe4966916f797e4d1f612d7318 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7012ec2facc632fe4966916f797e4d1f612d7318 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 15:13:25 2023 From: gitlab at gitlab.haskell.org (Melanie Brown (@mixphix)) Date: Thu, 20 Apr 2023 11:13:25 -0400 Subject: [Git][ghc/ghc][wip/clc-86] qualified isn't always post Message-ID: <64415695f2180_178e744a44be58709951@gitlab.mail> Melanie Brown pushed to branch wip/clc-86 at Glasgow Haskell Compiler / GHC Commits: 1ab066c7 by Melanie Phoenix at 2023-04-20T11:13:22-04:00 qualified isn't always post - - - - - 1 changed file: - libraries/base/Control/Monad/Zip.hs Changes: ===================================== libraries/base/Control/Monad/Zip.hs ===================================== @@ -20,7 +20,7 @@ module Control.Monad.Zip where import Control.Monad (liftM, liftM2) import Data.Functor.Identity -import Data.Functor qualified +import qualified Data.Functor import Data.Monoid import Data.Ord ( Down(..) ) import Data.Proxy View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ab066c7d8155967f6cd1309981b5dcde2efa2b8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1ab066c7d8155967f6cd1309981b5dcde2efa2b8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 15:19:57 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 20 Apr 2023 11:19:57 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 50 commits: nonmoving: Disable slop-zeroing Message-ID: <6441581df924_178e744a75b9a4712283@gitlab.mail> Matthew Pickering pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - e51af4b3 by Matthew Pickering at 2023-04-20T16:19:37+01:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 61df2dd7 by romes at 2023-04-20T16:19:37+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 687c2d2b by romes at 2023-04-20T16:19:37+01:00 Validate compatibility of ghcs when loading plugins - - - - - b9f6f6d5 by romes at 2023-04-20T16:19:37+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 2ef4c3a3 by Matthew Pickering at 2023-04-20T16:19:37+01:00 Use hash-unit-ids in release jobs - - - - - 8488080c by GHC GitLab CI at 2023-04-20T16:19:37+01:00 Fix upload_ghc_libs glob - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b46a92e80d0b04dee969a27361dc2435105224b1...8488080c632408d2397f9f129078f579e61e8652 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b46a92e80d0b04dee969a27361dc2435105224b1...8488080c632408d2397f9f129078f579e61e8652 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 16:46:25 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Thu, 20 Apr 2023 12:46:25 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] Deleted 1 commit: Let ghc-heap depend on the current GHC / RTS version Message-ID: <64416c6165865_178e744c1f6da47218a7@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: 87f9b668 by Sven Tennie at 2023-04-20T06:41:12+00:00 Let ghc-heap depend on the current GHC / RTS version It strongly depends on the structures in the RTS. Being compatible to other GHC versions introduces a lot of preprocessor special-case macros. - - - - - 12 changed files: - compiler/ghc.cabal.in - hadrian/src/Packages.hs - hadrian/src/Settings/Default.hs - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc - libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/PeekProfInfo_ProfilingEnabled.hsc - libraries/ghc-heap/GHC/Exts/Stack.hs - libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/ghc-heap.cabal.in - libraries/ghci/ghci.cabal.in Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -87,7 +87,8 @@ Library exceptions == 0.10.*, stm, ghc-boot == @ProjectVersionMunged@, - ghc-heap == @ProjectVersionMunged@, + -- in-tree used for Stage >= 1, pre-built for Stage0 + ghc-heap, ghci == @ProjectVersionMunged@ if os(windows) ===================================== hadrian/src/Packages.hs ===================================== @@ -53,13 +53,20 @@ isGhcPackage = (`elem` ghcPackages) array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, countDeps, compareSizes, compiler, containers, deepseq, deriveConstants, directory, exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, - ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, + ghcCompact, ghcConfig, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, parsec, pretty, primitive, process, rts, runGhc, stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace :: Package + +-- | `Package` of the @ghc-heap@ library +-- +-- N.B.: As it strongly depends on structures of the RTS, needs to be built with +-- the GHC version to be built (>= @Stage1@) +ghcHeap:: Package + array = lib "array" base = lib "base" binary = lib "binary" ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -77,7 +77,6 @@ stage0Packages = do , cabalSyntax , cabal , compiler - , containers , directory , process , exceptions @@ -86,7 +85,6 @@ stage0Packages = do , runGhc , ghcBoot , ghcBootTh - , ghcHeap , ghci , ghcPkg , haddock @@ -132,6 +130,7 @@ stage1Packages = do , deepseq , exceptions , ghc + , ghcHeap , ghcBignum , ghcCompact , ghcPkg ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -88,18 +88,10 @@ class HasHeapRep (a :: TYPE rep) where -> IO Closure -- ^ Heap representation of the closure. -#if __GLASGOW_HASKELL__ >= 901 instance HasHeapRep (a :: TYPE ('BoxedRep 'Lifted)) where -#else -instance HasHeapRep (a :: TYPE 'LiftedRep) where -#endif getClosureData = getClosureDataFromHeapObject -#if __GLASGOW_HASKELL__ >= 901 instance HasHeapRep (a :: TYPE ('BoxedRep 'Unlifted)) where -#else -instance HasHeapRep (a :: TYPE 'UnliftedRep) where -#endif getClosureData x = getClosureDataFromHeapObject (unsafeCoerce# x) instance Int# ~ a => HasHeapRep (a :: TYPE 'IntRep) where @@ -369,9 +361,7 @@ getClosureDataFromHeapRepPrim getConDesc decodeCCS itbl heapRep pts = do { info = itbl , stack_size = FFIClosures.stack_size fields , stack_dirty = FFIClosures.stack_dirty fields -#if __GLASGOW_HASKELL__ >= 811 , stack_marking = FFIClosures.stack_marking fields -#endif }) | otherwise -> fail $ "Expected 0 ptr argument to STACK, found " ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -302,9 +302,7 @@ data GenClosure b { info :: !StgInfoTable , stack_size :: !Word32 -- ^ stack size in *words* , stack_dirty :: !Word8 -- ^ non-zero => dirty -#if __GLASGOW_HASKELL__ >= 811 , stack_marking :: !Word8 -#endif } ------------------------------------------------------------ ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc ===================================== @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module GHC.Exts.Heap.FFIClosures_ProfilingEnabled where @@ -99,9 +98,7 @@ unset bitMask w = w `xor` bitMask data StackFields = StackFields { stack_size :: Word32, stack_dirty :: Word8, -#if __GLASGOW_HASKELL__ >= 811 stack_marking :: Word8, -#endif stack_sp :: Addr## } @@ -110,9 +107,7 @@ peekStackFields :: Ptr a -> IO StackFields peekStackFields ptr = do stack_size' <- (#peek struct StgStack_, stack_size) ptr ::IO Word32 dirty' <- (#peek struct StgStack_, dirty) ptr -#if __GLASGOW_HASKELL__ >= 811 marking' <- (#peek struct StgStack_, marking) ptr -#endif Ptr sp' <- (#peek struct StgStack_, sp) ptr -- TODO decode the stack. @@ -120,8 +115,6 @@ peekStackFields ptr = do return StackFields { stack_size = stack_size', stack_dirty = dirty', -#if __GLASGOW_HASKELL__ >= 811 stack_marking = marking', -#endif stack_sp = sp' } ===================================== libraries/ghc-heap/GHC/Exts/Heap/ProfInfo/PeekProfInfo_ProfilingEnabled.hsc ===================================== @@ -6,10 +6,6 @@ module GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled( , peekTopCCS ) where -#if __GLASGOW_HASKELL__ >= 811 - --- See [hsc and CPP workaround] - #define PROFILING #include "Rts.h" @@ -158,16 +154,3 @@ peekIndexTable loopBreakers costCenterCacheRef ptr = do -- | casts a @Ptr@ to an @Int@ ptrToInt :: Ptr a -> Int ptrToInt (Ptr a##) = I## (addr2Int## a##) - -#else -import Prelude -import Foreign - -import GHC.Exts.Heap.ProfInfo.Types - -peekStgTSOProfInfo :: (Ptr b -> IO (Maybe CostCentreStack)) -> Ptr a -> IO (Maybe StgTSOProfInfo) -peekStgTSOProfInfo _ _ = return Nothing - -peekTopCCS :: Ptr a -> IO (Maybe CostCentreStack) -peekTopCCS _ = return Nothing -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack.hs ===================================== @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -#if MIN_TOOL_VERSION_ghc(9,7,0) {-# LANGUAGE RecordWildCards #-} module GHC.Exts.Stack @@ -28,7 +26,3 @@ stackFrameSize (RetBCO {..}) = sizeStgClosure + 1 + length bcoArgs -- The one additional word is a pointer to the next stack chunk stackFrameSize (UnderflowFrame {}) = sizeStgClosure + 1 stackFrameSize _ = error "Unexpected stack frame type" - -#else -module GHC.Exts.Stack where -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack/Constants.hsc ===================================== @@ -1,10 +1,7 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module GHC.Exts.Stack.Constants where -#if MIN_TOOL_VERSION_ghc(9,7,0) - import Prelude #include "Rts.h" @@ -126,5 +123,3 @@ bytesToWords b = bytesInWord :: Int bytesInWord = (#const SIZEOF_VOID_P) - -#endif ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -#if MIN_TOOL_VERSION_ghc(9,7,0) {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleInstances #-} @@ -458,7 +456,3 @@ decodeStack (StackSnapshot stack#) = do go :: Maybe StackFrameLocation -> [StackFrameLocation] go Nothing = [] go (Just r) = r : go (advanceStackFrameLocation r) - -#else -module GHC.Exts.Stack.Decode where -#endif ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -12,7 +12,7 @@ description: and retrieving information about those data structures. build-type: Simple -tested-with: GHC==7.11 +tested-with: GHC==@ProjectVersionMunged@ source-repository head type: git ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -80,7 +80,8 @@ library deepseq == 1.4.*, filepath == 1.4.*, ghc-boot == @ProjectVersionMunged@, - ghc-heap == @ProjectVersionMunged@, + -- in-tree used for Stage >= 1, pre-built for Stage0 + ghc-heap, template-haskell == 2.20.*, transformers >= 0.5 && < 0.7 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f9b66867832399e4fd18459d617f2fc7c493e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87f9b66867832399e4fd18459d617f2fc7c493e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 17:03:40 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 13:03:40 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: hadrian: Pass haddock file arguments in a response file Message-ID: <6441706c56fe_178e744ca408d472593c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 4cdea53a by sheaf at 2023-04-20T13:03:25-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 53c52433 by Ben Gamari at 2023-04-20T13:03:26-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 12497eb9 by Ben Gamari at 2023-04-20T13:03:26-04:00 testsuite: Add test for #23071 - - - - - 20 changed files: - .gitmodules - cabal.project-reinstall - compiler/GHC/Driver/Make.hs - + compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Session.hs - compiler/ghc.cabal.in - docs/users_guide/9.8.1-notes.rst - docs/users_guide/using.rst - hadrian/src/Builder.hs - hadrian/src/Packages.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Builders/Haddock.hs - hadrian/src/Settings/Default.hs - libraries/base/GHC/Read.hs - + libraries/semaphore-compat - packages - rts/Threads.c - + testsuite/tests/primops/should_run/T23071.hs - testsuite/tests/primops/should_run/all.T Changes: ===================================== .gitmodules ===================================== @@ -83,6 +83,10 @@ url = https://gitlab.haskell.org/ghc/packages/unix.git ignore = untracked branch = 2.7 +[submodule "libraries/semaphore-compat"] + path = libraries/semaphore-compat + url = https://gitlab.haskell.org/ghc/semaphore-compat.git + ignore = untracked [submodule "libraries/stm"] path = libraries/stm url = https://gitlab.haskell.org/ghc/packages/stm.git ===================================== cabal.project-reinstall ===================================== @@ -28,6 +28,7 @@ packages: ./compiler ./libraries/parsec/ -- ./libraries/pretty/ ./libraries/process/ + ./libraries/semaphore-compat ./libraries/stm -- ./libraries/template-haskell/ ./libraries/terminfo/ ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -75,6 +75,7 @@ import GHC.Driver.Env import GHC.Driver.Errors import GHC.Driver.Errors.Types import GHC.Driver.Main +import GHC.Driver.MakeSem import GHC.Parser.Header @@ -151,10 +152,10 @@ import GHC.Runtime.Loader import GHC.Rename.Names import GHC.Utils.Constants import GHC.Types.Unique.DFM (udfmRestrictKeysSet) -import qualified Data.IntSet as I import GHC.Types.Unique import GHC.Iface.Errors.Types +import qualified Data.IntSet as I -- ----------------------------------------------------------------------------- -- Loading the program @@ -664,6 +665,30 @@ createBuildPlan mod_graph maybe_top_mod = (vcat [text "Build plan missing nodes:", (text "PLAN:" <+> ppr (sum (map countMods build_plan))), (text "GRAPH:" <+> ppr (length (mgModSummaries' mod_graph )))]) build_plan +mkWorkerLimit :: DynFlags -> IO WorkerLimit +mkWorkerLimit dflags = + case parMakeCount dflags of + Nothing -> pure $ num_procs 1 + Just (ParMakeSemaphore h) -> pure (JSemLimit (SemaphoreName h)) + Just ParMakeNumProcessors -> num_procs <$> getNumProcessors + Just (ParMakeThisMany n) -> pure $ num_procs n + where + num_procs x = NumProcessorsLimit (max 1 x) + +isWorkerLimitSequential :: WorkerLimit -> Bool +isWorkerLimitSequential (NumProcessorsLimit x) = x <= 1 +isWorkerLimitSequential (JSemLimit {}) = False + +-- | This describes what we use to limit the number of jobs, either we limit it +-- ourselves to a specific number or we have an external parallelism semaphore +-- limit it for us. +data WorkerLimit + = NumProcessorsLimit Int + | JSemLimit + SemaphoreName + -- ^ Semaphore name to use + deriving Eq + -- | Generalized version of 'load' which also supports a custom -- 'Messager' (for reporting progress) and 'ModuleGraph' (generally -- produced by calling 'depanal'. @@ -744,14 +769,12 @@ load' mhmi_cache how_much mHscMessage mod_graph = do liftIO $ debugTraceMsg logger 2 (hang (text "Ready for upsweep") 2 (ppr build_plan)) - n_jobs <- case parMakeCount (hsc_dflags hsc_env) of - Nothing -> liftIO getNumProcessors - Just n -> return n + worker_limit <- liftIO $ mkWorkerLimit dflags setSession $ hscUpdateHUG (unitEnv_map pruneHomeUnitEnv) hsc_env (upsweep_ok, hsc_env1) <- withDeferredDiagnostics $ do hsc_env <- getSession - liftIO $ upsweep n_jobs hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan + liftIO $ upsweep worker_limit hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan setSession hsc_env1 case upsweep_ok of Failed -> loadFinish upsweep_ok @@ -1036,13 +1059,7 @@ getDependencies direct_deps build_map = type BuildM a = StateT BuildLoopState IO a --- | Abstraction over the operations of a semaphore which allows usage with the --- -j1 case -data AbstractSem = AbstractSem { acquireSem :: IO () - , releaseSem :: IO () } -withAbstractSem :: AbstractSem -> IO b -> IO b -withAbstractSem sem = MC.bracket_ (acquireSem sem) (releaseSem sem) -- | Environment used when compiling a module data MakeEnv = MakeEnv { hsc_env :: !HscEnv -- The basic HscEnv which will be augmented for each module @@ -1227,7 +1244,7 @@ withCurrentUnit uid = do local (\env -> env { hsc_env = hscSetActiveUnitId uid (hsc_env env)}) upsweep - :: Int -- ^ The number of workers we wish to run in parallel + :: WorkerLimit -- ^ The number of workers we wish to run in parallel -> HscEnv -- ^ The base HscEnv, which is augmented for each module -> Maybe ModIfaceCache -- ^ A cache to incrementally write final interface files to -> Maybe Messager @@ -2832,7 +2849,7 @@ label_self thread_name = do CC.labelThread self_tid thread_name -runPipelines :: Int -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () +runPipelines :: WorkerLimit -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () -- Don't even initialise plugins if there are no pipelines runPipelines _ _ _ [] = return () runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do @@ -2840,7 +2857,7 @@ runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do plugins_hsc_env <- initializePlugins orig_hsc_env case n_job of - 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines + NumProcessorsLimit n | n <= 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines _n -> runParPipelines n_job plugins_hsc_env mHscMessager all_pipelines runSeqPipelines :: HscEnv -> Maybe Messager -> [MakeAction] -> IO () @@ -2850,16 +2867,38 @@ runSeqPipelines plugin_hsc_env mHscMessager all_pipelines = , compile_sem = AbstractSem (return ()) (return ()) , env_messager = mHscMessager } - in runAllPipelines 1 env all_pipelines + in runAllPipelines (NumProcessorsLimit 1) env all_pipelines +runNjobsAbstractSem :: Int -> (AbstractSem -> IO a) -> IO a +runNjobsAbstractSem n_jobs action = do + compile_sem <- newQSem n_jobs + n_capabilities <- getNumCapabilities + n_cpus <- getNumProcessors + let + asem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + set_num_caps n = unless (n_capabilities /= 1) $ setNumCapabilities n + updNumCapabilities = do + -- Setting number of capabilities more than + -- CPU count usually leads to high userspace + -- lock contention. #9221 + set_num_caps $ min n_jobs n_cpus + resetNumCapabilities = set_num_caps n_capabilities + MC.bracket_ updNumCapabilities resetNumCapabilities $ action asem + +runWorkerLimit :: WorkerLimit -> (AbstractSem -> IO a) -> IO a +runWorkerLimit worker_limit action = case worker_limit of + NumProcessorsLimit n_jobs -> + runNjobsAbstractSem n_jobs action + JSemLimit sem -> + runJSemAbstractSem sem action -- | Build and run a pipeline -runParPipelines :: Int -- ^ How many capabilities to use - -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module +runParPipelines :: WorkerLimit -- ^ How to limit work parallelism + -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module -> Maybe Messager -- ^ Optional custom messager to use to report progress -> [MakeAction] -- ^ The build plan for all the module nodes -> IO () -runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do +runParPipelines worker_limit plugin_hsc_env mHscMessager all_pipelines = do -- A variable which we write to when an error has happened and we have to tell the @@ -2869,39 +2908,23 @@ runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do -- will add it's LogQueue into this queue. log_queue_queue_var <- newTVarIO newLogQueueQueue -- Thread which coordinates the printing of logs - wait_log_thread <- logThread n_jobs (length all_pipelines) (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var + wait_log_thread <- logThread (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var -- Make the logger thread-safe, in case there is some output which isn't sent via the LogQueue. thread_safe_logger <- liftIO $ makeThreadSafe (hsc_logger plugin_hsc_env) let thread_safe_hsc_env = plugin_hsc_env { hsc_logger = thread_safe_logger } - let updNumCapabilities = liftIO $ do - n_capabilities <- getNumCapabilities - n_cpus <- getNumProcessors - -- Setting number of capabilities more than - -- CPU count usually leads to high userspace - -- lock contention. #9221 - let n_caps = min n_jobs n_cpus - unless (n_capabilities /= 1) $ setNumCapabilities n_caps - return n_capabilities - - let resetNumCapabilities orig_n = do - liftIO $ setNumCapabilities orig_n - atomically $ writeTVar stopped_var True - wait_log_thread - - compile_sem <- newQSem n_jobs - let abstract_sem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + runWorkerLimit worker_limit $ \abstract_sem -> do + let env = MakeEnv { hsc_env = thread_safe_hsc_env + , withLogger = withParLog log_queue_queue_var + , compile_sem = abstract_sem + , env_messager = mHscMessager + } -- Reset the number of capabilities once the upsweep ends. - let env = MakeEnv { hsc_env = thread_safe_hsc_env - , withLogger = withParLog log_queue_queue_var - , compile_sem = abstract_sem - , env_messager = mHscMessager - } - - MC.bracket updNumCapabilities resetNumCapabilities $ \_ -> - runAllPipelines n_jobs env all_pipelines + runAllPipelines worker_limit env all_pipelines + atomically $ writeTVar stopped_var True + wait_log_thread withLocalTmpFS :: RunMakeM a -> RunMakeM a withLocalTmpFS act = do @@ -2918,10 +2941,11 @@ withLocalTmpFS act = do MC.bracket initialiser finaliser $ \lcl_hsc_env -> local (\env -> env { hsc_env = lcl_hsc_env}) act -- | Run the given actions and then wait for them all to finish. -runAllPipelines :: Int -> MakeEnv -> [MakeAction] -> IO () -runAllPipelines n_jobs env acts = do - let spawn_actions :: IO [ThreadId] - spawn_actions = if n_jobs == 1 +runAllPipelines :: WorkerLimit -> MakeEnv -> [MakeAction] -> IO () +runAllPipelines worker_limit env acts = do + let single_worker = isWorkerLimitSequential worker_limit + spawn_actions :: IO [ThreadId] + spawn_actions = if single_worker then (:[]) <$> (forkIOWithUnmask $ \unmask -> void $ runLoop (\io -> io unmask) env acts) else runLoop forkIOWithUnmask env acts ===================================== compiler/GHC/Driver/MakeSem.hs ===================================== @@ -0,0 +1,545 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE NumericUnderscores #-} + +-- | Implementation of a jobserver using system semaphores. +-- +-- +module GHC.Driver.MakeSem + ( -- * JSem: parallelism semaphore backed + -- by a system semaphore (Posix/Windows) + runJSemAbstractSem + + -- * System semaphores + , Semaphore, SemaphoreName(..) + + -- * Abstract semaphores + , AbstractSem(..) + , withAbstractSem + ) + where + +import GHC.Prelude +import GHC.Conc +import GHC.Data.OrdList +import GHC.IO.Exception +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Utils.Json + +import System.Semaphore + +import Control.Monad +import qualified Control.Monad.Catch as MC +import Control.Concurrent.MVar +import Control.Concurrent.STM +import Data.Foldable +import Data.Functor +import GHC.Stack +import Debug.Trace + +--------------------------------------- +-- Semaphore jobserver + +-- | A jobserver based off a system 'Semaphore'. +-- +-- Keeps track of the pending jobs and resources +-- available from the semaphore. +data Jobserver + = Jobserver + { jSemaphore :: !Semaphore + -- ^ The semaphore which controls available resources + , jobs :: !(TVar JobResources) + -- ^ The currently pending jobs, and the resources + -- obtained from the semaphore + } + +data JobserverOptions + = JobserverOptions + { releaseDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between acquiring a token + -- and releasing a token. + , setNumCapsDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between two consecutive + -- calls of 'setNumCapabilities'. + } + +defaultJobserverOptions :: JobserverOptions +defaultJobserverOptions = + JobserverOptions + { releaseDebounce = 1000 -- 1 second + , setNumCapsDebounce = 1000 -- 1 second + } + +-- | Resources available for running jobs, i.e. +-- tokens obtained from the parallelism semaphore. +data JobResources + = Jobs + { tokensOwned :: !Int + -- ^ How many tokens have been claimed from the semaphore + , tokensFree :: !Int + -- ^ How many tokens are not currently being used + , jobsWaiting :: !(OrdList (TMVar ())) + -- ^ Pending jobs waiting on a token, the job will be blocked on the TMVar so putting into + -- the TMVar will allow the job to continue. + } + +instance Outputable JobResources where + ppr Jobs{..} + = text "JobResources" <+> + ( braces $ hsep + [ text "owned=" <> ppr tokensOwned + , text "free=" <> ppr tokensFree + , text "num_waiting=" <> ppr (length jobsWaiting) + ] ) + +-- | Add one new token. +addToken :: JobResources -> JobResources +addToken jobs@( Jobs { tokensOwned = owned, tokensFree = free }) + = jobs { tokensOwned = owned + 1, tokensFree = free + 1 } + +-- | Free one token. +addFreeToken :: JobResources -> JobResources +addFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (tokensOwned jobs > free) + (text "addFreeToken:" <+> ppr (tokensOwned jobs) <+> ppr free) + $ jobs { tokensFree = free + 1 } + +-- | Use up one token. +removeFreeToken :: JobResources -> JobResources +removeFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (free > 0) + (text "removeFreeToken:" <+> ppr free) + $ jobs { tokensFree = free - 1 } + +-- | Return one owned token. +removeOwnedToken :: JobResources -> JobResources +removeOwnedToken jobs@( Jobs { tokensOwned = owned }) + = assertPpr (owned > 1) + (text "removeOwnedToken:" <+> ppr owned) + $ jobs { tokensOwned = owned - 1 } + +-- | Add one new job to the end of the list of pending jobs. +addJob :: TMVar () -> JobResources -> JobResources +addJob job jobs@( Jobs { jobsWaiting = wait }) + = jobs { jobsWaiting = wait `SnocOL` job } + +-- | The state of the semaphore job server. +data JobserverState + = JobserverState + { jobserverAction :: !JobserverAction + -- ^ The current action being performed by the + -- job server. + , canChangeNumCaps :: !(TVar Bool) + -- ^ A TVar that signals whether it has been long + -- enough since we last changed 'numCapabilities'. + , canReleaseToken :: !(TVar Bool) + -- ^ A TVar that signals whether we last acquired + -- a token long enough ago that we can now release + -- a token. + } +data JobserverAction + -- | The jobserver is idle: no thread is currently + -- interacting with the semaphore. + = Idle + -- | A thread is waiting for a token on the semaphore. + | Acquiring + { activeWaitId :: WaitId + , threadFinished :: TMVar (Maybe MC.SomeException) } + +-- | Retrieve the 'TMVar' that signals if the current thread has finished, +-- if any thread is currently active in the jobserver. +activeThread_maybe :: JobserverAction -> Maybe (TMVar (Maybe MC.SomeException)) +activeThread_maybe Idle = Nothing +activeThread_maybe (Acquiring { threadFinished = tmvar }) = Just tmvar + +-- | Whether we should try to acquire a new token from the semaphore: +-- there is a pending job and no free tokens. +guardAcquire :: JobResources -> Bool +guardAcquire ( Jobs { tokensFree, jobsWaiting } ) + = tokensFree == 0 && not (null jobsWaiting) + +-- | Whether we should release a token from the semaphore: +-- there are no pending jobs and we can release a token. +guardRelease :: JobResources -> Bool +guardRelease ( Jobs { tokensFree, tokensOwned, jobsWaiting } ) + = null jobsWaiting && tokensFree > 0 && tokensOwned > 1 + +--------------------------------------- +-- Semaphore jobserver implementation + +-- | Add one pending job to the jobserver. +-- +-- Blocks, waiting on the jobserver to supply a free token. +acquireJob :: TVar JobResources -> IO () +acquireJob jobs_tvar = do + (job_tmvar, _jobs0) <- tracedAtomically "acquire" $ + modifyJobResources jobs_tvar \ jobs -> do + job_tmvar <- newEmptyTMVar + return ((job_tmvar, jobs), addJob job_tmvar jobs) + atomically $ takeTMVar job_tmvar + +-- | Signal to the job server that one job has completed, +-- releasing its corresponding token. +releaseJob :: TVar JobResources -> IO () +releaseJob jobs_tvar = do + tracedAtomically "release" do + modifyJobResources jobs_tvar \ jobs -> do + massertPpr (tokensFree jobs < tokensOwned jobs) + (text "releaseJob: more free jobs than owned jobs!") + return ((), addFreeToken jobs) + + +-- | Release all tokens owned from the semaphore (to clean up +-- the jobserver at the end). +cleanupJobserver :: Jobserver -> IO () +cleanupJobserver (Jobserver { jSemaphore = sem + , jobs = jobs_tvar }) + = do + Jobs { tokensOwned = owned } <- readTVarIO jobs_tvar + let toks_to_release = owned - 1 + -- Subtract off the implicit token: whoever spawned the ghc process + -- in the first place is responsible for that token. + releaseSemaphore sem toks_to_release + +-- | Dispatch the available tokens acquired from the semaphore +-- to the pending jobs in the job server. +dispatchTokens :: JobResources -> STM JobResources +dispatchTokens jobs@( Jobs { tokensFree = toks_free, jobsWaiting = wait } ) + | toks_free > 0 + , next `ConsOL` rest <- wait + -- There's a pending job and a free token: + -- pass on the token to that job, and recur. + = do + putTMVar next () + let jobs' = jobs { tokensFree = toks_free - 1, jobsWaiting = rest } + dispatchTokens jobs' + | otherwise + = return jobs + +-- | Update the available resources used from a semaphore, dispatching +-- any newly acquired resources. +-- +-- Invariant: if the number of available resources decreases, there +-- must be no pending jobs. +-- +-- All modifications should go through this function to ensure the contents +-- of the 'TVar' remains in normal form. +modifyJobResources :: HasCallStack => TVar JobResources + -> (JobResources -> STM (a, JobResources)) + -> STM (a, Maybe JobResources) +modifyJobResources jobs_tvar action = do + old_jobs <- readTVar jobs_tvar + (a, jobs) <- action old_jobs + + -- Check the invariant: if the number of free tokens has decreased, + -- there must be no pending jobs. + massertPpr (null (jobsWaiting jobs) || tokensFree jobs >= tokensFree old_jobs) $ + vcat [ text "modiyJobResources: pending jobs but fewer free tokens" ] + dispatched_jobs <- dispatchTokens jobs + writeTVar jobs_tvar dispatched_jobs + return (a, Just dispatched_jobs) + + +tracedAtomically_ :: String -> STM (Maybe JobResources) -> IO () +tracedAtomically_ s act = tracedAtomically s (((),) <$> act) + +tracedAtomically :: String -> STM (a, Maybe JobResources) -> IO a +tracedAtomically origin act = do + (a, mjr) <- atomically act + forM_ mjr $ \ jr -> do + -- Use the "jsem:" prefix to identify where the write traces are + traceEventIO ("jsem:" ++ renderJobResources origin jr) + return a + +renderJobResources :: String -> JobResources -> String +renderJobResources origin (Jobs own free pending) = showSDocUnsafe $ renderJSON $ + JSObject [ ("name", JSString origin) + , ("owned", JSInt own) + , ("free", JSInt free) + , ("pending", JSInt (length pending) ) + ] + + +-- | Spawn a new thread that waits on the semaphore in order to acquire +-- an additional token. +acquireThread :: Jobserver -> IO JobserverAction +acquireThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + let + wait_result_action :: Either MC.SomeException Bool -> IO () + wait_result_action wait_res = + tracedAtomically_ "acquire_thread" do + (r, jb) <- case wait_res of + Left (e :: MC.SomeException) -> do + return $ (Just e, Nothing) + Right success -> do + if success + then do + modifyJobResources jobs_tvar \ jobs -> + return (Nothing, addToken jobs) + else + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jb + wait_id <- forkWaitOnSemaphoreInterruptible sem wait_result_action + labelThread (waitingThreadId wait_id) "acquire_thread" + return $ Acquiring { activeWaitId = wait_id + , threadFinished = threadFinished_tmvar } + +-- | Spawn a thread to release ownership of one resource from the semaphore, +-- provided we have spare resources and no pending jobs. +releaseThread :: Jobserver -> IO JobserverAction +releaseThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + MC.mask_ do + -- Pre-release the resource so that another thread doesn't take control of it + -- just as we release the lock on the semaphore. + still_ok_to_release + <- tracedAtomically "pre_release" $ + modifyJobResources jobs_tvar \ jobs -> + if guardRelease jobs + -- TODO: should this also debounce? + then return (True , removeOwnedToken $ removeFreeToken jobs) + else return (False, jobs) + if not still_ok_to_release + then return Idle + else do + tid <- forkIO $ do + x <- MC.try $ releaseSemaphore sem 1 + tracedAtomically_ "post-release" $ do + (r, jobs) <- case x of + Left (e :: MC.SomeException) -> do + modifyJobResources jobs_tvar \ jobs -> + return (Just e, addToken jobs) + Right _ -> do + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jobs + labelThread tid "release_thread" + return Idle + +-- | When there are pending jobs but no free tokens, +-- spawn a thread to acquire a new token from the semaphore. +-- +-- See 'acquireThread'. +tryAcquire :: JobserverOptions + -> Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryAcquire opts js@( Jobserver { jobs = jobs_tvar }) + st@( JobserverState { jobserverAction = Idle } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardAcquire jobs + return do + action <- acquireThread js + -- Set a debounce after acquiring a token. + can_release_tvar <- registerDelay $ (releaseDebounce opts * 1000) + return $ st { jobserverAction = action + , canReleaseToken = can_release_tvar } +tryAcquire _ _ _ = retry + +-- | When there are free tokens and no pending jobs, +-- spawn a thread to release a token from the semamphore. +-- +-- See 'releaseThread'. +tryRelease :: Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryRelease sjs@( Jobserver { jobs = jobs_tvar } ) + st@( JobserverState + { jobserverAction = Idle + , canReleaseToken = can_release_tvar } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardRelease jobs + can_release <- readTVar can_release_tvar + guard can_release + return do + action <- releaseThread sjs + return $ st { jobserverAction = action } +tryRelease _ _ = retry + +-- | Wait for an active thread to finish. Once it finishes: +-- +-- - set the 'JobserverAction' to 'Idle', +-- - update the number of capabilities to reflect the number +-- of owned tokens from the semaphore. +tryNoticeIdle :: JobserverOptions + -> TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryNoticeIdle opts jobs_tvar jobserver_state + | Just threadFinished_tmvar <- activeThread_maybe $ jobserverAction jobserver_state + = sync_num_caps (canChangeNumCaps jobserver_state) threadFinished_tmvar + | otherwise + = retry -- no active thread: wait until jobserver isn't idle + where + sync_num_caps :: TVar Bool + -> TMVar (Maybe MC.SomeException) + -> STM (IO JobserverState) + sync_num_caps can_change_numcaps_tvar threadFinished_tmvar = do + mb_ex <- takeTMVar threadFinished_tmvar + for_ mb_ex MC.throwM + Jobs { tokensOwned } <- readTVar jobs_tvar + can_change_numcaps <- readTVar can_change_numcaps_tvar + guard can_change_numcaps + return do + x <- getNumCapabilities + can_change_numcaps_tvar_2 <- + if x == tokensOwned + then return can_change_numcaps_tvar + else do + setNumCapabilities tokensOwned + registerDelay $ (setNumCapsDebounce opts * 1000) + return $ + jobserver_state + { jobserverAction = Idle + , canChangeNumCaps = can_change_numcaps_tvar_2 } + +-- | Try to stop the current thread which is acquiring/releasing resources +-- if that operation is no longer relevant. +tryStopThread :: TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryStopThread jobs_tvar jsj = do + case jobserverAction jsj of + Acquiring { activeWaitId = wait_id } -> do + jobs <- readTVar jobs_tvar + guard $ null (jobsWaiting jobs) + return do + interruptWaitOnSemaphore wait_id + return $ jsj { jobserverAction = Idle } + _ -> retry + +-- | Main jobserver loop: acquire/release resources as +-- needed for the pending jobs and available semaphore tokens. +jobserverLoop :: JobserverOptions -> Jobserver -> IO () +jobserverLoop opts sjs@(Jobserver { jobs = jobs_tvar }) + = do + true_tvar <- newTVarIO True + let init_state :: JobserverState + init_state = + JobserverState + { jobserverAction = Idle + , canChangeNumCaps = true_tvar + , canReleaseToken = true_tvar } + loop init_state + where + loop s = do + action <- atomically $ asum $ (\x -> x s) <$> + [ tryRelease sjs + , tryAcquire opts sjs + , tryNoticeIdle opts jobs_tvar + , tryStopThread jobs_tvar + ] + s <- action + loop s + +-- | Create a new jobserver using the given semaphore handle. +makeJobserver :: SemaphoreName -> IO (AbstractSem, IO ()) +makeJobserver sem_name = do + semaphore <- openSemaphore sem_name + let + init_jobs = + Jobs { tokensOwned = 1 + , tokensFree = 1 + , jobsWaiting = NilOL + } + jobs_tvar <- newTVarIO init_jobs + let + opts = defaultJobserverOptions -- TODO: allow this to be configured + sjs = Jobserver { jSemaphore = semaphore + , jobs = jobs_tvar } + loop_finished_mvar <- newEmptyMVar + loop_tid <- forkIOWithUnmask \ unmask -> do + r <- try $ unmask $ jobserverLoop opts sjs + putMVar loop_finished_mvar $ + case r of + Left e + | Just ThreadKilled <- fromException e + -> Nothing + | otherwise + -> Just e + Right () -> Nothing + labelThread loop_tid "job_server" + let + acquireSem = acquireJob jobs_tvar + releaseSem = releaseJob jobs_tvar + cleanupSem = do + -- this is interruptible + cleanupJobserver sjs + killThread loop_tid + mb_ex <- takeMVar loop_finished_mvar + for_ mb_ex MC.throwM + + return (AbstractSem{..}, cleanupSem) + +-- | Implement an abstract semaphore using a semaphore 'Jobserver' +-- which queries the system semaphore of the given name for resources. +runJSemAbstractSem :: SemaphoreName -- ^ the system semaphore to use + -> (AbstractSem -> IO a) -- ^ the operation to run + -- which requires a semaphore + -> IO a +runJSemAbstractSem sem action = MC.mask \ unmask -> do + (abs, cleanup) <- makeJobserver sem + r <- try $ unmask $ action abs + case r of + Left (e1 :: MC.SomeException) -> do + (_ :: Either MC.SomeException ()) <- MC.try cleanup + MC.throwM e1 + Right x -> cleanup $> x + +{- Note [Architecture of the Job Server] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In `-jsem` mode, the amount of parallelism that GHC can use is controlled by a +system semaphore. We take resources from the semaphore when we need them, and +give them back if we don't have enough to do. + +A naive implementation would just take and release the semaphore around performing +the action, but this leads to two issues: + +* When taking a token in the semaphore, we must call `setNumCapabilities` in order + to adjust how many capabilities are available for parallel garbage collection. + This causes unnecessary synchronisations. +* We want to implement a debounce, so that whilst there is pending work in the + current process we prefer to keep hold of resources from the semaphore. + This reduces overall memory usage, as there are fewer live GHC processes at once. + +Therefore, the obtention of semaphore resources is separated away from the +request for the resource in the driver. + +A token from the semaphore is requested using `acquireJob`. This creates a pending +job, which is a MVar that can be filled in to signal that the requested token is ready. + +When the job is finished, the token is released by calling `releaseJob`, which just +increases the number of `free` jobs. If there are more pending jobs when the free count +is increased, the token is immediately reused (see `modifyJobResources`). + +The `jobServerLoop` interacts with the system semaphore: when there are pending +jobs, `acquireThread` blocks, waiting for a token from the semaphore. Once a +token is obtained, it increases the owned count. + +When GHC has free tokens (tokens from the semaphore that it is not using), +no pending jobs, and the debounce has expired, then `releaseThread` will +release tokens back to the global semaphore. + +`tryStopThread` attempts to kill threads which are waiting to acquire a resource +when we no longer need it. For example, consider that we attempt to acquire two +tokens, but the first job finishes before we acquire the second token. +This second token is no longer needed, so we should cancel the wait +(as it would not be used to do any work, and not be returned until the debounce). +We only need to kill `acquireJob`, because `releaseJob` never blocks. + +Note [Eventlog Messages for jsem] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It can be tricky to verify that the work is shared adequately across different +processes. To help debug this, we output the values of `JobResource` to the +eventlog whenever the global state changes. There are some scripts which can be used +to analyse this output and report statistics about core saturation in the +GitHub repo (https://github.com/mpickering/ghc-jsem-analyse). + +-} ===================================== compiler/GHC/Driver/Pipeline/LogQueue.hs ===================================== @@ -100,10 +100,10 @@ dequeueLogQueueQueue (LogQueueQueue n lqq) = case IM.minViewWithKey lqq of Just ((k, v), lqq') | k == n -> Just (v, LogQueueQueue (n + 1) lqq') _ -> Nothing -logThread :: Int -> Int -> Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit +logThread :: Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit -> TVar LogQueueQueue -- Queue for logs -> IO (IO ()) -logThread _ _ logger stopped lqq_var = do +logThread logger stopped lqq_var = do finished_var <- newEmptyMVar _ <- forkIO $ print_logs *> putMVar finished_var () return (takeMVar finished_var) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Driver.Session ( needSourceNotes, OnOff(..), DynFlags(..), + ParMakeCount(..), outputFile, objectSuf, ways, FlagSpec(..), HasDynFlags(..), ContainsDynFlags(..), @@ -467,9 +468,9 @@ data DynFlags = DynFlags { ruleCheck :: Maybe String, strictnessBefore :: [Int], -- ^ Additional demand analysis - parMakeCount :: Maybe Int, -- ^ The number of modules to compile in parallel - -- in --make mode, where Nothing ==> compile as - -- many in parallel as there are CPUs. + parMakeCount :: Maybe ParMakeCount, + -- ^ The number of modules to compile in parallel + -- If unspecified, compile with a single job. enableTimeStats :: Bool, -- ^ Enable RTS timing statistics? ghcHeapSize :: Maybe Int, -- ^ The heap size to set. @@ -791,6 +792,16 @@ instance (Monad m, HasDynFlags m) => HasDynFlags (ExceptT e m) where class ContainsDynFlags t where extractDynFlags :: t -> DynFlags +-- | The type for the -jN argument, specifying that -j on its own represents +-- using the number of machine processors. +data ParMakeCount + -- | Use this many processors (@-j@ flag). + = ParMakeThisMany Int + -- | Use parallelism with as many processors as possible (@-j@ flag without an argument). + | ParMakeNumProcessors + -- | Use the specific semaphore @@ to control parallelism (@-jsem @ flag). + | ParMakeSemaphore FilePath + ----------------------------------------------------------------------------- -- Accessors from 'DynFlags' @@ -1154,7 +1165,7 @@ defaultDynFlags mySettings = historySize = 20, strictnessBefore = [], - parMakeCount = Just 1, + parMakeCount = Nothing, enableTimeStats = False, ghcHeapSize = Nothing, @@ -2120,14 +2131,16 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "j" (OptIntSuffix (\n -> case n of Just n - | n > 0 -> upd (\d -> d { parMakeCount = Just n }) + | n > 0 -> upd (\d -> d { parMakeCount = Just (ParMakeThisMany n) }) | otherwise -> addErr "Syntax: -j[n] where n > 0" - Nothing -> upd (\d -> d { parMakeCount = Nothing }))) + Nothing -> upd (\d -> d { parMakeCount = Just ParMakeNumProcessors }))) -- When the number of parallel builds -- is omitted, it is the same -- as specifying that the number of -- parallel builds is equal to the -- result of getNumProcessors + , make_ord_flag defGhcFlag "jsem" $ hasArg $ \f d -> d { parMakeCount = Just (ParMakeSemaphore f) } + , make_ord_flag defFlag "instantiated-with" (sepArg setUnitInstantiations) , make_ord_flag defFlag "this-component-id" (sepArg setUnitInstanceOf) ===================================== compiler/ghc.cabal.in ===================================== @@ -85,6 +85,7 @@ Library hpc == 0.6.*, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, + semaphore-compat, stm, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, @@ -436,6 +437,7 @@ Library GHC.Driver.GenerateCgIPEStub GHC.Driver.Hooks GHC.Driver.LlvmConfigCache + GHC.Driver.MakeSem GHC.Driver.Main GHC.Driver.Make GHC.Driver.MakeFile ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -87,6 +87,13 @@ Compiler deriving instance TypeError (Text "Boo") => Bar Baz +- GHC Proposal `#540 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0540-jsem.rst`_ has been implemented. + This adds the `-jsem`:ghc-flag: flag, which instructs GHC to act as a jobserver client. + This enables multiple GHC processes running at once to share system resources + with each other, communicating via the system semaphore specified by + the flag argument. + + GHCi ~~~~ ===================================== docs/users_guide/using.rst ===================================== @@ -751,6 +751,60 @@ search path (see :ref:`search-path`). number of processors. Note that compilation of a module may not begin until its dependencies have been built. + +GHC Jobserver Protocol +~~~~~~~~~~~~~~~~~~~~~~ + +The GHC Jobserver Protocol was specified in `GHC proposal #540 `__. + +This protocol allows +a server to dynamically invoke many instances of a client process, +while restricting all of those instances to use no more than capabilities. +This is achieved by coordination over a system semaphore (either a POSIX +semaphore in the case of Linux and Darwin, or a Win32 semaphore +in the case of Windows platforms). + +There are two kinds of participants in the GHC Jobserver protocol: + +- The *jobserver* creates a system semaphore with a certain number of + available tokens. + + Each time the jobserver wants to spawn a new jobclient subprocess, it **must** + first acquire a single token from the semaphore, before spawning + the subprocess. This token **must** be released once the subprocess terminates. + + Once work is finished, the jobserver **must** destroy the semaphore it created. + +- A *jobclient* is a subprocess spawned by the jobserver or another jobclient. + + Each jobclient starts with one available token (its *implicit token*, + which was acquired by the parent which spawned it), and can request more + tokens through the Jobserver Protocol by waiting on the semaphore. + + Each time a jobclient wants to spawn a new jobclient subprocess, it **must** + pass on a single token to the child jobclient. This token can either be the + jobclient's implicit token, or another token which the jobclient acquired + from the semaphore. + + Each jobclient **must** release exactly as many tokens as it has acquired from + the semaphore (this does not include the implicit tokens). + + GHC itself acts as a jobclient which can be enabled by using the flag ``-jsem``. + +.. ghc-flag:: -jsem + :shortdesc: When compiling with :ghc-flag:`--make`, coordinate with + other processes through the semaphore ⟨sem⟩ to compile + modules in parallel. + :type: dynamic + :category: misc + + Perform compilation in parallel when possible, coordinating with other + processes through the semaphore ⟨sem⟩ (specified as a string). + Error if the semaphore doesn't exist. + + Use of ``-jsem`` will override use of :ghc-flag:``-j[⟨n⟩]``, + and vice-versa. + .. _multi-home-units: Multiple Home Units ===================================== hadrian/src/Builder.hs ===================================== @@ -41,6 +41,7 @@ import Packages import GHC.IO.Encoding (getFileSystemEncoding) import qualified Data.ByteString as BS import qualified GHC.Foreign as GHC +import GHC.ResponseFile -- | C compiler can be used in two different modes: -- * Compile or preprocess a source file. @@ -353,6 +354,8 @@ instance H.Builder Builder where Exit _ <- cmd' [path] (buildArgs ++ [input]) return () + Haddock BuildPackage -> runHaddock path buildArgs buildInputs + HsCpp -> captureStdout Make dir -> cmd' path ["-C", dir] buildArgs @@ -385,6 +388,16 @@ instance H.Builder Builder where _ -> cmd' [path] buildArgs +-- | Invoke @haddock@ given a path to it and a list of arguments. The arguments +-- are passed in a response file. +runHaddock :: FilePath -- ^ path to @haddock@ + -> [String] + -> [FilePath] -- ^ input file paths + -> Action () +runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do + writeFile' tmp $ escapeArgs fileInputs + cmd [haddockPath] flagArgs ('@' : tmp) + -- TODO: Some builders are required only on certain platforms. For example, -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform -- specific optional builders as soon as we can reliably test this feature. ===================================== hadrian/src/Packages.hs ===================================== @@ -8,7 +8,7 @@ module Packages ( ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, stm, templateHaskell, terminfo, text, time, timeout, touchy, + runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, touchy, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -39,7 +39,7 @@ ghcPackages = , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh , ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl - , parsec, pretty, process, rts, runGhc, stm, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell , terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -55,7 +55,7 @@ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, count exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - parsec, pretty, primitive, process, rts, runGhc, stm, templateHaskell, + parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -110,6 +110,7 @@ process = lib "process" remoteIserv = util "remote-iserv" rts = top "rts" runGhc = util "runghc" +semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" terminfo = lib "terminfo" ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -171,6 +171,7 @@ toolTargets = [ binary , templateHaskell , text , transformers + , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Builders/Haddock.hs ===================================== @@ -68,7 +68,6 @@ haddockBuilderArgs = mconcat ++ "," ++ baseUrl p ++ "/src/%{MODULE}.html#%{NAME}," ++ haddock | (p, haddock) <- haddocks_with_versions ] , pure [ "--optghc=" ++ opt | opt <- ghcOpts, not ("--package-db" `isInfixOf` opt) ] - , getInputs , arg "+RTS" , arg $ "-t" ++ (statsDir -/- pkgName pkg ++ ".t") , arg "--machine-readable" ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -95,6 +95,7 @@ stage0Packages = do , hpcBin , mtl , parsec + , semaphoreCompat , time , templateHaskell , text @@ -142,6 +143,7 @@ stage1Packages = do , integerGmp , pretty , rts + , semaphoreCompat , stm , unlit , xhtml ===================================== libraries/base/GHC/Read.hs ===================================== @@ -205,8 +205,8 @@ class Read a where -- | The method 'readList' is provided to allow the programmer to -- give a specialised way of parsing lists of values. -- For example, this is used by the predefined 'Read' instance of - -- the 'Char' type, where values of type 'String' should be are - -- expected to use double quotes, rather than square brackets. + -- the 'Char' type, where values of type 'String' are expected to + -- use double quotes, rather than square brackets. readList :: ReadS [a] -- | Proposed replacement for 'readsPrec' using new-style parsers (GHC only). ===================================== libraries/semaphore-compat ===================================== @@ -0,0 +1 @@ +Subproject commit 663ef75467995acf41c51d3e21d03347e85b844e ===================================== packages ===================================== @@ -65,5 +65,6 @@ libraries/Win32 - - https:/ libraries/xhtml - - https://github.com/haskell/xhtml.git libraries/exceptions - - https://github.com/ekmett/exceptions.git nofib nofib - - +libraries/semaphore-compat - - - libraries/stm - - ssh://git at github.com/haskell/stm.git . - ghc.git - ===================================== rts/Threads.c ===================================== @@ -872,6 +872,7 @@ StgMutArrPtrs *listThreads(Capability *cap) const StgWord size = n_threads + mutArrPtrsCardTableSize(n_threads); StgMutArrPtrs *arr = (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size); + SET_HDR(arr, &stg_MUT_ARR_PTRS_DIRTY_info, CCS_SYSTEM); TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0); arr->ptrs = n_threads; arr->size = size; ===================================== testsuite/tests/primops/should_run/T23071.hs ===================================== @@ -0,0 +1,5 @@ +import Control.Monad +import GHC.Conc.Sync + +main = replicateM_ 1000000 $ listThreads >>= print + ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -60,3 +60,4 @@ test('UnliftedTVar2', normal, compile_and_run, ['']) test('UnliftedWeakPtr', normal, compile_and_run, ['']) test('T21624', normal, compile_and_run, ['']) +test('T23071', ignore_stdout, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d23b736fb66c62fe1a6da08cf03431880e90980b...12497eb922d04fd0f53362b932402ba158dc8bd2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d23b736fb66c62fe1a6da08cf03431880e90980b...12497eb922d04fd0f53362b932402ba158dc8bd2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 17:12:31 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 13:12:31 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] 16 commits: Major refactor in the handling of equality constraints Message-ID: <6441727fd9afc_178e744cb0bca0732984@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - 830d1c3c by Josh Meredith at 2023-04-20T17:12:17+00:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 30 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0bc332e84ebb97effc0e35d48c604704d51ff32f...830d1c3cd72d4e86a520ad1d86eac341b02a9f95 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0bc332e84ebb97effc0e35d48c604704d51ff32f...830d1c3cd72d4e86a520ad1d86eac341b02a9f95 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 17:14:51 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 20 Apr 2023 13:14:51 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] 2 commits: Replace the implementation of CodeBuffers with unboxed types Message-ID: <6441730bdb81c_178e744cbc5088733516@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 6eccf82c by Josh Meredith at 2023-04-20T08:44:11+00:00 Replace the implementation of CodeBuffers with unboxed types - - - - - 852820f4 by Josh Meredith at 2023-04-20T17:14:19+00:00 Use unboxed codebuffers in base - - - - - 8 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/Types.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,7 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +20,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +145,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +169,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let (# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/Types.hs ===================================== @@ -1,6 +1,9 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude, ExistentialQuantification #-} {-# OPTIONS_GHC -funbox-strict-fields #-} +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE PatternSynonyms, ViewPatterns #-} +{-# LANGUAGE UnboxedTuples, MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -17,11 +20,13 @@ ----------------------------------------------------------------------------- module GHC.IO.Encoding.Types ( - BufferCodec(..), + BufferCodec(.., BufferCodec, encode, recover, close, getState, setState), TextEncoding(..), TextEncoder, TextDecoder, CodeBuffer, EncodeBuffer, DecodeBuffer, - CodingProgress(..) + CodingProgress(..), + DecodeBuffer#, EncodeBuffer#, + DecodingBuffer#, EncodingBuffer# ) where import GHC.Base @@ -33,8 +38,8 @@ import GHC.IO.Buffer -- ----------------------------------------------------------------------------- -- Text encoders/decoders -data BufferCodec from to state = BufferCodec { - encode :: CodeBuffer from to, +data BufferCodec from to state = BufferCodec# { + encode# :: CodeBuffer# from to, -- ^ The @encode@ function translates elements of the buffer @from@ -- to the buffer @to at . It should translate as many elements as possible -- given the sizes of the buffers, including translating zero elements @@ -50,7 +55,7 @@ data BufferCodec from to state = BufferCodec { -- library in order to report translation errors at the point they -- actually occur, rather than when the buffer is translated. - recover :: Buffer from -> Buffer to -> IO (Buffer from, Buffer to), + recover# :: Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #), -- ^ The @recover@ function is used to continue decoding -- in the presence of invalid or unrepresentable sequences. This includes -- both those detected by @encode@ returning @InvalidSequence@ and those @@ -69,12 +74,12 @@ data BufferCodec from to state = BufferCodec { -- -- @since 4.4.0.0 - close :: IO (), + close# :: IO (), -- ^ Resources associated with the encoding may now be released. -- The @encode@ function may not be called again after calling -- @close at . - getState :: IO state, + getState# :: IO state, -- ^ Return the current state of the codec. -- -- Many codecs are not stateful, and in these case the state can be @@ -87,14 +92,22 @@ data BufferCodec from to state = BufferCodec { -- beginning), and if not, whether to use the big or little-endian -- encoding. - setState :: state -> IO () + setState# :: state -> IO () -- restore the state of the codec using the state from a previous -- call to 'getState'. } -type CodeBuffer from to = Buffer from -> Buffer to -> IO (CodingProgress, Buffer from, Buffer to) -type DecodeBuffer = CodeBuffer Word8 Char -type EncodeBuffer = CodeBuffer Char Word8 +type CodeBuffer from to = Buffer from -> Buffer to -> IO (CodingProgress, Buffer from, Buffer to) +type DecodeBuffer = CodeBuffer Word8 Char +type EncodeBuffer = CodeBuffer Char Word8 + +type CodeBuffer# from to = Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, CodingProgress, Buffer from, Buffer to #) +type DecodeBuffer# = CodeBuffer# Word8 Char +type EncodeBuffer# = CodeBuffer# Char Word8 + +type CodingBuffer# from to = State# RealWorld -> (# State# RealWorld, CodingProgress, Buffer from, Buffer to #) +type DecodingBuffer# = CodingBuffer# Word8 Char +type EncodingBuffer# = CodingBuffer# Char Word8 type TextDecoder state = BufferCodec Word8 CharBufElem state type TextEncoder state = BufferCodec CharBufElem Word8 state @@ -132,3 +145,29 @@ data CodingProgress = InputUnderflow -- ^ Stopped because the input contains in , Show -- ^ @since 4.4.0.0 ) +pattern BufferCodec :: CodeBuffer from to + -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) + -> IO () + -> IO state + -> (state -> IO ()) + -> BufferCodec from to state +pattern BufferCodec{encode, recover, close, getState, setState} <- + BufferCodec# (getEncode -> encode) (getRecover -> recover) close getState setState + where + BufferCodec e r c g s = BufferCodec# (mkEncode e) (mkRecover r) c g s + +getEncode :: CodeBuffer# from to -> CodeBuffer from to +getEncode e i o = IO $ \st -> + let !(# st', prog, i', o' #) = e i o st in (# st', (prog, i', o') #) + +getRecover :: (Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #)) + -> (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) +getRecover r i o = IO $ \st -> + let !(# st', i', o' #) = r i o st in (# st', (i', o') #) + +mkEncode :: CodeBuffer from to -> CodeBuffer# from to +mkEncode e i o st = let !(# st', (prog, i', o') #) = unIO (e i o) st in (# st', prog, i', o' #) + +mkRecover :: (Buffer from -> Buffer to -> IO (Buffer from, Buffer to)) + -> (Buffer from -> Buffer to -> State# RealWorld -> (# State# RealWorld, Buffer from, Buffer to #)) +mkRecover r i o st = let !(# st', (i', o') #) = unIO (r i o) st in (# st', i', o' #) ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let (# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let (# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let (# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let (# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b037bbb093c5d51520acdd332d5947811e36417e...852820f42fd5bd3196d46fb2ec2eaa1fc95a851d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b037bbb093c5d51520acdd332d5947811e36417e...852820f42fd5bd3196d46fb2ec2eaa1fc95a851d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 17:52:51 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 20 Apr 2023 13:52:51 -0400 Subject: [Git][ghc/ghc][wip/ghcup-metadata-nightly] testing Message-ID: <64417bf387f44_178e744d6502b4743231@gitlab.mail> Matthew Pickering pushed to branch wip/ghcup-metadata-nightly at Glasgow Haskell Compiler / GHC Commits: 05158f5a by GHC GitLab CI at 2023-04-20T18:52:44+01:00 testing - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -1065,7 +1065,7 @@ ghcup-metadata-nightly-push: script: - git config user.email "ghc-ci at gitlab-haskell.org" - git config user.name "GHC GitLab CI" - - git clone git at gitlab.haskell.org:ghc/ghcup-metadata.git + - git clone https://gitlab.haskell.org/ghc/ghcup-metadata.git - cp metadata_test.yaml ghcup-metadata/ghcup-0.0.7.yaml - cd ghcup-metadata - echo "" >> ghcup-0.0.7.yaml View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05158f5a9d673dcfd21916ae8e1866c1e384cf56 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/05158f5a9d673dcfd21916ae8e1866c1e384cf56 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 22:34:04 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 18:34:04 -0400 Subject: [Git][ghc/ghc][master] Implement -jsem: parallelism controlled by semaphores Message-ID: <6441bddc730b8_178e745226ad34779789@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 14 changed files: - .gitmodules - cabal.project-reinstall - compiler/GHC/Driver/Make.hs - + compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Session.hs - compiler/ghc.cabal.in - docs/users_guide/9.8.1-notes.rst - docs/users_guide/using.rst - hadrian/src/Packages.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - + libraries/semaphore-compat - packages Changes: ===================================== .gitmodules ===================================== @@ -83,6 +83,10 @@ url = https://gitlab.haskell.org/ghc/packages/unix.git ignore = untracked branch = 2.7 +[submodule "libraries/semaphore-compat"] + path = libraries/semaphore-compat + url = https://gitlab.haskell.org/ghc/semaphore-compat.git + ignore = untracked [submodule "libraries/stm"] path = libraries/stm url = https://gitlab.haskell.org/ghc/packages/stm.git ===================================== cabal.project-reinstall ===================================== @@ -28,6 +28,7 @@ packages: ./compiler ./libraries/parsec/ -- ./libraries/pretty/ ./libraries/process/ + ./libraries/semaphore-compat ./libraries/stm -- ./libraries/template-haskell/ ./libraries/terminfo/ ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -75,6 +75,7 @@ import GHC.Driver.Env import GHC.Driver.Errors import GHC.Driver.Errors.Types import GHC.Driver.Main +import GHC.Driver.MakeSem import GHC.Parser.Header @@ -151,10 +152,10 @@ import GHC.Runtime.Loader import GHC.Rename.Names import GHC.Utils.Constants import GHC.Types.Unique.DFM (udfmRestrictKeysSet) -import qualified Data.IntSet as I import GHC.Types.Unique import GHC.Iface.Errors.Types +import qualified Data.IntSet as I -- ----------------------------------------------------------------------------- -- Loading the program @@ -664,6 +665,30 @@ createBuildPlan mod_graph maybe_top_mod = (vcat [text "Build plan missing nodes:", (text "PLAN:" <+> ppr (sum (map countMods build_plan))), (text "GRAPH:" <+> ppr (length (mgModSummaries' mod_graph )))]) build_plan +mkWorkerLimit :: DynFlags -> IO WorkerLimit +mkWorkerLimit dflags = + case parMakeCount dflags of + Nothing -> pure $ num_procs 1 + Just (ParMakeSemaphore h) -> pure (JSemLimit (SemaphoreName h)) + Just ParMakeNumProcessors -> num_procs <$> getNumProcessors + Just (ParMakeThisMany n) -> pure $ num_procs n + where + num_procs x = NumProcessorsLimit (max 1 x) + +isWorkerLimitSequential :: WorkerLimit -> Bool +isWorkerLimitSequential (NumProcessorsLimit x) = x <= 1 +isWorkerLimitSequential (JSemLimit {}) = False + +-- | This describes what we use to limit the number of jobs, either we limit it +-- ourselves to a specific number or we have an external parallelism semaphore +-- limit it for us. +data WorkerLimit + = NumProcessorsLimit Int + | JSemLimit + SemaphoreName + -- ^ Semaphore name to use + deriving Eq + -- | Generalized version of 'load' which also supports a custom -- 'Messager' (for reporting progress) and 'ModuleGraph' (generally -- produced by calling 'depanal'. @@ -744,14 +769,12 @@ load' mhmi_cache how_much mHscMessage mod_graph = do liftIO $ debugTraceMsg logger 2 (hang (text "Ready for upsweep") 2 (ppr build_plan)) - n_jobs <- case parMakeCount (hsc_dflags hsc_env) of - Nothing -> liftIO getNumProcessors - Just n -> return n + worker_limit <- liftIO $ mkWorkerLimit dflags setSession $ hscUpdateHUG (unitEnv_map pruneHomeUnitEnv) hsc_env (upsweep_ok, hsc_env1) <- withDeferredDiagnostics $ do hsc_env <- getSession - liftIO $ upsweep n_jobs hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan + liftIO $ upsweep worker_limit hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan setSession hsc_env1 case upsweep_ok of Failed -> loadFinish upsweep_ok @@ -1036,13 +1059,7 @@ getDependencies direct_deps build_map = type BuildM a = StateT BuildLoopState IO a --- | Abstraction over the operations of a semaphore which allows usage with the --- -j1 case -data AbstractSem = AbstractSem { acquireSem :: IO () - , releaseSem :: IO () } -withAbstractSem :: AbstractSem -> IO b -> IO b -withAbstractSem sem = MC.bracket_ (acquireSem sem) (releaseSem sem) -- | Environment used when compiling a module data MakeEnv = MakeEnv { hsc_env :: !HscEnv -- The basic HscEnv which will be augmented for each module @@ -1227,7 +1244,7 @@ withCurrentUnit uid = do local (\env -> env { hsc_env = hscSetActiveUnitId uid (hsc_env env)}) upsweep - :: Int -- ^ The number of workers we wish to run in parallel + :: WorkerLimit -- ^ The number of workers we wish to run in parallel -> HscEnv -- ^ The base HscEnv, which is augmented for each module -> Maybe ModIfaceCache -- ^ A cache to incrementally write final interface files to -> Maybe Messager @@ -2832,7 +2849,7 @@ label_self thread_name = do CC.labelThread self_tid thread_name -runPipelines :: Int -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () +runPipelines :: WorkerLimit -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () -- Don't even initialise plugins if there are no pipelines runPipelines _ _ _ [] = return () runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do @@ -2840,7 +2857,7 @@ runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do plugins_hsc_env <- initializePlugins orig_hsc_env case n_job of - 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines + NumProcessorsLimit n | n <= 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines _n -> runParPipelines n_job plugins_hsc_env mHscMessager all_pipelines runSeqPipelines :: HscEnv -> Maybe Messager -> [MakeAction] -> IO () @@ -2850,16 +2867,38 @@ runSeqPipelines plugin_hsc_env mHscMessager all_pipelines = , compile_sem = AbstractSem (return ()) (return ()) , env_messager = mHscMessager } - in runAllPipelines 1 env all_pipelines + in runAllPipelines (NumProcessorsLimit 1) env all_pipelines +runNjobsAbstractSem :: Int -> (AbstractSem -> IO a) -> IO a +runNjobsAbstractSem n_jobs action = do + compile_sem <- newQSem n_jobs + n_capabilities <- getNumCapabilities + n_cpus <- getNumProcessors + let + asem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + set_num_caps n = unless (n_capabilities /= 1) $ setNumCapabilities n + updNumCapabilities = do + -- Setting number of capabilities more than + -- CPU count usually leads to high userspace + -- lock contention. #9221 + set_num_caps $ min n_jobs n_cpus + resetNumCapabilities = set_num_caps n_capabilities + MC.bracket_ updNumCapabilities resetNumCapabilities $ action asem + +runWorkerLimit :: WorkerLimit -> (AbstractSem -> IO a) -> IO a +runWorkerLimit worker_limit action = case worker_limit of + NumProcessorsLimit n_jobs -> + runNjobsAbstractSem n_jobs action + JSemLimit sem -> + runJSemAbstractSem sem action -- | Build and run a pipeline -runParPipelines :: Int -- ^ How many capabilities to use - -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module +runParPipelines :: WorkerLimit -- ^ How to limit work parallelism + -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module -> Maybe Messager -- ^ Optional custom messager to use to report progress -> [MakeAction] -- ^ The build plan for all the module nodes -> IO () -runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do +runParPipelines worker_limit plugin_hsc_env mHscMessager all_pipelines = do -- A variable which we write to when an error has happened and we have to tell the @@ -2869,39 +2908,23 @@ runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do -- will add it's LogQueue into this queue. log_queue_queue_var <- newTVarIO newLogQueueQueue -- Thread which coordinates the printing of logs - wait_log_thread <- logThread n_jobs (length all_pipelines) (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var + wait_log_thread <- logThread (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var -- Make the logger thread-safe, in case there is some output which isn't sent via the LogQueue. thread_safe_logger <- liftIO $ makeThreadSafe (hsc_logger plugin_hsc_env) let thread_safe_hsc_env = plugin_hsc_env { hsc_logger = thread_safe_logger } - let updNumCapabilities = liftIO $ do - n_capabilities <- getNumCapabilities - n_cpus <- getNumProcessors - -- Setting number of capabilities more than - -- CPU count usually leads to high userspace - -- lock contention. #9221 - let n_caps = min n_jobs n_cpus - unless (n_capabilities /= 1) $ setNumCapabilities n_caps - return n_capabilities - - let resetNumCapabilities orig_n = do - liftIO $ setNumCapabilities orig_n - atomically $ writeTVar stopped_var True - wait_log_thread - - compile_sem <- newQSem n_jobs - let abstract_sem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + runWorkerLimit worker_limit $ \abstract_sem -> do + let env = MakeEnv { hsc_env = thread_safe_hsc_env + , withLogger = withParLog log_queue_queue_var + , compile_sem = abstract_sem + , env_messager = mHscMessager + } -- Reset the number of capabilities once the upsweep ends. - let env = MakeEnv { hsc_env = thread_safe_hsc_env - , withLogger = withParLog log_queue_queue_var - , compile_sem = abstract_sem - , env_messager = mHscMessager - } - - MC.bracket updNumCapabilities resetNumCapabilities $ \_ -> - runAllPipelines n_jobs env all_pipelines + runAllPipelines worker_limit env all_pipelines + atomically $ writeTVar stopped_var True + wait_log_thread withLocalTmpFS :: RunMakeM a -> RunMakeM a withLocalTmpFS act = do @@ -2918,10 +2941,11 @@ withLocalTmpFS act = do MC.bracket initialiser finaliser $ \lcl_hsc_env -> local (\env -> env { hsc_env = lcl_hsc_env}) act -- | Run the given actions and then wait for them all to finish. -runAllPipelines :: Int -> MakeEnv -> [MakeAction] -> IO () -runAllPipelines n_jobs env acts = do - let spawn_actions :: IO [ThreadId] - spawn_actions = if n_jobs == 1 +runAllPipelines :: WorkerLimit -> MakeEnv -> [MakeAction] -> IO () +runAllPipelines worker_limit env acts = do + let single_worker = isWorkerLimitSequential worker_limit + spawn_actions :: IO [ThreadId] + spawn_actions = if single_worker then (:[]) <$> (forkIOWithUnmask $ \unmask -> void $ runLoop (\io -> io unmask) env acts) else runLoop forkIOWithUnmask env acts ===================================== compiler/GHC/Driver/MakeSem.hs ===================================== @@ -0,0 +1,545 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE NumericUnderscores #-} + +-- | Implementation of a jobserver using system semaphores. +-- +-- +module GHC.Driver.MakeSem + ( -- * JSem: parallelism semaphore backed + -- by a system semaphore (Posix/Windows) + runJSemAbstractSem + + -- * System semaphores + , Semaphore, SemaphoreName(..) + + -- * Abstract semaphores + , AbstractSem(..) + , withAbstractSem + ) + where + +import GHC.Prelude +import GHC.Conc +import GHC.Data.OrdList +import GHC.IO.Exception +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Utils.Json + +import System.Semaphore + +import Control.Monad +import qualified Control.Monad.Catch as MC +import Control.Concurrent.MVar +import Control.Concurrent.STM +import Data.Foldable +import Data.Functor +import GHC.Stack +import Debug.Trace + +--------------------------------------- +-- Semaphore jobserver + +-- | A jobserver based off a system 'Semaphore'. +-- +-- Keeps track of the pending jobs and resources +-- available from the semaphore. +data Jobserver + = Jobserver + { jSemaphore :: !Semaphore + -- ^ The semaphore which controls available resources + , jobs :: !(TVar JobResources) + -- ^ The currently pending jobs, and the resources + -- obtained from the semaphore + } + +data JobserverOptions + = JobserverOptions + { releaseDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between acquiring a token + -- and releasing a token. + , setNumCapsDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between two consecutive + -- calls of 'setNumCapabilities'. + } + +defaultJobserverOptions :: JobserverOptions +defaultJobserverOptions = + JobserverOptions + { releaseDebounce = 1000 -- 1 second + , setNumCapsDebounce = 1000 -- 1 second + } + +-- | Resources available for running jobs, i.e. +-- tokens obtained from the parallelism semaphore. +data JobResources + = Jobs + { tokensOwned :: !Int + -- ^ How many tokens have been claimed from the semaphore + , tokensFree :: !Int + -- ^ How many tokens are not currently being used + , jobsWaiting :: !(OrdList (TMVar ())) + -- ^ Pending jobs waiting on a token, the job will be blocked on the TMVar so putting into + -- the TMVar will allow the job to continue. + } + +instance Outputable JobResources where + ppr Jobs{..} + = text "JobResources" <+> + ( braces $ hsep + [ text "owned=" <> ppr tokensOwned + , text "free=" <> ppr tokensFree + , text "num_waiting=" <> ppr (length jobsWaiting) + ] ) + +-- | Add one new token. +addToken :: JobResources -> JobResources +addToken jobs@( Jobs { tokensOwned = owned, tokensFree = free }) + = jobs { tokensOwned = owned + 1, tokensFree = free + 1 } + +-- | Free one token. +addFreeToken :: JobResources -> JobResources +addFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (tokensOwned jobs > free) + (text "addFreeToken:" <+> ppr (tokensOwned jobs) <+> ppr free) + $ jobs { tokensFree = free + 1 } + +-- | Use up one token. +removeFreeToken :: JobResources -> JobResources +removeFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (free > 0) + (text "removeFreeToken:" <+> ppr free) + $ jobs { tokensFree = free - 1 } + +-- | Return one owned token. +removeOwnedToken :: JobResources -> JobResources +removeOwnedToken jobs@( Jobs { tokensOwned = owned }) + = assertPpr (owned > 1) + (text "removeOwnedToken:" <+> ppr owned) + $ jobs { tokensOwned = owned - 1 } + +-- | Add one new job to the end of the list of pending jobs. +addJob :: TMVar () -> JobResources -> JobResources +addJob job jobs@( Jobs { jobsWaiting = wait }) + = jobs { jobsWaiting = wait `SnocOL` job } + +-- | The state of the semaphore job server. +data JobserverState + = JobserverState + { jobserverAction :: !JobserverAction + -- ^ The current action being performed by the + -- job server. + , canChangeNumCaps :: !(TVar Bool) + -- ^ A TVar that signals whether it has been long + -- enough since we last changed 'numCapabilities'. + , canReleaseToken :: !(TVar Bool) + -- ^ A TVar that signals whether we last acquired + -- a token long enough ago that we can now release + -- a token. + } +data JobserverAction + -- | The jobserver is idle: no thread is currently + -- interacting with the semaphore. + = Idle + -- | A thread is waiting for a token on the semaphore. + | Acquiring + { activeWaitId :: WaitId + , threadFinished :: TMVar (Maybe MC.SomeException) } + +-- | Retrieve the 'TMVar' that signals if the current thread has finished, +-- if any thread is currently active in the jobserver. +activeThread_maybe :: JobserverAction -> Maybe (TMVar (Maybe MC.SomeException)) +activeThread_maybe Idle = Nothing +activeThread_maybe (Acquiring { threadFinished = tmvar }) = Just tmvar + +-- | Whether we should try to acquire a new token from the semaphore: +-- there is a pending job and no free tokens. +guardAcquire :: JobResources -> Bool +guardAcquire ( Jobs { tokensFree, jobsWaiting } ) + = tokensFree == 0 && not (null jobsWaiting) + +-- | Whether we should release a token from the semaphore: +-- there are no pending jobs and we can release a token. +guardRelease :: JobResources -> Bool +guardRelease ( Jobs { tokensFree, tokensOwned, jobsWaiting } ) + = null jobsWaiting && tokensFree > 0 && tokensOwned > 1 + +--------------------------------------- +-- Semaphore jobserver implementation + +-- | Add one pending job to the jobserver. +-- +-- Blocks, waiting on the jobserver to supply a free token. +acquireJob :: TVar JobResources -> IO () +acquireJob jobs_tvar = do + (job_tmvar, _jobs0) <- tracedAtomically "acquire" $ + modifyJobResources jobs_tvar \ jobs -> do + job_tmvar <- newEmptyTMVar + return ((job_tmvar, jobs), addJob job_tmvar jobs) + atomically $ takeTMVar job_tmvar + +-- | Signal to the job server that one job has completed, +-- releasing its corresponding token. +releaseJob :: TVar JobResources -> IO () +releaseJob jobs_tvar = do + tracedAtomically "release" do + modifyJobResources jobs_tvar \ jobs -> do + massertPpr (tokensFree jobs < tokensOwned jobs) + (text "releaseJob: more free jobs than owned jobs!") + return ((), addFreeToken jobs) + + +-- | Release all tokens owned from the semaphore (to clean up +-- the jobserver at the end). +cleanupJobserver :: Jobserver -> IO () +cleanupJobserver (Jobserver { jSemaphore = sem + , jobs = jobs_tvar }) + = do + Jobs { tokensOwned = owned } <- readTVarIO jobs_tvar + let toks_to_release = owned - 1 + -- Subtract off the implicit token: whoever spawned the ghc process + -- in the first place is responsible for that token. + releaseSemaphore sem toks_to_release + +-- | Dispatch the available tokens acquired from the semaphore +-- to the pending jobs in the job server. +dispatchTokens :: JobResources -> STM JobResources +dispatchTokens jobs@( Jobs { tokensFree = toks_free, jobsWaiting = wait } ) + | toks_free > 0 + , next `ConsOL` rest <- wait + -- There's a pending job and a free token: + -- pass on the token to that job, and recur. + = do + putTMVar next () + let jobs' = jobs { tokensFree = toks_free - 1, jobsWaiting = rest } + dispatchTokens jobs' + | otherwise + = return jobs + +-- | Update the available resources used from a semaphore, dispatching +-- any newly acquired resources. +-- +-- Invariant: if the number of available resources decreases, there +-- must be no pending jobs. +-- +-- All modifications should go through this function to ensure the contents +-- of the 'TVar' remains in normal form. +modifyJobResources :: HasCallStack => TVar JobResources + -> (JobResources -> STM (a, JobResources)) + -> STM (a, Maybe JobResources) +modifyJobResources jobs_tvar action = do + old_jobs <- readTVar jobs_tvar + (a, jobs) <- action old_jobs + + -- Check the invariant: if the number of free tokens has decreased, + -- there must be no pending jobs. + massertPpr (null (jobsWaiting jobs) || tokensFree jobs >= tokensFree old_jobs) $ + vcat [ text "modiyJobResources: pending jobs but fewer free tokens" ] + dispatched_jobs <- dispatchTokens jobs + writeTVar jobs_tvar dispatched_jobs + return (a, Just dispatched_jobs) + + +tracedAtomically_ :: String -> STM (Maybe JobResources) -> IO () +tracedAtomically_ s act = tracedAtomically s (((),) <$> act) + +tracedAtomically :: String -> STM (a, Maybe JobResources) -> IO a +tracedAtomically origin act = do + (a, mjr) <- atomically act + forM_ mjr $ \ jr -> do + -- Use the "jsem:" prefix to identify where the write traces are + traceEventIO ("jsem:" ++ renderJobResources origin jr) + return a + +renderJobResources :: String -> JobResources -> String +renderJobResources origin (Jobs own free pending) = showSDocUnsafe $ renderJSON $ + JSObject [ ("name", JSString origin) + , ("owned", JSInt own) + , ("free", JSInt free) + , ("pending", JSInt (length pending) ) + ] + + +-- | Spawn a new thread that waits on the semaphore in order to acquire +-- an additional token. +acquireThread :: Jobserver -> IO JobserverAction +acquireThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + let + wait_result_action :: Either MC.SomeException Bool -> IO () + wait_result_action wait_res = + tracedAtomically_ "acquire_thread" do + (r, jb) <- case wait_res of + Left (e :: MC.SomeException) -> do + return $ (Just e, Nothing) + Right success -> do + if success + then do + modifyJobResources jobs_tvar \ jobs -> + return (Nothing, addToken jobs) + else + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jb + wait_id <- forkWaitOnSemaphoreInterruptible sem wait_result_action + labelThread (waitingThreadId wait_id) "acquire_thread" + return $ Acquiring { activeWaitId = wait_id + , threadFinished = threadFinished_tmvar } + +-- | Spawn a thread to release ownership of one resource from the semaphore, +-- provided we have spare resources and no pending jobs. +releaseThread :: Jobserver -> IO JobserverAction +releaseThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + MC.mask_ do + -- Pre-release the resource so that another thread doesn't take control of it + -- just as we release the lock on the semaphore. + still_ok_to_release + <- tracedAtomically "pre_release" $ + modifyJobResources jobs_tvar \ jobs -> + if guardRelease jobs + -- TODO: should this also debounce? + then return (True , removeOwnedToken $ removeFreeToken jobs) + else return (False, jobs) + if not still_ok_to_release + then return Idle + else do + tid <- forkIO $ do + x <- MC.try $ releaseSemaphore sem 1 + tracedAtomically_ "post-release" $ do + (r, jobs) <- case x of + Left (e :: MC.SomeException) -> do + modifyJobResources jobs_tvar \ jobs -> + return (Just e, addToken jobs) + Right _ -> do + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jobs + labelThread tid "release_thread" + return Idle + +-- | When there are pending jobs but no free tokens, +-- spawn a thread to acquire a new token from the semaphore. +-- +-- See 'acquireThread'. +tryAcquire :: JobserverOptions + -> Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryAcquire opts js@( Jobserver { jobs = jobs_tvar }) + st@( JobserverState { jobserverAction = Idle } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardAcquire jobs + return do + action <- acquireThread js + -- Set a debounce after acquiring a token. + can_release_tvar <- registerDelay $ (releaseDebounce opts * 1000) + return $ st { jobserverAction = action + , canReleaseToken = can_release_tvar } +tryAcquire _ _ _ = retry + +-- | When there are free tokens and no pending jobs, +-- spawn a thread to release a token from the semamphore. +-- +-- See 'releaseThread'. +tryRelease :: Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryRelease sjs@( Jobserver { jobs = jobs_tvar } ) + st@( JobserverState + { jobserverAction = Idle + , canReleaseToken = can_release_tvar } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardRelease jobs + can_release <- readTVar can_release_tvar + guard can_release + return do + action <- releaseThread sjs + return $ st { jobserverAction = action } +tryRelease _ _ = retry + +-- | Wait for an active thread to finish. Once it finishes: +-- +-- - set the 'JobserverAction' to 'Idle', +-- - update the number of capabilities to reflect the number +-- of owned tokens from the semaphore. +tryNoticeIdle :: JobserverOptions + -> TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryNoticeIdle opts jobs_tvar jobserver_state + | Just threadFinished_tmvar <- activeThread_maybe $ jobserverAction jobserver_state + = sync_num_caps (canChangeNumCaps jobserver_state) threadFinished_tmvar + | otherwise + = retry -- no active thread: wait until jobserver isn't idle + where + sync_num_caps :: TVar Bool + -> TMVar (Maybe MC.SomeException) + -> STM (IO JobserverState) + sync_num_caps can_change_numcaps_tvar threadFinished_tmvar = do + mb_ex <- takeTMVar threadFinished_tmvar + for_ mb_ex MC.throwM + Jobs { tokensOwned } <- readTVar jobs_tvar + can_change_numcaps <- readTVar can_change_numcaps_tvar + guard can_change_numcaps + return do + x <- getNumCapabilities + can_change_numcaps_tvar_2 <- + if x == tokensOwned + then return can_change_numcaps_tvar + else do + setNumCapabilities tokensOwned + registerDelay $ (setNumCapsDebounce opts * 1000) + return $ + jobserver_state + { jobserverAction = Idle + , canChangeNumCaps = can_change_numcaps_tvar_2 } + +-- | Try to stop the current thread which is acquiring/releasing resources +-- if that operation is no longer relevant. +tryStopThread :: TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryStopThread jobs_tvar jsj = do + case jobserverAction jsj of + Acquiring { activeWaitId = wait_id } -> do + jobs <- readTVar jobs_tvar + guard $ null (jobsWaiting jobs) + return do + interruptWaitOnSemaphore wait_id + return $ jsj { jobserverAction = Idle } + _ -> retry + +-- | Main jobserver loop: acquire/release resources as +-- needed for the pending jobs and available semaphore tokens. +jobserverLoop :: JobserverOptions -> Jobserver -> IO () +jobserverLoop opts sjs@(Jobserver { jobs = jobs_tvar }) + = do + true_tvar <- newTVarIO True + let init_state :: JobserverState + init_state = + JobserverState + { jobserverAction = Idle + , canChangeNumCaps = true_tvar + , canReleaseToken = true_tvar } + loop init_state + where + loop s = do + action <- atomically $ asum $ (\x -> x s) <$> + [ tryRelease sjs + , tryAcquire opts sjs + , tryNoticeIdle opts jobs_tvar + , tryStopThread jobs_tvar + ] + s <- action + loop s + +-- | Create a new jobserver using the given semaphore handle. +makeJobserver :: SemaphoreName -> IO (AbstractSem, IO ()) +makeJobserver sem_name = do + semaphore <- openSemaphore sem_name + let + init_jobs = + Jobs { tokensOwned = 1 + , tokensFree = 1 + , jobsWaiting = NilOL + } + jobs_tvar <- newTVarIO init_jobs + let + opts = defaultJobserverOptions -- TODO: allow this to be configured + sjs = Jobserver { jSemaphore = semaphore + , jobs = jobs_tvar } + loop_finished_mvar <- newEmptyMVar + loop_tid <- forkIOWithUnmask \ unmask -> do + r <- try $ unmask $ jobserverLoop opts sjs + putMVar loop_finished_mvar $ + case r of + Left e + | Just ThreadKilled <- fromException e + -> Nothing + | otherwise + -> Just e + Right () -> Nothing + labelThread loop_tid "job_server" + let + acquireSem = acquireJob jobs_tvar + releaseSem = releaseJob jobs_tvar + cleanupSem = do + -- this is interruptible + cleanupJobserver sjs + killThread loop_tid + mb_ex <- takeMVar loop_finished_mvar + for_ mb_ex MC.throwM + + return (AbstractSem{..}, cleanupSem) + +-- | Implement an abstract semaphore using a semaphore 'Jobserver' +-- which queries the system semaphore of the given name for resources. +runJSemAbstractSem :: SemaphoreName -- ^ the system semaphore to use + -> (AbstractSem -> IO a) -- ^ the operation to run + -- which requires a semaphore + -> IO a +runJSemAbstractSem sem action = MC.mask \ unmask -> do + (abs, cleanup) <- makeJobserver sem + r <- try $ unmask $ action abs + case r of + Left (e1 :: MC.SomeException) -> do + (_ :: Either MC.SomeException ()) <- MC.try cleanup + MC.throwM e1 + Right x -> cleanup $> x + +{- Note [Architecture of the Job Server] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In `-jsem` mode, the amount of parallelism that GHC can use is controlled by a +system semaphore. We take resources from the semaphore when we need them, and +give them back if we don't have enough to do. + +A naive implementation would just take and release the semaphore around performing +the action, but this leads to two issues: + +* When taking a token in the semaphore, we must call `setNumCapabilities` in order + to adjust how many capabilities are available for parallel garbage collection. + This causes unnecessary synchronisations. +* We want to implement a debounce, so that whilst there is pending work in the + current process we prefer to keep hold of resources from the semaphore. + This reduces overall memory usage, as there are fewer live GHC processes at once. + +Therefore, the obtention of semaphore resources is separated away from the +request for the resource in the driver. + +A token from the semaphore is requested using `acquireJob`. This creates a pending +job, which is a MVar that can be filled in to signal that the requested token is ready. + +When the job is finished, the token is released by calling `releaseJob`, which just +increases the number of `free` jobs. If there are more pending jobs when the free count +is increased, the token is immediately reused (see `modifyJobResources`). + +The `jobServerLoop` interacts with the system semaphore: when there are pending +jobs, `acquireThread` blocks, waiting for a token from the semaphore. Once a +token is obtained, it increases the owned count. + +When GHC has free tokens (tokens from the semaphore that it is not using), +no pending jobs, and the debounce has expired, then `releaseThread` will +release tokens back to the global semaphore. + +`tryStopThread` attempts to kill threads which are waiting to acquire a resource +when we no longer need it. For example, consider that we attempt to acquire two +tokens, but the first job finishes before we acquire the second token. +This second token is no longer needed, so we should cancel the wait +(as it would not be used to do any work, and not be returned until the debounce). +We only need to kill `acquireJob`, because `releaseJob` never blocks. + +Note [Eventlog Messages for jsem] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It can be tricky to verify that the work is shared adequately across different +processes. To help debug this, we output the values of `JobResource` to the +eventlog whenever the global state changes. There are some scripts which can be used +to analyse this output and report statistics about core saturation in the +GitHub repo (https://github.com/mpickering/ghc-jsem-analyse). + +-} ===================================== compiler/GHC/Driver/Pipeline/LogQueue.hs ===================================== @@ -100,10 +100,10 @@ dequeueLogQueueQueue (LogQueueQueue n lqq) = case IM.minViewWithKey lqq of Just ((k, v), lqq') | k == n -> Just (v, LogQueueQueue (n + 1) lqq') _ -> Nothing -logThread :: Int -> Int -> Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit +logThread :: Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit -> TVar LogQueueQueue -- Queue for logs -> IO (IO ()) -logThread _ _ logger stopped lqq_var = do +logThread logger stopped lqq_var = do finished_var <- newEmptyMVar _ <- forkIO $ print_logs *> putMVar finished_var () return (takeMVar finished_var) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Driver.Session ( needSourceNotes, OnOff(..), DynFlags(..), + ParMakeCount(..), outputFile, objectSuf, ways, FlagSpec(..), HasDynFlags(..), ContainsDynFlags(..), @@ -467,9 +468,9 @@ data DynFlags = DynFlags { ruleCheck :: Maybe String, strictnessBefore :: [Int], -- ^ Additional demand analysis - parMakeCount :: Maybe Int, -- ^ The number of modules to compile in parallel - -- in --make mode, where Nothing ==> compile as - -- many in parallel as there are CPUs. + parMakeCount :: Maybe ParMakeCount, + -- ^ The number of modules to compile in parallel + -- If unspecified, compile with a single job. enableTimeStats :: Bool, -- ^ Enable RTS timing statistics? ghcHeapSize :: Maybe Int, -- ^ The heap size to set. @@ -791,6 +792,16 @@ instance (Monad m, HasDynFlags m) => HasDynFlags (ExceptT e m) where class ContainsDynFlags t where extractDynFlags :: t -> DynFlags +-- | The type for the -jN argument, specifying that -j on its own represents +-- using the number of machine processors. +data ParMakeCount + -- | Use this many processors (@-j@ flag). + = ParMakeThisMany Int + -- | Use parallelism with as many processors as possible (@-j@ flag without an argument). + | ParMakeNumProcessors + -- | Use the specific semaphore @@ to control parallelism (@-jsem @ flag). + | ParMakeSemaphore FilePath + ----------------------------------------------------------------------------- -- Accessors from 'DynFlags' @@ -1154,7 +1165,7 @@ defaultDynFlags mySettings = historySize = 20, strictnessBefore = [], - parMakeCount = Just 1, + parMakeCount = Nothing, enableTimeStats = False, ghcHeapSize = Nothing, @@ -2120,14 +2131,16 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "j" (OptIntSuffix (\n -> case n of Just n - | n > 0 -> upd (\d -> d { parMakeCount = Just n }) + | n > 0 -> upd (\d -> d { parMakeCount = Just (ParMakeThisMany n) }) | otherwise -> addErr "Syntax: -j[n] where n > 0" - Nothing -> upd (\d -> d { parMakeCount = Nothing }))) + Nothing -> upd (\d -> d { parMakeCount = Just ParMakeNumProcessors }))) -- When the number of parallel builds -- is omitted, it is the same -- as specifying that the number of -- parallel builds is equal to the -- result of getNumProcessors + , make_ord_flag defGhcFlag "jsem" $ hasArg $ \f d -> d { parMakeCount = Just (ParMakeSemaphore f) } + , make_ord_flag defFlag "instantiated-with" (sepArg setUnitInstantiations) , make_ord_flag defFlag "this-component-id" (sepArg setUnitInstanceOf) ===================================== compiler/ghc.cabal.in ===================================== @@ -85,6 +85,7 @@ Library hpc == 0.6.*, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, + semaphore-compat, stm, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, @@ -436,6 +437,7 @@ Library GHC.Driver.GenerateCgIPEStub GHC.Driver.Hooks GHC.Driver.LlvmConfigCache + GHC.Driver.MakeSem GHC.Driver.Main GHC.Driver.Make GHC.Driver.MakeFile ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -87,6 +87,13 @@ Compiler deriving instance TypeError (Text "Boo") => Bar Baz +- GHC Proposal `#540 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0540-jsem.rst`_ has been implemented. + This adds the `-jsem`:ghc-flag: flag, which instructs GHC to act as a jobserver client. + This enables multiple GHC processes running at once to share system resources + with each other, communicating via the system semaphore specified by + the flag argument. + + GHCi ~~~~ ===================================== docs/users_guide/using.rst ===================================== @@ -751,6 +751,60 @@ search path (see :ref:`search-path`). number of processors. Note that compilation of a module may not begin until its dependencies have been built. + +GHC Jobserver Protocol +~~~~~~~~~~~~~~~~~~~~~~ + +The GHC Jobserver Protocol was specified in `GHC proposal #540 `__. + +This protocol allows +a server to dynamically invoke many instances of a client process, +while restricting all of those instances to use no more than capabilities. +This is achieved by coordination over a system semaphore (either a POSIX +semaphore in the case of Linux and Darwin, or a Win32 semaphore +in the case of Windows platforms). + +There are two kinds of participants in the GHC Jobserver protocol: + +- The *jobserver* creates a system semaphore with a certain number of + available tokens. + + Each time the jobserver wants to spawn a new jobclient subprocess, it **must** + first acquire a single token from the semaphore, before spawning + the subprocess. This token **must** be released once the subprocess terminates. + + Once work is finished, the jobserver **must** destroy the semaphore it created. + +- A *jobclient* is a subprocess spawned by the jobserver or another jobclient. + + Each jobclient starts with one available token (its *implicit token*, + which was acquired by the parent which spawned it), and can request more + tokens through the Jobserver Protocol by waiting on the semaphore. + + Each time a jobclient wants to spawn a new jobclient subprocess, it **must** + pass on a single token to the child jobclient. This token can either be the + jobclient's implicit token, or another token which the jobclient acquired + from the semaphore. + + Each jobclient **must** release exactly as many tokens as it has acquired from + the semaphore (this does not include the implicit tokens). + + GHC itself acts as a jobclient which can be enabled by using the flag ``-jsem``. + +.. ghc-flag:: -jsem + :shortdesc: When compiling with :ghc-flag:`--make`, coordinate with + other processes through the semaphore ⟨sem⟩ to compile + modules in parallel. + :type: dynamic + :category: misc + + Perform compilation in parallel when possible, coordinating with other + processes through the semaphore ⟨sem⟩ (specified as a string). + Error if the semaphore doesn't exist. + + Use of ``-jsem`` will override use of :ghc-flag:``-j[⟨n⟩]``, + and vice-versa. + .. _multi-home-units: Multiple Home Units ===================================== hadrian/src/Packages.hs ===================================== @@ -8,7 +8,7 @@ module Packages ( ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, stm, templateHaskell, terminfo, text, time, timeout, touchy, + runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, touchy, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -39,7 +39,7 @@ ghcPackages = , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh , ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl - , parsec, pretty, process, rts, runGhc, stm, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell , terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -55,7 +55,7 @@ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, count exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - parsec, pretty, primitive, process, rts, runGhc, stm, templateHaskell, + parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -110,6 +110,7 @@ process = lib "process" remoteIserv = util "remote-iserv" rts = top "rts" runGhc = util "runghc" +semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" terminfo = lib "terminfo" ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -171,6 +171,7 @@ toolTargets = [ binary , templateHaskell , text , transformers + , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -95,6 +95,7 @@ stage0Packages = do , hpcBin , mtl , parsec + , semaphoreCompat , time , templateHaskell , text @@ -142,6 +143,7 @@ stage1Packages = do , integerGmp , pretty , rts + , semaphoreCompat , stm , unlit , xhtml ===================================== libraries/semaphore-compat ===================================== @@ -0,0 +1 @@ +Subproject commit 663ef75467995acf41c51d3e21d03347e85b844e ===================================== packages ===================================== @@ -65,5 +65,6 @@ libraries/Win32 - - https:/ libraries/xhtml - - https://github.com/haskell/xhtml.git libraries/exceptions - - https://github.com/ekmett/exceptions.git nofib nofib - - +libraries/semaphore-compat - - - libraries/stm - - ssh://git at github.com/haskell/stm.git . - ghc.git - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5c8731244bc13a3d813d2a4d53b3188b28dc8355 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5c8731244bc13a3d813d2a4d53b3188b28dc8355 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 22:34:36 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 20 Apr 2023 18:34:36 -0400 Subject: [Git][ghc/ghc][master] 2 commits: rts: Initialize Array# header in listThreads# Message-ID: <6441bdfcb5e25_178e745225fba0785031@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - 3 changed files: - rts/Threads.c - + testsuite/tests/primops/should_run/T23071.hs - testsuite/tests/primops/should_run/all.T Changes: ===================================== rts/Threads.c ===================================== @@ -872,6 +872,7 @@ StgMutArrPtrs *listThreads(Capability *cap) const StgWord size = n_threads + mutArrPtrsCardTableSize(n_threads); StgMutArrPtrs *arr = (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size); + SET_HDR(arr, &stg_MUT_ARR_PTRS_DIRTY_info, CCS_SYSTEM); TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0); arr->ptrs = n_threads; arr->size = size; ===================================== testsuite/tests/primops/should_run/T23071.hs ===================================== @@ -0,0 +1,5 @@ +import Control.Monad +import GHC.Conc.Sync + +main = replicateM_ 1000000 $ listThreads >>= print + ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -60,3 +60,4 @@ test('UnliftedTVar2', normal, compile_and_run, ['']) test('UnliftedWeakPtr', normal, compile_and_run, ['']) test('T21624', normal, compile_and_run, ['']) +test('T23071', ignore_stdout, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c8731244bc13a3d813d2a4d53b3188b28dc8355...1db30fe1dd38dd8ffedfadf3845706fcde02933b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c8731244bc13a3d813d2a4d53b3188b28dc8355...1db30fe1dd38dd8ffedfadf3845706fcde02933b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 23:54:42 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 19:54:42 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6441d0c2c3a19_178e7453e402707873e1@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 74a5718e by Apoorv Ingle at 2023-04-20T18:54:27-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 3 changed files: - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Gen/App.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,31 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +-- warnUnusedBindValue fun arg arg_ty +-- -- | is_gen_then (unLoc fun) +-- = warnDiscardedDoBindings arg arg_ty +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this expr a compiler generated (>>) + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L (SrcSpanAnn _ l) f) = f `hasKey` thenMClassOpKey -- && isNoSrcSpan l + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74a5718ef2f56d82dc8722146ea6bef26341b02d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74a5718ef2f56d82dc8722146ea6bef26341b02d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 20 23:55:08 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 19:55:08 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6441d0dcd6d3f_178e7453e2aa247878a6@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: b27bd49f by Apoorv Ingle at 2023-04-20T18:55:02-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 3 changed files: - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Gen/App.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,31 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +-- warnUnusedBindValue fun arg arg_ty +-- -- | is_gen_then (unLoc fun) +-- = warnDiscardedDoBindings arg arg_ty +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this expr a compiler generated (>>) + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L _ f) = f `hasKey` thenMClassOpKey -- && isNoSrcSpan l + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b27bd49f81a399e3d73f929efd2409d73bb705f5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b27bd49f81a399e3d73f929efd2409d73bb705f5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 00:09:10 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 20:09:10 -0400 Subject: [Git][ghc/ghc][wip/expand-do] 112 commits: Make exprIsConApp_maybe a bit cleverer Message-ID: <6441d426dc93d_178e7453fb057478873e@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - 4d1360f2 by Apoorv Ingle at 2023-04-20T19:04:34-05:00 HsExpand for HsDo Fixes for #18324 - fixed rec do blocks to use mfix - make sure fail is used for pattern match failures in bind statments - - - - - 4a637b38 by Apoorv Ingle at 2023-04-20T19:06:28-05:00 move expand_do_stmts GHC.Tc.Match so that we can type check patterns and determine more accurately if we need to generate a fail block - - - - - 0f27e795 by Apoorv Ingle at 2023-04-20T19:06:31-05:00 do stmt expansion for Applicative Do - - - - - d587a706 by Apoorv Ingle at 2023-04-20T19:06:31-05:00 expansion of a bind statement may not be as easy as it looks. T18324b.hs is a an example. I think its some delicate interaction between quick look and type families - - - - - 54a24d20 by Apoorv Ingle at 2023-04-20T19:06:32-05:00 do not add explicit return for `mfix` mdo blocks. This whole last stmt business is very messy. - - - - - fd61ef1f by Apoorv Ingle at 2023-04-20T19:06:32-05:00 wrap the mfix function arg tuple in a lazy pattern so that we do not go in a recursive loop - - - - - 3f409570 by Apoorv Ingle at 2023-04-20T19:06:32-05:00 carry over some location info into the expanded expresion - - - - - 76226706 by Apoorv Ingle at 2023-04-20T19:08:34-05:00 trying to add warnings for unused bindings at type checking rather than HsToCore. Current state is that spurious warnings are generated - - - - - 2c547f77 by Apoorv Ingle at 2023-04-20T19:08:46-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - .gitmodules - cabal.project-reinstall - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/LateCC.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/ConstantFold.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b27bd49f81a399e3d73f929efd2409d73bb705f5...2c547f77e65815f6b86c8a3f55828e1c1569bd88 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b27bd49f81a399e3d73f929efd2409d73bb705f5...2c547f77e65815f6b86c8a3f55828e1c1569bd88 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 00:22:44 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 20:22:44 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6441d754ea3d9_178e745490fda47894b5@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 22e9aebb by Apoorv Ingle at 2023-04-20T19:22:17-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 7 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -2011,13 +2011,6 @@ matchDoContextErrString (MDoExpr m) = prependQualified m (text "'mdo' block") matchDoContextErrString ListComp = text "list comprehension" matchDoContextErrString MonadComp = text "monad comprehension" -instance Outputable HsDoFlavour where - ppr (DoExpr m) = text "DoExpr" <+> parens (ppr m) - ppr (MDoExpr m) = text "MDoExpr" <+> parens (ppr m) - ppr GhciStmtCtxt = text "GhciStmtCtxt" - ppr ListComp = text "ListComp" - ppr MonadComp = text "MonadComp" - pprMatchInCtxt :: (OutputableBndrId idR, Outputable body) => Match (GhcPass idR) body -> SDoc pprMatchInCtxt match = hang (text "In" <+> pprMatchContext (m_ctxt match) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,29 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + -- retrieve the location info and the head of the application + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this id a compiler generated (>>) with expanded do + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L _ f) = f `hasKey` thenMClassOpKey + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1304,7 +1304,6 @@ instance Diagnostic TcRnMessage where TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement" , text "in" <+> pprAStmtContext ctxt ] - TcRnUnUsedDoBind ty -> mkSimpleDecorated $ pprBadMonadBind ty TcRnIllegalTupleSection -> mkSimpleDecorated $ text "Illegal tuple section" TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $ @@ -2136,8 +2135,6 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnLastStmtNotExpr{} -> ErrorWithoutFlag - TcRnUnUsedDoBind{} - -> WarningWithFlag Opt_WarnUnusedDoBind TcRnUnexpectedStatementInContext{} -> ErrorWithoutFlag TcRnSectionWithoutParentheses{} @@ -2721,8 +2718,6 @@ instance Diagnostic TcRnMessage where -> noHints TcRnLastStmtNotExpr{} -> noHints - TcRnUnUsedDoBind {} - -> noHints TcRnUnexpectedStatementInContext _ _ mExt | Nothing <- mExt -> noHints | Just ext <- mExt -> [suggestExtension ext] @@ -5039,6 +5034,50 @@ pprPatSynInvalidRhsReason = \case text "Pattern" <+> quotes (ppr p) <+> text "is not invertible" PatSynUnboundVar var -> quotes (ppr var) <+> text "is not bound by the LHS of the pattern synonym" +pprBadFieldAnnotationReason :: BadFieldAnnotationReason -> SDoc +pprBadFieldAnnotationReason = \case + LazyFieldsDisabled -> + text "Lazy field annotations (~) are disabled" + UnpackWithoutStrictness -> + text "UNPACK pragma lacks '!'" + BackpackUnpackAbstractType -> + text "Ignoring unusable UNPACK pragma" + +pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc +pprSuperclassCycleDetail = \case + SCD_HeadTyVar pred -> + hang (text "one of whose superclass constraints is headed by a type variable:") + 2 (quotes (ppr pred)) + SCD_HeadTyFam pred -> + hang (text "one of whose superclass constraints is headed by a type family:") + 2 (quotes (ppr pred)) + SCD_Superclass cls -> + text "one of whose superclasses is" <+> quotes (ppr cls) + +pprRoleValidationFailedReason :: Role -> RoleValidationFailedReason -> SDoc +pprRoleValidationFailedReason role = \case + TyVarRoleMismatch tv role' -> + text "type variable" <+> quotes (ppr tv) <+> + text "cannot have role" <+> ppr role <+> + text "because it was assigned role" <+> ppr role' + TyVarMissingInEnv tv -> + text "type variable" <+> quotes (ppr tv) <+> text "missing in environment" + BadCoercionRole co -> + text "coercion" <+> ppr co <+> text "has bad role" <+> ppr role + +pprDisabledClassExtension :: Class -> DisabledClassExtension -> SDoc +pprDisabledClassExtension cls = \case + MultiParamDisabled n -> + text howMany <+> text "parameters for class" <+> quotes (ppr cls) + where + howMany | n == 0 = "No" + | otherwise = "Too many" + FunDepsDisabled -> + text "Fundeps in class" <+> quotes (ppr cls) + ConstrainedClassMethodsDisabled sel_id pred -> + vcat [ hang (text "Constraint" <+> quotes (ppr pred) + <+> text "in the type of" <+> quotes (ppr sel_id)) + 2 (text "constrains only the class type variables")] pprBadMonadBind :: Type -> SDoc pprBadMonadBind elt_ty ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2903,17 +2903,6 @@ data TcRnMessage where -> Maybe LangExt.Extension -> TcRnMessage - {-| A do statment that discards a non-unit value - Example: do return 10 -- value discarded - return 10 - - Test cases: testsuite/tests/deSugar/should_compile/T3263-2 - - -} - TcRnUnUsedDoBind - :: Type - -> TcRnMessage - {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section without enabling the TupleSections extension. ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -430,12 +430,15 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219 GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232 GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814 - GhcDiagnosticCode "TcRnUnUsedDoBind" = 61315 GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026 GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880 GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730 GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155 GhcDiagnosticCode "TcRnTermNameInType" = 37479 + GhcDiagnosticCode "TcRnUnexpectedKindVar" = 12875 + GhcDiagnosticCode "TcRnNegativeNumTypeLiteral" = 93632 + GhcDiagnosticCode "TcRnUnusedQuantifiedTypeVar" = 54180 + GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957 GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716 GhcDiagnosticCode "TcRnWarnDefaulting" = 18042 ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22e9aebb7f1d518a24483a818a91dd7d5897fd78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/22e9aebb7f1d518a24483a818a91dd7d5897fd78 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 00:23:37 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 20:23:37 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6441d7893d391_178e745490fda47901dd@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 26ceda8b by Apoorv Ingle at 2023-04-20T19:23:26-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 8 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -2011,13 +2011,6 @@ matchDoContextErrString (MDoExpr m) = prependQualified m (text "'mdo' block") matchDoContextErrString ListComp = text "list comprehension" matchDoContextErrString MonadComp = text "monad comprehension" -instance Outputable HsDoFlavour where - ppr (DoExpr m) = text "DoExpr" <+> parens (ppr m) - ppr (MDoExpr m) = text "MDoExpr" <+> parens (ppr m) - ppr GhciStmtCtxt = text "GhciStmtCtxt" - ppr ListComp = text "ListComp" - ppr MonadComp = text "MonadComp" - pprMatchInCtxt :: (OutputableBndrId idR, Outputable body) => Match (GhcPass idR) body -> SDoc pprMatchInCtxt match = hang (text "In" <+> pprMatchContext (m_ctxt match) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,29 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + -- retrieve the location info and the head of the application + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this id a compiler generated (>>) with expanded do + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L _ f) = f `hasKey` thenMClassOpKey + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1304,7 +1304,6 @@ instance Diagnostic TcRnMessage where TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement" , text "in" <+> pprAStmtContext ctxt ] - TcRnUnUsedDoBind ty -> mkSimpleDecorated $ pprBadMonadBind ty TcRnIllegalTupleSection -> mkSimpleDecorated $ text "Illegal tuple section" TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $ @@ -2136,8 +2135,6 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnLastStmtNotExpr{} -> ErrorWithoutFlag - TcRnUnUsedDoBind{} - -> WarningWithFlag Opt_WarnUnusedDoBind TcRnUnexpectedStatementInContext{} -> ErrorWithoutFlag TcRnSectionWithoutParentheses{} @@ -2721,8 +2718,6 @@ instance Diagnostic TcRnMessage where -> noHints TcRnLastStmtNotExpr{} -> noHints - TcRnUnUsedDoBind {} - -> noHints TcRnUnexpectedStatementInContext _ _ mExt | Nothing <- mExt -> noHints | Just ext <- mExt -> [suggestExtension ext] @@ -5039,6 +5034,50 @@ pprPatSynInvalidRhsReason = \case text "Pattern" <+> quotes (ppr p) <+> text "is not invertible" PatSynUnboundVar var -> quotes (ppr var) <+> text "is not bound by the LHS of the pattern synonym" +pprBadFieldAnnotationReason :: BadFieldAnnotationReason -> SDoc +pprBadFieldAnnotationReason = \case + LazyFieldsDisabled -> + text "Lazy field annotations (~) are disabled" + UnpackWithoutStrictness -> + text "UNPACK pragma lacks '!'" + BackpackUnpackAbstractType -> + text "Ignoring unusable UNPACK pragma" + +pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc +pprSuperclassCycleDetail = \case + SCD_HeadTyVar pred -> + hang (text "one of whose superclass constraints is headed by a type variable:") + 2 (quotes (ppr pred)) + SCD_HeadTyFam pred -> + hang (text "one of whose superclass constraints is headed by a type family:") + 2 (quotes (ppr pred)) + SCD_Superclass cls -> + text "one of whose superclasses is" <+> quotes (ppr cls) + +pprRoleValidationFailedReason :: Role -> RoleValidationFailedReason -> SDoc +pprRoleValidationFailedReason role = \case + TyVarRoleMismatch tv role' -> + text "type variable" <+> quotes (ppr tv) <+> + text "cannot have role" <+> ppr role <+> + text "because it was assigned role" <+> ppr role' + TyVarMissingInEnv tv -> + text "type variable" <+> quotes (ppr tv) <+> text "missing in environment" + BadCoercionRole co -> + text "coercion" <+> ppr co <+> text "has bad role" <+> ppr role + +pprDisabledClassExtension :: Class -> DisabledClassExtension -> SDoc +pprDisabledClassExtension cls = \case + MultiParamDisabled n -> + text howMany <+> text "parameters for class" <+> quotes (ppr cls) + where + howMany | n == 0 = "No" + | otherwise = "Too many" + FunDepsDisabled -> + text "Fundeps in class" <+> quotes (ppr cls) + ConstrainedClassMethodsDisabled sel_id pred -> + vcat [ hang (text "Constraint" <+> quotes (ppr pred) + <+> text "in the type of" <+> quotes (ppr sel_id)) + 2 (text "constrains only the class type variables")] pprBadMonadBind :: Type -> SDoc pprBadMonadBind elt_ty ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2903,17 +2903,6 @@ data TcRnMessage where -> Maybe LangExt.Extension -> TcRnMessage - {-| A do statment that discards a non-unit value - Example: do return 10 -- value discarded - return 10 - - Test cases: testsuite/tests/deSugar/should_compile/T3263-2 - - -} - TcRnUnUsedDoBind - :: Type - -> TcRnMessage - {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section without enabling the TupleSections extension. ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -328,7 +327,7 @@ tcApp rn_expr exp_res_ty vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args - + -- Instantiate ; do_ql <- wantQuickLook rn_fun ; (delta, inst_args, app_res_rho) <- tcInstFun do_ql True fun fun_sigma rn_args @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -1238,7 +1238,7 @@ expand_do_stmts do_or_lc ((L _ (BindStmt xbsrn pat e)): lstmts) ] | otherwise = -- just use the Prelude.>>= TODO: Necessary? --- stmts ~~> stmts' +-- stmts ~~> stmts' -- ------------------------------------------------------- -- pat <- e ; stmts ~~> (Prelude.>>=) e (\ pat -> stmts') do traceTc "expand_do_stmts: generic binop" empty ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -430,12 +430,15 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219 GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232 GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814 - GhcDiagnosticCode "TcRnUnUsedDoBind" = 61315 GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026 GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880 GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730 GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155 GhcDiagnosticCode "TcRnTermNameInType" = 37479 + GhcDiagnosticCode "TcRnUnexpectedKindVar" = 12875 + GhcDiagnosticCode "TcRnNegativeNumTypeLiteral" = 93632 + GhcDiagnosticCode "TcRnUnusedQuantifiedTypeVar" = 54180 + GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957 GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716 GhcDiagnosticCode "TcRnWarnDefaulting" = 18042 ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26ceda8b61582ea23a23f9fee4bc9ed59c62235d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26ceda8b61582ea23a23f9fee4bc9ed59c62235d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 00:24:15 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 20 Apr 2023 20:24:15 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6441d7af2cb51_178e745497808479063@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 2f16025d by Apoorv Ingle at 2023-04-20T19:24:03-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 8 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -2011,13 +2011,6 @@ matchDoContextErrString (MDoExpr m) = prependQualified m (text "'mdo' block") matchDoContextErrString ListComp = text "list comprehension" matchDoContextErrString MonadComp = text "monad comprehension" -instance Outputable HsDoFlavour where - ppr (DoExpr m) = text "DoExpr" <+> parens (ppr m) - ppr (MDoExpr m) = text "MDoExpr" <+> parens (ppr m) - ppr GhciStmtCtxt = text "GhciStmtCtxt" - ppr ListComp = text "ListComp" - ppr MonadComp = text "MonadComp" - pprMatchInCtxt :: (OutputableBndrId idR, Outputable body) => Match (GhcPass idR) body -> SDoc pprMatchInCtxt match = hang (text "In" <+> pprMatchContext (m_ctxt match) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,29 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + -- retrieve the location info and the head of the application + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this id a compiler generated (>>) with expanded do + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L _ f) = f `hasKey` thenMClassOpKey + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1304,7 +1304,6 @@ instance Diagnostic TcRnMessage where TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement" , text "in" <+> pprAStmtContext ctxt ] - TcRnUnUsedDoBind ty -> mkSimpleDecorated $ pprBadMonadBind ty TcRnIllegalTupleSection -> mkSimpleDecorated $ text "Illegal tuple section" TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $ @@ -2136,8 +2135,6 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnLastStmtNotExpr{} -> ErrorWithoutFlag - TcRnUnUsedDoBind{} - -> WarningWithFlag Opt_WarnUnusedDoBind TcRnUnexpectedStatementInContext{} -> ErrorWithoutFlag TcRnSectionWithoutParentheses{} @@ -2721,8 +2718,6 @@ instance Diagnostic TcRnMessage where -> noHints TcRnLastStmtNotExpr{} -> noHints - TcRnUnUsedDoBind {} - -> noHints TcRnUnexpectedStatementInContext _ _ mExt | Nothing <- mExt -> noHints | Just ext <- mExt -> [suggestExtension ext] @@ -5039,8 +5034,47 @@ pprPatSynInvalidRhsReason = \case text "Pattern" <+> quotes (ppr p) <+> text "is not invertible" PatSynUnboundVar var -> quotes (ppr var) <+> text "is not bound by the LHS of the pattern synonym" - -pprBadMonadBind :: Type -> SDoc -pprBadMonadBind elt_ty - = hang (text "A do-notation statement discarded a result of type") - 2 (quotes (ppr elt_ty)) +pprBadFieldAnnotationReason :: BadFieldAnnotationReason -> SDoc +pprBadFieldAnnotationReason = \case + LazyFieldsDisabled -> + text "Lazy field annotations (~) are disabled" + UnpackWithoutStrictness -> + text "UNPACK pragma lacks '!'" + BackpackUnpackAbstractType -> + text "Ignoring unusable UNPACK pragma" + +pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc +pprSuperclassCycleDetail = \case + SCD_HeadTyVar pred -> + hang (text "one of whose superclass constraints is headed by a type variable:") + 2 (quotes (ppr pred)) + SCD_HeadTyFam pred -> + hang (text "one of whose superclass constraints is headed by a type family:") + 2 (quotes (ppr pred)) + SCD_Superclass cls -> + text "one of whose superclasses is" <+> quotes (ppr cls) + +pprRoleValidationFailedReason :: Role -> RoleValidationFailedReason -> SDoc +pprRoleValidationFailedReason role = \case + TyVarRoleMismatch tv role' -> + text "type variable" <+> quotes (ppr tv) <+> + text "cannot have role" <+> ppr role <+> + text "because it was assigned role" <+> ppr role' + TyVarMissingInEnv tv -> + text "type variable" <+> quotes (ppr tv) <+> text "missing in environment" + BadCoercionRole co -> + text "coercion" <+> ppr co <+> text "has bad role" <+> ppr role + +pprDisabledClassExtension :: Class -> DisabledClassExtension -> SDoc +pprDisabledClassExtension cls = \case + MultiParamDisabled n -> + text howMany <+> text "parameters for class" <+> quotes (ppr cls) + where + howMany | n == 0 = "No" + | otherwise = "Too many" + FunDepsDisabled -> + text "Fundeps in class" <+> quotes (ppr cls) + ConstrainedClassMethodsDisabled sel_id pred -> + vcat [ hang (text "Constraint" <+> quotes (ppr pred) + <+> text "in the type of" <+> quotes (ppr sel_id)) + 2 (text "constrains only the class type variables")] ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2903,17 +2903,6 @@ data TcRnMessage where -> Maybe LangExt.Extension -> TcRnMessage - {-| A do statment that discards a non-unit value - Example: do return 10 -- value discarded - return 10 - - Test cases: testsuite/tests/deSugar/should_compile/T3263-2 - - -} - TcRnUnUsedDoBind - :: Type - -> TcRnMessage - {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section without enabling the TupleSections extension. ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -328,7 +327,7 @@ tcApp rn_expr exp_res_ty vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args - + -- Instantiate ; do_ql <- wantQuickLook rn_fun ; (delta, inst_args, app_res_rho) <- tcInstFun do_ql True fun fun_sigma rn_args @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -1238,7 +1238,7 @@ expand_do_stmts do_or_lc ((L _ (BindStmt xbsrn pat e)): lstmts) ] | otherwise = -- just use the Prelude.>>= TODO: Necessary? --- stmts ~~> stmts' +-- stmts ~~> stmts' -- ------------------------------------------------------- -- pat <- e ; stmts ~~> (Prelude.>>=) e (\ pat -> stmts') do traceTc "expand_do_stmts: generic binop" empty ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -430,12 +430,15 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219 GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232 GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814 - GhcDiagnosticCode "TcRnUnUsedDoBind" = 61315 GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026 GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880 GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730 GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155 GhcDiagnosticCode "TcRnTermNameInType" = 37479 + GhcDiagnosticCode "TcRnUnexpectedKindVar" = 12875 + GhcDiagnosticCode "TcRnNegativeNumTypeLiteral" = 93632 + GhcDiagnosticCode "TcRnUnusedQuantifiedTypeVar" = 54180 + GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957 GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716 GhcDiagnosticCode "TcRnWarnDefaulting" = 18042 ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f16025d33dc4e7d0f35c0654b8acf55e3c21189 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f16025d33dc4e7d0f35c0654b8acf55e3c21189 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 07:15:31 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Fri, 21 Apr 2023 03:15:31 -0400 Subject: [Git][ghc/ghc][wip/sized-literals] Add sized primitive literal syntax Message-ID: <644238136e836_178e745b364b648097e1@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/sized-literals at Glasgow Haskell Compiler / GHC Commits: 88676302 by Ben Orchard at 2023-04-21T09:06:33+02:00 Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - 26 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Lit.hs - docs/users_guide/9.8.1-notes.rst - + docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/literals.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/exts/stolen_syntax.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - testsuite/tests/driver/T4437.hs - + testsuite/tests/extendedliterals/all.T - + testsuite/tests/extendedliterals/extendedliterals01.hs - + testsuite/tests/extendedliterals/extendedliterals02.hs - + testsuite/tests/extendedliterals/extendedliterals03.hs - + testsuite/tests/extendedliterals/extendedliterals03.stdout - − testsuite/tests/ghci/should_run/SizedLiterals.hs - − testsuite/tests/ghci/should_run/SizedLiteralsA.hs - testsuite/tests/ghci/should_run/all.T - testsuite/tests/printer/Ppr038.hs - utils/check-exact/ExactPrint.hs - utils/haddock Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3745,6 +3745,7 @@ xFlagsDeps = [ flagSpec "ExplicitForAll" LangExt.ExplicitForAll, flagSpec "ExplicitNamespaces" LangExt.ExplicitNamespaces, flagSpec "ExtendedDefaultRules" LangExt.ExtendedDefaultRules, + flagSpec "ExtendedLiterals" LangExt.ExtendedLiterals, flagSpec "FlexibleContexts" LangExt.FlexibleContexts, flagSpec "FlexibleInstances" LangExt.FlexibleInstances, flagSpec "ForeignFunctionInterface" LangExt.ForeignFunctionInterface, ===================================== compiler/GHC/Hs/Lit.hs ===================================== @@ -50,7 +50,13 @@ type instance XHsStringPrim (GhcPass _) = SourceText type instance XHsInt (GhcPass _) = NoExtField type instance XHsIntPrim (GhcPass _) = SourceText type instance XHsWordPrim (GhcPass _) = SourceText +type instance XHsInt8Prim (GhcPass _) = SourceText +type instance XHsInt16Prim (GhcPass _) = SourceText +type instance XHsInt32Prim (GhcPass _) = SourceText type instance XHsInt64Prim (GhcPass _) = SourceText +type instance XHsWord8Prim (GhcPass _) = SourceText +type instance XHsWord16Prim (GhcPass _) = SourceText +type instance XHsWord32Prim (GhcPass _) = SourceText type instance XHsWord64Prim (GhcPass _) = SourceText type instance XHsInteger (GhcPass _) = SourceText type instance XHsRat (GhcPass _) = NoExtField @@ -128,14 +134,20 @@ hsLitNeedsParens p = go go (HsString {}) = False go (HsStringPrim {}) = False go (HsInt _ x) = p > topPrec && il_neg x - go (HsIntPrim {}) = False - go (HsWordPrim {}) = False - go (HsInt64Prim {}) = False - go (HsWord64Prim {}) = False go (HsInteger _ x _) = p > topPrec && x < 0 go (HsRat _ x _) = p > topPrec && fl_neg x go (HsFloatPrim {}) = False go (HsDoublePrim {}) = False + go (HsIntPrim {}) = False + go (HsInt8Prim {}) = False + go (HsInt16Prim {}) = False + go (HsInt32Prim {}) = False + go (HsInt64Prim {}) = False + go (HsWordPrim {}) = False + go (HsWord8Prim {}) = False + go (HsWord16Prim {}) = False + go (HsWord64Prim {}) = False + go (HsWord32Prim {}) = False go (XLit _) = False -- | Convert a literal from one index type to another @@ -147,7 +159,13 @@ convertLit (HsStringPrim a x) = HsStringPrim a x convertLit (HsInt a x) = HsInt a x convertLit (HsIntPrim a x) = HsIntPrim a x convertLit (HsWordPrim a x) = HsWordPrim a x +convertLit (HsInt8Prim a x) = HsInt8Prim a x +convertLit (HsInt16Prim a x) = HsInt16Prim a x +convertLit (HsInt32Prim a x) = HsInt32Prim a x convertLit (HsInt64Prim a x) = HsInt64Prim a x +convertLit (HsWord8Prim a x) = HsWord8Prim a x +convertLit (HsWord16Prim a x) = HsWord16Prim a x +convertLit (HsWord32Prim a x) = HsWord32Prim a x convertLit (HsWord64Prim a x) = HsWord64Prim a x convertLit (HsInteger a x b) = HsInteger a x b convertLit (HsRat a x b) = HsRat a x b @@ -182,8 +200,14 @@ instance Outputable (HsLit (GhcPass p)) where ppr (HsFloatPrim _ f) = ppr f <> primFloatSuffix ppr (HsDoublePrim _ d) = ppr d <> primDoubleSuffix ppr (HsIntPrim st i) = pprWithSourceText st (pprPrimInt i) - ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsInt8Prim st i) = pprWithSourceText st (pprPrimInt8 i) + ppr (HsInt16Prim st i) = pprWithSourceText st (pprPrimInt16 i) + ppr (HsInt32Prim st i) = pprWithSourceText st (pprPrimInt32 i) ppr (HsInt64Prim st i) = pprWithSourceText st (pprPrimInt64 i) + ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsWord8Prim st w) = pprWithSourceText st (pprPrimWord8 w) + ppr (HsWord16Prim st w) = pprWithSourceText st (pprPrimWord16 w) + ppr (HsWord32Prim st w) = pprWithSourceText st (pprPrimWord32 w) ppr (HsWord64Prim st w) = pprWithSourceText st (pprPrimWord64 w) -- in debug mode, print the expression that it's resolved to, too @@ -211,7 +235,13 @@ pmPprHsLit (HsStringPrim _ s) = pprHsBytes s pmPprHsLit (HsInt _ i) = integer (il_value i) pmPprHsLit (HsIntPrim _ i) = integer i pmPprHsLit (HsWordPrim _ w) = integer w +pmPprHsLit (HsInt8Prim _ i) = integer i +pmPprHsLit (HsInt16Prim _ i) = integer i +pmPprHsLit (HsInt32Prim _ i) = integer i pmPprHsLit (HsInt64Prim _ i) = integer i +pmPprHsLit (HsWord8Prim _ w) = integer w +pmPprHsLit (HsWord16Prim _ w) = integer w +pmPprHsLit (HsWord32Prim _ w) = integer w pmPprHsLit (HsWord64Prim _ w) = integer w pmPprHsLit (HsInteger _ i _) = integer i pmPprHsLit (HsRat _ f _) = ppr f ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -77,7 +77,13 @@ hsLitType (HsStringPrim _ _) = addrPrimTy hsLitType (HsInt _ _) = intTy hsLitType (HsIntPrim _ _) = intPrimTy hsLitType (HsWordPrim _ _) = wordPrimTy +hsLitType (HsInt8Prim _ _) = int8PrimTy +hsLitType (HsInt16Prim _ _) = int16PrimTy +hsLitType (HsInt32Prim _ _) = int32PrimTy hsLitType (HsInt64Prim _ _) = int64PrimTy +hsLitType (HsWord8Prim _ _) = word8PrimTy +hsLitType (HsWord16Prim _ _) = word16PrimTy +hsLitType (HsWord32Prim _ _) = word32PrimTy hsLitType (HsWord64Prim _ _) = word64PrimTy hsLitType (HsInteger _ _ ty) = ty hsLitType (HsRat _ _ ty) = ty ===================================== compiler/GHC/HsToCore/Match/Literal.hs ===================================== @@ -106,7 +106,13 @@ dsLit l = do HsCharPrim _ c -> return (Lit (LitChar c)) HsIntPrim _ i -> return (Lit (mkLitIntWrap platform i)) HsWordPrim _ w -> return (Lit (mkLitWordWrap platform w)) + HsInt8Prim _ i -> return (Lit (mkLitInt8Wrap i)) + HsInt16Prim _ i -> return (Lit (mkLitInt16Wrap i)) + HsInt32Prim _ i -> return (Lit (mkLitInt32Wrap i)) HsInt64Prim _ i -> return (Lit (mkLitInt64Wrap i)) + HsWord8Prim _ w -> return (Lit (mkLitWord8Wrap w)) + HsWord16Prim _ w -> return (Lit (mkLitWord16Wrap w)) + HsWord32Prim _ w -> return (Lit (mkLitWord32Wrap w)) HsWord64Prim _ w -> return (Lit (mkLitWord64Wrap w)) -- This can be slow for very large literals. See Note [FractionalLit representation] @@ -455,10 +461,23 @@ getSimpleIntegralLit :: HsLit GhcTc -> Maybe (Integer, Type) getSimpleIntegralLit (HsInt _ IL{ il_value = i }) = Just (i, intTy) getSimpleIntegralLit (HsIntPrim _ i) = Just (i, intPrimTy) getSimpleIntegralLit (HsWordPrim _ i) = Just (i, wordPrimTy) +getSimpleIntegralLit (HsInt8Prim _ i) = Just (i, int8PrimTy) +getSimpleIntegralLit (HsInt16Prim _ i) = Just (i, int16PrimTy) +getSimpleIntegralLit (HsInt32Prim _ i) = Just (i, int32PrimTy) getSimpleIntegralLit (HsInt64Prim _ i) = Just (i, int64PrimTy) +getSimpleIntegralLit (HsWord8Prim _ i) = Just (i, word8PrimTy) +getSimpleIntegralLit (HsWord16Prim _ i) = Just (i, word16PrimTy) +getSimpleIntegralLit (HsWord32Prim _ i) = Just (i, word32PrimTy) getSimpleIntegralLit (HsWord64Prim _ i) = Just (i, word64PrimTy) getSimpleIntegralLit (HsInteger _ i ty) = Just (i, ty) -getSimpleIntegralLit _ = Nothing + +getSimpleIntegralLit HsChar{} = Nothing +getSimpleIntegralLit HsCharPrim{} = Nothing +getSimpleIntegralLit HsString{} = Nothing +getSimpleIntegralLit HsStringPrim{} = Nothing +getSimpleIntegralLit HsRat{} = Nothing +getSimpleIntegralLit HsFloatPrim{} = Nothing +getSimpleIntegralLit HsDoublePrim{} = Nothing -- | Extract the Char if the expression is a Char literal. getLHsCharLit :: LHsExpr GhcTc -> Maybe Char @@ -638,7 +657,13 @@ hsLitKey :: Platform -> HsLit GhcTc -> Literal -- HsLit does not. hsLitKey platform (HsIntPrim _ i) = mkLitIntWrap platform i hsLitKey platform (HsWordPrim _ w) = mkLitWordWrap platform w +hsLitKey _ (HsInt8Prim _ i) = mkLitInt8Wrap i +hsLitKey _ (HsInt16Prim _ i) = mkLitInt16Wrap i +hsLitKey _ (HsInt32Prim _ i) = mkLitInt32Wrap i hsLitKey _ (HsInt64Prim _ i) = mkLitInt64Wrap i +hsLitKey _ (HsWord8Prim _ w) = mkLitWord8Wrap w +hsLitKey _ (HsWord16Prim _ w) = mkLitWord16Wrap w +hsLitKey _ (HsWord32Prim _ w) = mkLitWord32Wrap w hsLitKey _ (HsWord64Prim _ w) = mkLitWord64Wrap w hsLitKey _ (HsCharPrim _ c) = mkLitChar c -- This following two can be slow. See Note [FractionalLit representation] ===================================== compiler/GHC/Parser.y ===================================== @@ -718,6 +718,14 @@ are the most common patterns, rewritten as regular expressions for clarity: PRIMSTRING { L _ (ITprimstring _ _) } PRIMINTEGER { L _ (ITprimint _ _) } PRIMWORD { L _ (ITprimword _ _) } + PRIMINTEGER8 { L _ (ITprimint8 _ _) } + PRIMINTEGER16 { L _ (ITprimint16 _ _) } + PRIMINTEGER32 { L _ (ITprimint32 _ _) } + PRIMINTEGER64 { L _ (ITprimint64 _ _) } + PRIMWORD8 { L _ (ITprimword8 _ _) } + PRIMWORD16 { L _ (ITprimword16 _ _) } + PRIMWORD32 { L _ (ITprimword32 _ _) } + PRIMWORD64 { L _ (ITprimword64 _ _) } PRIMFLOAT { L _ (ITprimfloat _) } PRIMDOUBLE { L _ (ITprimdouble _) } @@ -3876,6 +3884,22 @@ literal :: { Located (HsLit GhcPs) } $ getPRIMINTEGER $1 } | PRIMWORD { sL1 $1 $ HsWordPrim (getPRIMWORDs $1) $ getPRIMWORD $1 } + | PRIMINTEGER8 { sL1 $1 $ HsInt8Prim (getPRIMINTEGER8s $1) + $ getPRIMINTEGER8 $1 } + | PRIMINTEGER16 { sL1 $1 $ HsInt16Prim (getPRIMINTEGER16s $1) + $ getPRIMINTEGER16 $1 } + | PRIMINTEGER32 { sL1 $1 $ HsInt32Prim (getPRIMINTEGER32s $1) + $ getPRIMINTEGER32 $1 } + | PRIMINTEGER64 { sL1 $1 $ HsInt64Prim (getPRIMINTEGER64s $1) + $ getPRIMINTEGER64 $1 } + | PRIMWORD8 { sL1 $1 $ HsWord8Prim (getPRIMWORD8s $1) + $ getPRIMWORD8 $1 } + | PRIMWORD16 { sL1 $1 $ HsWord16Prim (getPRIMWORD16s $1) + $ getPRIMWORD16 $1 } + | PRIMWORD32 { sL1 $1 $ HsWord32Prim (getPRIMWORD32s $1) + $ getPRIMWORD32 $1 } + | PRIMWORD64 { sL1 $1 $ HsWord64Prim (getPRIMWORD64s $1) + $ getPRIMWORD64 $1 } | PRIMCHAR { sL1 $1 $ HsCharPrim (getPRIMCHARs $1) $ getPRIMCHAR $1 } | PRIMSTRING { sL1 $1 $ HsStringPrim (getPRIMSTRINGs $1) @@ -3916,43 +3940,59 @@ bars :: { ([SrcSpan],Int) } -- One or more bars happyError :: P a happyError = srcParseFail -getVARID (L _ (ITvarid x)) = x -getCONID (L _ (ITconid x)) = x -getVARSYM (L _ (ITvarsym x)) = x -getCONSYM (L _ (ITconsym x)) = x -getDO (L _ (ITdo x)) = x -getMDO (L _ (ITmdo x)) = x -getQVARID (L _ (ITqvarid x)) = x -getQCONID (L _ (ITqconid x)) = x -getQVARSYM (L _ (ITqvarsym x)) = x -getQCONSYM (L _ (ITqconsym x)) = x -getIPDUPVARID (L _ (ITdupipvarid x)) = x -getLABELVARID (L _ (ITlabelvarid _ x)) = x -getCHAR (L _ (ITchar _ x)) = x -getSTRING (L _ (ITstring _ x)) = x -getINTEGER (L _ (ITinteger x)) = x -getRATIONAL (L _ (ITrational x)) = x -getPRIMCHAR (L _ (ITprimchar _ x)) = x -getPRIMSTRING (L _ (ITprimstring _ x)) = x -getPRIMINTEGER (L _ (ITprimint _ x)) = x -getPRIMWORD (L _ (ITprimword _ x)) = x -getPRIMFLOAT (L _ (ITprimfloat x)) = x -getPRIMDOUBLE (L _ (ITprimdouble x)) = x -getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) -getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) -getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) +getVARID (L _ (ITvarid x)) = x +getCONID (L _ (ITconid x)) = x +getVARSYM (L _ (ITvarsym x)) = x +getCONSYM (L _ (ITconsym x)) = x +getDO (L _ (ITdo x)) = x +getMDO (L _ (ITmdo x)) = x +getQVARID (L _ (ITqvarid x)) = x +getQCONID (L _ (ITqconid x)) = x +getQVARSYM (L _ (ITqvarsym x)) = x +getQCONSYM (L _ (ITqconsym x)) = x +getIPDUPVARID (L _ (ITdupipvarid x)) = x +getLABELVARID (L _ (ITlabelvarid _ x)) = x +getCHAR (L _ (ITchar _ x)) = x +getSTRING (L _ (ITstring _ x)) = x +getINTEGER (L _ (ITinteger x)) = x +getRATIONAL (L _ (ITrational x)) = x +getPRIMCHAR (L _ (ITprimchar _ x)) = x +getPRIMSTRING (L _ (ITprimstring _ x)) = x +getPRIMINTEGER (L _ (ITprimint _ x)) = x +getPRIMWORD (L _ (ITprimword _ x)) = x +getPRIMINTEGER8 (L _ (ITprimint8 _ x)) = x +getPRIMINTEGER16 (L _ (ITprimint16 _ x)) = x +getPRIMINTEGER32 (L _ (ITprimint32 _ x)) = x +getPRIMINTEGER64 (L _ (ITprimint64 _ x)) = x +getPRIMWORD8 (L _ (ITprimword8 _ x)) = x +getPRIMWORD16 (L _ (ITprimword16 _ x)) = x +getPRIMWORD32 (L _ (ITprimword32 _ x)) = x +getPRIMWORD64 (L _ (ITprimword64 _ x)) = x +getPRIMFLOAT (L _ (ITprimfloat x)) = x +getPRIMDOUBLE (L _ (ITprimdouble x)) = x +getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) +getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) +getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) getCOMPLETE_PRAGs (L _ (ITcomplete_prag x)) = x -getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l - -getINTEGERs (L _ (ITinteger (IL src _ _))) = src -getCHARs (L _ (ITchar src _)) = src -getSTRINGs (L _ (ITstring src _)) = src -getPRIMCHARs (L _ (ITprimchar src _)) = src -getPRIMSTRINGs (L _ (ITprimstring src _)) = src -getPRIMINTEGERs (L _ (ITprimint src _)) = src -getPRIMWORDs (L _ (ITprimword src _)) = src - -getLABELVARIDs (L _ (ITlabelvarid src _)) = src +getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l + +getINTEGERs (L _ (ITinteger (IL src _ _))) = src +getCHARs (L _ (ITchar src _)) = src +getSTRINGs (L _ (ITstring src _)) = src +getPRIMCHARs (L _ (ITprimchar src _)) = src +getPRIMSTRINGs (L _ (ITprimstring src _)) = src +getPRIMINTEGERs (L _ (ITprimint src _)) = src +getPRIMWORDs (L _ (ITprimword src _)) = src +getPRIMINTEGER8s (L _ (ITprimint8 src _)) = src +getPRIMINTEGER16s (L _ (ITprimint16 src _)) = src +getPRIMINTEGER32s (L _ (ITprimint32 src _)) = src +getPRIMINTEGER64s (L _ (ITprimint64 src _)) = src +getPRIMWORD8s (L _ (ITprimword8 src _)) = src +getPRIMWORD16s (L _ (ITprimword16 src _)) = src +getPRIMWORD32s (L _ (ITprimword32 src _)) = src +getPRIMWORD64s (L _ (ITprimword64 src _)) = src + +getLABELVARIDs (L _ (ITlabelvarid src _)) = src -- See Note [Pragma source text] in "GHC.Types.SourceText" for the following getINLINE_PRAGs (L _ (ITinline_prag _ inl _)) = inlineSpecSource inl ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -194,6 +194,10 @@ $docsym = [\| \^ \* \$] @exponent = @numspc [eE] [\-\+]? @decimal @bin_exponent = @numspc [pP] [\-\+]? @decimal + at binarylit = 0[bB] @numspc @binary + at octallit = 0[oO] @numspc @octal + at hexadecimallit = 0[xX] @numspc @hexadecimal + @qual = (@conid \.)+ @qvarid = @qual @varid @qconid = @qual @conid @@ -517,15 +521,15 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- <0> { -- Normal integral literals (:: Num a => a, from Integer) - @decimal { tok_num positive 0 0 decimal } - 0[bB] @numspc @binary / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } - 0[oO] @numspc @octal { tok_num positive 2 2 octal } - 0[xX] @numspc @hexadecimal { tok_num positive 2 2 hexadecimal } - @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } - @negative 0[bB] @numspc @binary / { negLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } - @negative 0[oO] @numspc @octal / { negLitPred } { tok_num negative 3 3 octal } - @negative 0[xX] @numspc @hexadecimal / { negLitPred } { tok_num negative 3 3 hexadecimal } + @decimal { tok_num positive 0 0 decimal } + @binarylit / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } + @octallit { tok_num positive 2 2 octal } + @hexadecimallit { tok_num positive 2 2 hexadecimal } + @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } + @negative @binarylit / { negLitPred `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } + @negative @octallit / { negLitPred } { tok_num negative 3 3 octal } + @negative @hexadecimallit / { negLitPred } { tok_num negative 3 3 hexadecimal } -- Normal rational literals (:: Fractional a => a, from Rational) @floating_point { tok_frac 0 tok_float } @@ -540,31 +544,116 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- Unboxed ints (:: Int#) and words (:: Word#) -- It's simpler (and faster?) to give separate cases to the negatives, -- especially considering octal/hexadecimal prefixes. - @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } - 0[bB] @numspc @binary \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } - 0[oO] @numspc @octal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } - 0[xX] @numspc @hexadecimal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } - @negative @decimal \# / { negHashLitPred } { tok_primint negative 1 2 decimal } - @negative 0[bB] @numspc @binary \# / { negHashLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } - @negative 0[oO] @numspc @octal \# / { negHashLitPred } { tok_primint negative 3 4 octal } - @negative 0[xX] @numspc @hexadecimal \# - / { negHashLitPred } { tok_primint negative 3 4 hexadecimal } - - @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } - 0[bB] @numspc @binary \# \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } - 0[oO] @numspc @octal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } - 0[xX] @numspc @hexadecimal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } + @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } + @binarylit \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } + @octallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } + @hexadecimallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } + @negative @decimal \# / { negHashLitPred MagicHashBit } { tok_primint negative 1 2 decimal } + @negative @binarylit \# / { negHashLitPred MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } + @negative @octallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 octal } + @negative @hexadecimallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 hexadecimal } + + @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } + @binarylit \# \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } + @octallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } + @hexadecimallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } -- Unboxed floats and doubles (:: Float#, :: Double#) -- prim_{float,double} work with signed literals @floating_point \# / { ifExtension MagicHashBit } { tok_frac 1 tok_primfloat } @floating_point \# \# / { ifExtension MagicHashBit } { tok_frac 2 tok_primdouble } - @negative @floating_point \# / { negHashLitPred } { tok_frac 1 tok_primfloat } - @negative @floating_point \# \# / { negHashLitPred } { tok_frac 2 tok_primdouble } + @negative @floating_point \# / { negHashLitPred MagicHashBit } { tok_frac 1 tok_primfloat } + @negative @floating_point \# \# / { negHashLitPred MagicHashBit } { tok_frac 2 tok_primdouble } + + @decimal \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 0 decimal } + @binarylit \#"Int8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 positive 2 binary } + @octallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 octal } + @hexadecimallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 hexadecimal } + @negative @decimal \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 1 decimal } + @negative @binarylit \#"Int8" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 negative 3 binary } + @negative @octallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 octal } + @negative @hexadecimallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 hexadecimal } + + @decimal \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 0 decimal } + @binarylit \#"Int16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 positive 2 binary } + @octallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 octal } + @hexadecimallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 hexadecimal } + @negative @decimal \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 1 decimal } + @negative @binarylit \#"Int16" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 negative 3 binary } + @negative @octallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 octal } + @negative @hexadecimallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 hexadecimal } + + @decimal \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 0 decimal } + @binarylit \#"Int32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 positive 2 binary } + @octallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 octal } + @hexadecimallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 hexadecimal } + @negative @decimal \#"Int32" / { negHashLitPred ExtendedLiteralsBit } { tok_primint32 negative 1 decimal } + @negative @binarylit \#"Int32" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 negative 3 binary } + @negative @octallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 octal } + @negative @hexadecimallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 hexadecimal } + + @decimal \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 0 decimal } + @binarylit \#"Int64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 positive 2 binary } + @octallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 octal } + @hexadecimallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 hexadecimal } + @negative @decimal \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 1 decimal } + @negative @binarylit \#"Int64" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 negative 3 binary } + @negative @octallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 octal } + @negative @hexadecimallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 hexadecimal } + + @decimal \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 0 4 decimal } + @binarylit \#"Int" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 6 binary } + @octallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 octal } + @hexadecimallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 hexadecimal } + @negative @decimal \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 1 5 decimal } + @negative @binarylit \#"Int" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 7 binary } + @negative @octallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 octal } + @negative @hexadecimallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 hexadecimal } + + @decimal \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 0 decimal } + @binarylit \#"Word8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword8 2 binary } + @octallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 octal } + @hexadecimallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 hexadecimal } + + @decimal \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 0 decimal } + @binarylit \#"Word16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword16 2 binary } + @octallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 octal } + @hexadecimallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 hexadecimal } + + @decimal \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 0 decimal } + @binarylit \#"Word32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword32 2 binary } + @octallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 octal } + @hexadecimallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 hexadecimal } + + @decimal \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 0 decimal } + @binarylit \#"Word64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword64 2 binary } + @octallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 octal } + @hexadecimallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 hexadecimal } + + @decimal \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 0 5 decimal } + @binarylit \#"Word" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 7 binary } + @octallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 octal } + @hexadecimallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 hexadecimal } + } -- Strings and chars are lexed by hand-written code. The reason is @@ -866,6 +955,14 @@ data Token | ITprimstring SourceText ByteString -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimint SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimword SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimfloat FractionalLit | ITprimdouble FractionalLit @@ -1281,10 +1378,10 @@ negLitPred = alexNotPred precededByClosingToken -- Check if we should parse an unboxed negative literal (e.g. -123#) as a single token. -negHashLitPred :: AlexAccPred ExtsBitmap -negHashLitPred = prefix_minus `alexAndPred` magic_hash +negHashLitPred :: ExtBits -> AlexAccPred ExtsBitmap +negHashLitPred ext = prefix_minus `alexAndPred` magic_hash where - magic_hash = ifExtension MagicHashBit + magic_hash = ifExtension ext -- Either MagicHashBit or ExtendedLiteralsBit prefix_minus = -- Note [prefix_minus in negLitPred and negHashLitPred] alexNotPred precededByClosingToken @@ -1829,6 +1926,40 @@ binary = (2,octDecDigit) octal = (8,octDecDigit) hexadecimal = (16,hexDigit) +-- | Helper for defining @IntX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @123#Int8@). +tok_primintX :: (SourceText -> Integer -> Token) + -> Int + -> (Integer -> Integer) + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primintX itint addlen transint transbuf = + tok_integral itint transint transbuf (transbuf+addlen) + +tok_primint8, tok_primint16, tok_primint32, tok_primint64 + :: (Integer -> Integer) + -> Int -> (Integer, (Char->Int)) -> Action +tok_primint8 = tok_primintX ITprimint8 5 +tok_primint16 = tok_primintX ITprimint16 6 +tok_primint32 = tok_primintX ITprimint32 6 +tok_primint64 = tok_primintX ITprimint64 6 + +-- | Helper for defining @WordX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @234#Word8@). +tok_primwordX :: (SourceText -> Integer -> Token) + -> Int + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primwordX itint addlen transbuf = + tok_integral itint positive transbuf (transbuf+addlen) + +tok_primword8, tok_primword16, tok_primword32, tok_primword64 + :: Int -> (Integer, (Char->Int)) -> Action +tok_primword8 = tok_primwordX ITprimword8 6 +tok_primword16 = tok_primwordX ITprimword16 7 +tok_primword32 = tok_primwordX ITprimword32 7 +tok_primword64 = tok_primwordX ITprimword64 7 + -- readSignificandExponentPair can understand negative rationals, exponents, everything. tok_frac :: Int -> (String -> Token) -> Action tok_frac drop f span buf len _buf2 = do @@ -2903,6 +3034,7 @@ data ExtBits | NoLexicalNegationBit -- See Note [Why not LexicalNegationBit] | OverloadedRecordDotBit | OverloadedRecordUpdateBit + | ExtendedLiteralsBit -- Flags that are updated once parsing starts | InRulePragBit @@ -2982,6 +3114,7 @@ mkParserOpts extensionFlags diag_opts supported .|. NoLexicalNegationBit `xoptNotBit` LangExt.LexicalNegation -- See Note [Why not LexicalNegationBit] .|. OverloadedRecordDotBit `xoptBit` LangExt.OverloadedRecordDot .|. OverloadedRecordUpdateBit `xoptBit` LangExt.OverloadedRecordUpdate -- Enable testing via 'getBit OverloadedRecordUpdateBit' in the parser (RecordDotSyntax parsing uses that information). + .|. ExtendedLiteralsBit `xoptBit` LangExt.ExtendedLiterals optBits = HaddockBit `setBitIf` isHaddock .|. RawTokenStreamBit `setBitIf` rawTokStream ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -568,7 +568,13 @@ type family XHsStringPrim x type family XHsInt x type family XHsIntPrim x type family XHsWordPrim x +type family XHsInt8Prim x +type family XHsInt16Prim x +type family XHsInt32Prim x type family XHsInt64Prim x +type family XHsWord8Prim x +type family XHsWord16Prim x +type family XHsWord32Prim x type family XHsWord64Prim x type family XHsInteger x type family XHsRat x ===================================== compiler/Language/Haskell/Syntax/Lit.hs ===================================== @@ -63,8 +63,20 @@ data HsLit x -- ^ literal @Int#@ | HsWordPrim (XHsWordPrim x) {- SourceText -} Integer -- ^ literal @Word#@ + | HsInt8Prim (XHsInt8Prim x) {- SourceText -} Integer + -- ^ literal @Int8#@ + | HsInt16Prim (XHsInt16Prim x) {- SourceText -} Integer + -- ^ literal @Int16#@ + | HsInt32Prim (XHsInt32Prim x) {- SourceText -} Integer + -- ^ literal @Int32#@ | HsInt64Prim (XHsInt64Prim x) {- SourceText -} Integer -- ^ literal @Int64#@ + | HsWord8Prim (XHsWord8Prim x) {- SourceText -} Integer + -- ^ literal @Word8#@ + | HsWord16Prim (XHsWord16Prim x) {- SourceText -} Integer + -- ^ literal @Word16#@ + | HsWord32Prim (XHsWord32Prim x) {- SourceText -} Integer + -- ^ literal @Word32#@ | HsWord64Prim (XHsWord64Prim x) {- SourceText -} Integer -- ^ literal @Word64#@ | HsInteger (XHsInteger x) {- SourceText -} Integer Type @@ -149,4 +161,3 @@ instance Ord OverLitVal where compare (HsIsString _ s1) (HsIsString _ s2) = s1 `lexicalCompareFS` s2 compare (HsIsString _ _) (HsIntegral _) = GT compare (HsIsString _ _) (HsFractional _) = GT - ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -6,6 +6,10 @@ Version 9.8.1 Language ~~~~~~~~ +- There is a new extension :extension:`ExtendedLiterals`, which enables + sized primitive literals, e.g. ``123#Int8`` is a literal of type ``Int8#``. + See the GHC proposal `#451 `_. + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/extended_literals.rst ===================================== @@ -0,0 +1,47 @@ +.. _extended-literals: + +Sized primitive literal syntax +------------------------------ + +.. extension:: ExtendedLiterals + :shortdesc: Enable numeric literal postfix syntax for unboxed integers. + + :since: 9.8.1 + + Allows defining unboxed numeric primitive values through ``#Type`` suffixes + on numeric literals e.g. ``0xFF#Word8 :: Word8#``. + +The :extension:`MagicHash` extension enables some new literals, including ``3# +:: Int#``, ``3## :: Word#``. This does not extend to all unboxed values. For +example, there is no literal syntax for ``Word8#``: you must write something +such as ``wordToWord8 (3## :: Word#) :: Word8#``. + +:extension:`ExtendedLiterals` enables further syntax for defining primitive +numeric literals. Suffix any Haskell integer lexeme with a hash sign ``#`` +followed by a primitive numeric type (without its hash suffix) to obtain a value +of that type. For example, ``0xFF#Word8 :: Word8#``. There must be no spaces +between the parts of the literal. + +The primitive numeric types allowed are: + +- ``Int8#`` +- ``Int16#`` +- ``Int32#`` +- ``Int64#`` +- ``Int#`` +- ``Word8#`` +- ``Word16#`` +- ``Word32#`` +- ``Word64#`` +- ``Word#`` + +All types permit any nonnegative Haskell integer lexeme, e.g. ``70``, ``0x2A``, +``0o1276``, ``0b1010`` (with :extension:`BinaryLiterals`). The signed ``Int`` +types also permit negative integer lexemes. Defining a literal with a value that +can't fit in its requested type will emit an overflow warning by default, the +same as boxed numeric literals. + +As with :extension:`MagicHash`, this extension does not bring anything into +scope, nor change any semantics. The syntax only applies to numeric literals. +You may want to import ``GHC.Exts`` (see :ref:`primitives`) to refer to the +types of the literals you define. ===================================== docs/users_guide/exts/literals.rst ===================================== @@ -10,6 +10,7 @@ Literals binary_literals hex_float_literals num_decimals + extended_literals numeric_underscores overloaded_strings overloaded_labels ===================================== docs/users_guide/exts/primitives.rst ===================================== @@ -19,6 +19,9 @@ your program, you must first import ``GHC.Exts`` to bring them into scope. Many of them have names ending in ``#``, and to mention such names you need the :extension:`MagicHash` extension. +To enable defining literals for other primitive data types, see the +:extension:`ExtendedLiterals` extension. + The primops make extensive use of `unboxed types <#glasgow-unboxed>`__ and `unboxed tuples <#unboxed-tuples>`__, which we briefly summarise here. ===================================== docs/users_guide/exts/stolen_syntax.rst ===================================== @@ -80,6 +80,9 @@ The following syntax is stolen: ⟨varid⟩, ``#``\ ⟨char⟩, ``#``, ⟨string⟩, ``#``, ⟨integer⟩, ``#``, ⟨float⟩, ``#``, ⟨float⟩, ``##`` Stolen by: :extension:`MagicHash` +⟨integer⟩, ``#(Int|Word)(8|16|32|64)?`` + Stolen by: :extension:`ExtendedLiterals` + ``(#``, ``#)`` Stolen by: :extension:`UnboxedTuples` ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -152,6 +152,7 @@ data Extension | OverloadedRecordDot | OverloadedRecordUpdate | TypeAbstractions + | ExtendedLiterals deriving (Eq, Enum, Show, Generic, Bounded) -- 'Ord' and 'Bounded' are provided for GHC API users (see discussions -- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and ===================================== testsuite/tests/driver/T4437.hs ===================================== @@ -37,7 +37,8 @@ check title expected got -- See Note [Adding a language extension] in compiler/GHC/Driver/Session.hs. expectedGhcOnlyExtensions :: [String] expectedGhcOnlyExtensions = - [ "TypeAbstractions" + [ "TypeAbstractions", + "ExtendedLiterals" ] expectedCabalOnlyExtensions :: [String] ===================================== testsuite/tests/extendedliterals/all.T ===================================== @@ -0,0 +1,3 @@ +test('extendedliterals01', normal, compile, ['']) +test('extendedliterals02', normal, compile, ['']) +test('extendedliterals03', [extra_ways(['ghci'])], compile_and_run, ['']) ===================================== testsuite/tests/extendedliterals/extendedliterals01.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE UnboxedSums, UnboxedTuples #-} + +-- needed on 32bit +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +import GHC.Exts +import GHC.Word +import GHC.Int + +-- Precise 'Int8#'/'Int8' range tests +exI8g1, exI8g2, exI8g3 :: Int8 +exI8g1 = I8# 0x00#Int8 +exI8g2 = I8# 0x7F#Int8 +exI8g3 = I8# -0x80#Int8 + +-- Showcase various syntax for equivalent 'Int' terms +exIg1, exIg2, exIg3 :: Int +exIg1 = 0x7FFFFFFFFFFFFFFF +exIg2 = I# 0x7FFFFFFFFFFFFFFF# +exIg3 = I# 0x7FFFFFFFFFFFFFFF#Int + +-- Motivating example: unboxed 'Word8#' parsing +data CEnum = Cons00 | Cons01 | ConsFF deriving Show +parseCEnum :: Word8# -> (# (##) | CEnum #) +parseCEnum = \case 0x00#Word8 -> (# | Cons00 #) + 0x01#Word8 -> (# | Cons01 #) + 0xFF#Word8 -> (# | ConsFF #) + _ -> (# (##) | #) + +w8ToBool# :: Word8# -> Int# +w8ToBool# = \case 0#Word8 -> 0# + _ -> 1# + +i8IsPole# :: Int8# -> Int# +i8IsPole# = \case 0x7F#Int8 -> 1# + -0x80#Int8 -> 1# + _ -> 0# ===================================== testsuite/tests/extendedliterals/extendedliterals02.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +--import GHC.Exts +import GHC.Int + +-- Overflowed 'Int8#' literals +exI8b1, exI8b2, exI8b3, exI8b4, exI8b5 :: Int8 +exI8b1 = I8# 0x80#Int8 +exI8b2 = I8# -0x81#Int8 +exI8b3 = I8# 0xFF#Int8 +exI8b4 = I8# -0xFF#Int8 +exI8b5 = I8# 0xFFFFFFFFFFFFFFFF#Int8 ===================================== testsuite/tests/extendedliterals/extendedliterals03.hs ===================================== @@ -0,0 +1,260 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +import GHC.Word +import GHC.Int +import GHC.Exts + +main = do + print (W8# (fibw8 6#Word8), + W16# (fibw16 6#Word16), + W32# (fibw32 6#Word32), + W64# (fibw64 6#Word64)) + print (I8# (fibi8 6#Int8), + I16# (fibi16 6#Int16), + I32# (fibi32 6#Int32), + I64# (fibi64 6#Int64)) + + print (W64# 0xFFFFFFFFFFFFFFFF#Word64) + print (I64# 0x7FFFFFFFFFFFFFFF#Int64) + print (I64# -0x8000000000000000#Int64) + print (W64# (x () `timesWord64#` y ())) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> False + 276447233#Word64 -> False + 276447234#Word64 -> False + 276047234#Word64 -> False + 5000000004#Word64 -> False + 100000000000000#Word64 -> True + _ -> False) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> True + _ -> False) + + print [ W8# (branchi8 0#Int8) + , W8# (branchi8 1#Int8) + , W8# (branchi8 -1#Int8) + , W8# (branchi8 126#Int8) + , W8# (branchi8 127#Int8) + , W8# (branchi8 -127#Int8) + , W8# (branchi8 -128#Int8) + , W8# (branchi8 2#Int8) + ] + + print [ W16# (branchi16 0#Int16) + , W16# (branchi16 1#Int16) + , W16# (branchi16 (-1#Int16)) + , W16# (branchi16 32767#Int16) + , W16# (branchi16 32766#Int16) + , W16# (branchi16 (-32768#Int16)) + , W16# (branchi16 (-32767#Int16)) + , W16# (branchi16 2#Int16) + ] + + print [ W32# (branchi32 0#Int32) + , W32# (branchi32 1#Int32) + , W32# (branchi32 (-1#Int32)) + , W32# (branchi32 2147483646#Int32) + , W32# (branchi32 2147483647#Int32) + , W32# (branchi32 (-2147483648#Int32)) + , W32# (branchi32 (-2147483647#Int32)) + , W32# (branchi32 2#Int32) + ] + + print [ W64# (branchi64 0#Int64) + , W64# (branchi64 1#Int64) + , W64# (branchi64 (-1#Int64)) + , W64# (branchi64 2147483647#Int64) + , W64# (branchi64 2147483648#Int64) + , W64# (branchi64 4294967297#Int64) + , W64# (branchi64 (-2147483648#Int64)) + , W64# (branchi64 (-2147483649#Int64)) + , W64# (branchi64 (-4294967295#Int64)) + , W64# (branchi64 9223372036854775807#Int64) + , W64# (branchi64 9223372036854775806#Int64) + , W64# (branchi64 (-9223372036854775808#Int64)) + , W64# (branchi64 (-9223372036854775807#Int64)) + , W64# (branchi64 2#Int64) + ] + + print [ I8# (branchw8 0#Word8) + , I8# (branchw8 1#Word8) + , I8# (branchw8 254#Word8) + , I8# (branchw8 255#Word8) + , I8# (branchw8 2#Word8) + ] + + print [ I16# (branchw16 0#Word16) + , I16# (branchw16 1#Word16) + , I16# (branchw16 255#Word16) + , I16# (branchw16 256#Word16) + , I16# (branchw16 65534#Word16) + , I16# (branchw16 65535#Word16) + , I16# (branchw16 2#Word16) + ] + + print [ I32# (branchw32 0#Word32) + , I32# (branchw32 1#Word32) + , I32# (branchw32 65534#Word32) + , I32# (branchw32 65535#Word32) + , I32# (branchw32 65536#Word32) + , I32# (branchw32 4294967295#Word32) + , I32# (branchw32 4294967294#Word32) + , I32# (branchw32 4294967293#Word32) + , I32# (branchw32 2#Word32) + ] + + print [ I64# (branchw64 0#Word64) + , I64# (branchw64 1#Word64) + , I64# (branchw64 65536#Word64) + , I64# (branchw64 4294967295#Word64) + , I64# (branchw64 4294967296#Word64) + , I64# (branchw64 4294967297#Word64) + , I64# (branchw64 18446744073709551615#Word64) + , I64# (branchw64 18446744073709551614#Word64) + , I64# (branchw64 18446744073709551613#Word64) + , I64# (branchw64 2#Word64) + ] + +fibw8 :: Word8# -> Word8# +fibw8 0#Word8 = 0#Word8 +fibw8 1#Word8 = 1#Word8 +fibw8 n = fibw8 (n `subWord8#` 1#Word8) `plusWord8#` fibw8 (n `subWord8#` 2#Word8) + +fibw16 :: Word16# -> Word16# +fibw16 0#Word16 = 0#Word16 +fibw16 1#Word16 = 1#Word16 +fibw16 n = fibw16 (n `subWord16#` 1#Word16) `plusWord16#` fibw16 (n `subWord16#` 2#Word16) + +fibw32 :: Word32# -> Word32# +fibw32 0#Word32 = 0#Word32 +fibw32 1#Word32 = 1#Word32 +fibw32 n = fibw32 (n `subWord32#` 1#Word32) `plusWord32#` fibw32 (n `subWord32#` 2#Word32) + +fibw64 :: Word64# -> Word64# +fibw64 0#Word64 = 0#Word64 +fibw64 1#Word64 = 1#Word64 +fibw64 n = fibw64 (n `subWord64#` 1#Word64) `plusWord64#` fibw64 (n `subWord64#` 2#Word64) + +-- + +fibi8 :: Int8# -> Int8# +fibi8 0#Int8 = 0#Int8 +fibi8 1#Int8 = 1#Int8 +fibi8 n = fibi8 (n `subInt8#` 1#Int8) `plusInt8#` fibi8 (n `subInt8#` 2#Int8) + +fibi16 :: Int16# -> Int16# +fibi16 0#Int16 = 0#Int16 +fibi16 1#Int16 = 1#Int16 +fibi16 n = fibi16 (n `subInt16#` 1#Int16) `plusInt16#` fibi16 (n `subInt16#` 2#Int16) + +fibi32 :: Int32# -> Int32# +fibi32 0#Int32 = 0#Int32 +fibi32 1#Int32 = 1#Int32 +fibi32 n = fibi32 (n `subInt32#` 1#Int32) `plusInt32#` fibi32 (n `subInt32#` 2#Int32) + +fibi64 :: Int64# -> Int64# +fibi64 0#Int64 = 0#Int64 +fibi64 1#Int64 = 1#Int64 +fibi64 n = fibi64 (n `subInt64#` 1#Int64) `plusInt64#` fibi64 (n `subInt64#` 2#Int64) + +-- + +branchi8 :: Int8# -> Word8# +branchi8 0#Int8 = 1#Word8 +branchi8 1#Int8 = 2#Word8 +branchi8 (-1#Int8) = 3#Word8 +branchi8 126#Int8 = 4#Word8 +branchi8 127#Int8 = 5#Word8 +branchi8 (-127#Int8) = 6#Word8 +branchi8 (-128#Int8) = 7#Word8 +branchi8 _ = 0#Word8 +{-# NOINLINE branchi8 #-} + +branchi16 :: Int16# -> Word16# +branchi16 0#Int16 = 1#Word16 +branchi16 1#Int16 = 2#Word16 +branchi16 (-1#Int16) = 3#Word16 +branchi16 32767#Int16 = 255#Word16 +branchi16 32766#Int16 = 256#Word16 +branchi16 (-32768#Int16) = 65534#Word16 +branchi16 (-32767#Int16) = 65535#Word16 +branchi16 _ = 0#Word16 +{-# NOINLINE branchi16 #-} + +branchi32 :: Int32# -> Word32# +branchi32 0#Int32 = 1#Word32 +branchi32 1#Int32 = 2#Word32 +branchi32 (-1#Int32) = 3#Word32 +branchi32 2147483646#Int32 = 65535#Word32 +branchi32 2147483647#Int32 = 65536#Word32 +branchi32 (-2147483648#Int32) = 4294967294#Word32 +branchi32 (-2147483647#Int32) = 4294967295#Word32 +branchi32 _ = 0#Word32 +{-# NOINLINE branchi32 #-} + +branchi64 :: Int64# -> Word64# +branchi64 0#Int64 = 18446744073709551615#Word64 +branchi64 1#Int64 = 2147483648#Word64 +branchi64 (-1#Int64) = 4294967296#Word64 +branchi64 2147483647#Int64 = 4294967297#Word64 +branchi64 2147483648#Int64 = 9#Word64 +branchi64 4294967297#Int64 = 1#Word64 +branchi64 (-2147483648#Int64) = 18446744073709551614#Word64 +branchi64 (-2147483649#Int64) = 3#Word64 +branchi64 (-4294967295#Int64) = 4#Word64 +branchi64 9223372036854775807#Int64 = 5#Word64 +branchi64 9223372036854775806#Int64 = 6#Word64 +branchi64 (-9223372036854775808#Int64) = 7#Word64 +branchi64 (-9223372036854775807#Int64) = 8#Word64 +branchi64 _ = 0#Word64 +{-# NOINLINE branchi64 #-} + +branchw8 :: Word8# -> Int8# +branchw8 0#Word8 = 1#Int8 +branchw8 1#Word8 = (-1#Int8) +branchw8 254#Word8 = 2#Int8 +branchw8 255#Word8 = (-2#Int8) +branchw8 _ = 0#Int8 +{-# NOINLINE branchw8 #-} + +branchw16 :: Word16# -> Int16# +branchw16 0#Word16 = 256#Int16 +branchw16 1#Word16 = (-256#Int16) +branchw16 255#Word16 = 32767#Int16 +branchw16 256#Word16 = (-32768#Int16) +branchw16 65534#Word16 = (-1#Int16) +branchw16 65535#Word16 = 1#Int16 +branchw16 _ = 0#Int16 +{-# NOINLINE branchw16 #-} + +branchw32 :: Word32# -> Int32# +branchw32 0#Word32 = 2147483647#Int32 +branchw32 1#Word32 = (-2147483648#Int32) +branchw32 65534#Word32 = 65535#Int32 +branchw32 65535#Word32 = 65536#Int32 +branchw32 65536#Word32 = (-1#Int32) +branchw32 4294967295#Word32 = (-65536#Int32) +branchw32 4294967294#Word32 = (-65537#Int32) +branchw32 4294967293#Word32 = 1#Int32 +branchw32 _ = 0#Int32 +{-# NOINLINE branchw32 #-} + +branchw64 :: Word64# -> Int64# +branchw64 0#Word64 = 9223372036854775807#Int64 +branchw64 1#Word64 = 2147483648#Int64 +branchw64 65536#Word64 = 4294967296#Int64 +branchw64 4294967295#Word64 = 4294967297#Int64 +branchw64 4294967296#Word64 = (-1#Int64) +branchw64 4294967297#Word64 = 9223372036854775806#Int64 +branchw64 18446744073709551615#Word64 = (-9223372036854775808#Int64) +branchw64 18446744073709551614#Word64 = (-9223372036854775807#Int64) +branchw64 18446744073709551613#Word64 = 1#Int64 +branchw64 _ = 0#Int64 +{-# NOINLINE branchw64 #-} + +x :: () -> Word64# +x () = 2000000000#Word64 +{-# NOINLINE x #-} + +y :: () -> Word64# +y () = 50000#Word64 +{-# NOINLINE y #-} ===================================== testsuite/tests/extendedliterals/extendedliterals03.stdout ===================================== @@ -0,0 +1,16 @@ +(8,8,8,8) +(8,8,8,8) +18446744073709551615 +9223372036854775807 +-9223372036854775808 +100000000000000 +True +False +[1,2,3,4,5,6,7,0] +[1,2,3,255,256,65534,65535,0] +[1,2,3,65535,65536,4294967294,4294967295,0] +[18446744073709551615,2147483648,4294967296,4294967297,9,1,18446744073709551614,3,4,5,6,7,8,0] +[1,-1,2,-2,0] +[256,-256,32767,-32768,-1,1,0] +[2147483647,-2147483648,65535,65536,-1,-65536,-65537,1,0] +[9223372036854775807,2147483648,4294967296,4294967297,-1,9223372036854775806,-9223372036854775808,-9223372036854775807,1,0] ===================================== testsuite/tests/ghci/should_run/SizedLiterals.hs deleted ===================================== @@ -1,117 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} - -import SizedLiteralsA -import Language.Haskell.TH - -{- - - This file is compiled with the GHC flags: - - -O -fbyte-code-and-object-code -fprefer-byte-code - - This makes sure that the Template Haskell runs in the bytecode - interpreter with optimized bytecode, allowing us to test the - sized unboxed literals. - - Running the test in GHCi directly would disable optimization. - - -} - -main :: IO () -main = do - print $(pure $ ListE [ ie (fibw8 5) - , ie (fibw16 5) - , ie (fibw32 5) - , ie (fibw64 5) - ]) - - print $(pure $ ListE [ ie (fibi8 5) - , ie (fibi16 5) - , ie (fibi32 5) - , ie (fibi64 5) - ]) - - print $(pure $ ListE [ ie (branchi8 0) - , ie (branchi8 1) - , ie (branchi8 (-1)) - , ie (branchi8 126) - , ie (branchi8 127) - , ie (branchi8 (-127)) - , ie (branchi8 (-128)) - , ie (branchi8 2) - ]) - - print $(pure $ ListE [ ie (branchi16 0) - , ie (branchi16 1) - , ie (branchi16 (-1)) - , ie (branchi16 32767) - , ie (branchi16 32766) - , ie (branchi16 (-32768)) - , ie (branchi16 (-32767)) - , ie (branchi16 2) - ]) - - print $(pure $ ListE [ ie (branchi32 0) - , ie (branchi32 1) - , ie (branchi32 (-1)) - , ie (branchi32 2147483646) - , ie (branchi32 2147483647) - , ie (branchi32 (-2147483648)) - , ie (branchi32 (-2147483647)) - , ie (branchi32 2) - ]) - - print $(pure $ ListE [ ie (branchi64 0) - , ie (branchi64 1) - , ie (branchi64 (-1)) - , ie (branchi64 2147483647) - , ie (branchi64 2147483648) - , ie (branchi64 4294967297) - , ie (branchi64 (-2147483648)) - , ie (branchi64 (-2147483649)) - , ie (branchi64 (-4294967295)) - , ie (branchi64 9223372036854775807) - , ie (branchi64 9223372036854775806) - , ie (branchi64 (-9223372036854775808)) - , ie (branchi64 (-9223372036854775807)) - , ie (branchi64 2) - ]) - - print $(pure $ ListE [ ie (branchw8 0) - , ie (branchw8 1) - , ie (branchw8 254) - , ie (branchw8 255) - , ie (branchw8 2) - ]) - - print $(pure $ ListE [ ie (branchw16 0) - , ie (branchw16 1) - , ie (branchw16 255) - , ie (branchw16 256) - , ie (branchw16 65534) - , ie (branchw16 65535) - , ie (branchw16 2) - ]) - - print $(pure $ ListE [ ie (branchw32 0) - , ie (branchw32 1) - , ie (branchw32 65534) - , ie (branchw32 65535) - , ie (branchw32 65536) - , ie (branchw32 4294967295) - , ie (branchw32 4294967294) - , ie (branchw32 4294967293) - , ie (branchw32 2) - ]) - - print $(pure $ ListE [ ie (branchw64 0) - , ie (branchw64 1) - , ie (branchw64 65536) - , ie (branchw64 4294967295) - , ie (branchw64 4294967296) - , ie (branchw64 4294967297) - , ie (branchw64 18446744073709551615) - , ie (branchw64 18446744073709551614) - , ie (branchw64 18446744073709551613) - , ie (branchw64 2) - ]) \ No newline at end of file ===================================== testsuite/tests/ghci/should_run/SizedLiteralsA.hs deleted ===================================== @@ -1,139 +0,0 @@ -module SizedLiteralsA where - -import GHC.Word -import GHC.Int -import Language.Haskell.TH.Syntax - -fibw8 :: Word8 -> Word8 -fibw8 0 = 0 -fibw8 1 = 1 -fibw8 n = fibw8 (n-1) + fibw8 (n-2) - -fibw16 :: Word16 -> Word16 -fibw16 0 = 0 -fibw16 1 = 1 -fibw16 n = fibw16 (n-1) + fibw16 (n-2) - -fibw32 :: Word32 -> Word32 -fibw32 0 = 0 -fibw32 1 = 1 -fibw32 n = fibw32 (n-1) + fibw32 (n-2) - -fibw64 :: Word64 -> Word64 -fibw64 0 = 0 -fibw64 1 = 1 -fibw64 n = fibw64 (n-1) + fibw64 (n-2) - --- - -fibi8 :: Int8 -> Int8 -fibi8 0 = 0 -fibi8 1 = 1 -fibi8 n = fibi8 (n-1) + fibi8 (n-2) - -fibi16 :: Int16 -> Int16 -fibi16 0 = 0 -fibi16 1 = 1 -fibi16 n = fibi16 (n-1) + fibi16 (n-2) - -fibi32 :: Int32 -> Int32 -fibi32 0 = 0 -fibi32 1 = 1 -fibi32 n = fibi32 (n-1) + fibi32 (n-2) - -fibi64 :: Int64 -> Int64 -fibi64 0 = 0 -fibi64 1 = 1 -fibi64 n = fibi64 (n-1) + fibi64 (n-2) - --- - -branchi8 :: Int8 -> Word8 -branchi8 0 = 1 -branchi8 1 = 2 -branchi8 (-1) = 3 -branchi8 126 = 4 -branchi8 127 = 5 -branchi8 (-127) = 6 -branchi8 (-128) = 7 -branchi8 _ = 0 - -branchi16 :: Int16 -> Word16 -branchi16 0 = 1 -branchi16 1 = 2 -branchi16 (-1) = 3 -branchi16 32767 = 255 -branchi16 32766 = 256 -branchi16 (-32768) = 65534 -branchi16 (-32767) = 65535 -branchi16 _ = 0 - -branchi32 :: Int32 -> Word32 -branchi32 0 = 1 -branchi32 1 = 2 -branchi32 (-1) = 3 -branchi32 2147483646 = 65535 -branchi32 2147483647 = 65536 -branchi32 (-2147483648) = 4294967294 -branchi32 (-2147483647) = 4294967295 -branchi32 _ = 0 - -branchi64 :: Int64 -> Word64 -branchi64 0 = 18446744073709551615 -branchi64 1 = 2147483648 -branchi64 (-1) = 4294967296 -branchi64 2147483647 = 4294967297 -branchi64 2147483648 = 9 -branchi64 4294967297 = 1 -branchi64 (-2147483648) = 18446744073709551614 -branchi64 (-2147483649) = 3 -branchi64 (-4294967295) = 4 -branchi64 9223372036854775807 = 5 -branchi64 9223372036854775806 = 6 -branchi64 (-9223372036854775808) = 7 -branchi64 (-9223372036854775807) = 8 -branchi64 _ = 0 - -branchw8 :: Word8 -> Int8 -branchw8 0 = 1 -branchw8 1 = (-1) -branchw8 254 = 2 -branchw8 255 = (-2) -branchw8 _ = 0 - -branchw16 :: Word16 -> Int16 -branchw16 0 = 256 -branchw16 1 = (-256) -branchw16 255 = 32767 -branchw16 256 = (-32768) -branchw16 65534 = (-1) -branchw16 65535 = 1 -branchw16 _ = 0 - -branchw32 :: Word32 -> Int32 -branchw32 0 = 2147483647 -branchw32 1 = (-2147483648) -branchw32 65534 = 65535 -branchw32 65535 = 65536 -branchw32 65536 = (-1) -branchw32 4294967295 = (-65536) -branchw32 4294967294 = (-65537) -branchw32 4294967293 = 1 -branchw32 _ = 0 - -branchw64 :: Word64 -> Int64 -branchw64 0 = 9223372036854775807 -branchw64 1 = 2147483648 -branchw64 65536 = 4294967296 -branchw64 4294967295 = 4294967297 -branchw64 4294967296 = (-1) -branchw64 4294967297 = 9223372036854775806 -branchw64 18446744073709551615 = (-9223372036854775808) -branchw64 18446744073709551614 = (-9223372036854775807) -branchw64 18446744073709551613 = 1 -branchw64 _ = 0 - --- - -ie :: Integral a => a -> Exp -ie x = LitE (IntegerL (toInteger x)) ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -85,7 +85,6 @@ test('T19628', [extra_files(['T19628a.hs']), only_ways(['ghci']) ], compile_and_ test('T21052', just_ghci, ghci_script, ['T21052.script']) test('T21300', just_ghci, ghci_script, ['T21300.script']) test('UnliftedDataType2', just_ghci, compile_and_run, ['']) -test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) ===================================== testsuite/tests/printer/Ppr038.hs ===================================== @@ -21,6 +21,14 @@ blah = x wordH = 005## floatH = 3.20# doubleH = 04.16## - -- int64H = 00456L# - -- word64H = 00456L## + intNH = 1000#Int + int8H = 1008#Int8 + int16H = 1016#Int8 + int32H = 1032#Int32 + int64H = 1064#Int64 + wordNH = 2000#Word + word8H = 2008#Word8 + word16H = 2016#Word16 + word32H = 2032#Word32 + word64H = 2064#Word64 x = 1 ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4706,7 +4706,13 @@ hsLit2String lit = HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v "" HsIntPrim src v -> toSourceTextWithSuffix src v "" HsWordPrim src v -> toSourceTextWithSuffix src v "" + HsInt8Prim src v -> toSourceTextWithSuffix src v "" + HsInt16Prim src v -> toSourceTextWithSuffix src v "" + HsInt32Prim src v -> toSourceTextWithSuffix src v "" HsInt64Prim src v -> toSourceTextWithSuffix src v "" + HsWord8Prim src v -> toSourceTextWithSuffix src v "" + HsWord16Prim src v -> toSourceTextWithSuffix src v "" + HsWord32Prim src v -> toSourceTextWithSuffix src v "" HsWord64Prim src v -> toSourceTextWithSuffix src v "" HsInteger src v _ -> toSourceTextWithSuffix src v "" HsRat _ fl@(FL{fl_text = src }) _ -> toSourceTextWithSuffix src fl "" ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 03ba53ca764f56a13d12607c110f923f129e809a +Subproject commit e16e20d592a6f5d9ed1af17b77fafd6495242345 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/886763022424589e7a389f52ad847d7d3d0acf0d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/886763022424589e7a389f52ad847d7d3d0acf0d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 07:53:25 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 03:53:25 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <644240f5d2eb4_178e745bc1c6bc817634@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: e43ca96f by Josh Meredith at 2023-04-21T07:52:55+00:00 Use unboxed codebuffers in base - - - - - 7 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let (# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let (# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let (# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let (# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let (# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e43ca96f7e87e5c3d1629d9fa33cc990e74a52d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e43ca96f7e87e5c3d1629d9fa33cc990e74a52d3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 08:26:04 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 04:26:04 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] Apply 1 suggestion(s) to 1 file(s) Message-ID: <6442489c64fda_178e745c6d0bf8829879@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 4a72ddfa by Sylvain Henry at 2023-04-21T08:26:02+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - libraries/base/tests/IO/all.T Changes: ===================================== libraries/base/tests/IO/all.T ===================================== @@ -153,4 +153,4 @@ test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) -test('mkdirExists', exit_code(1), compile_and_run, ['']) +test('mkdirExists', [exit_code(1),grep_errmsg(r'already exists')], compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4a72ddfa3250702945ada0007b43b63920143625 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4a72ddfa3250702945ada0007b43b63920143625 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 08:28:11 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 04:28:11 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] JS/base: provide implementation for mkdir (issue 22374) Message-ID: <6442491b7815b_178e745c6d0b44830294@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: f7d110ec by Josh Meredith at 2023-04-21T08:27:59+00:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 5 changed files: - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - + libraries/base/tests/IO/mkdirExists.stderr - testsuite/tests/ghc-api/target-contents/all.T Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -889,3 +889,21 @@ function h$__hscore_free_dirent(a,o) { function h$__hscore_d_name(a,o) { RETURN_UBX_TUP2(h$encodeModifiedUtf8(a.name),0); } + +function h$mkdir(path, path_offset, mode) { + if (!h$isNode()) { + throw "h$mkdir unsupported"; + } + const d = h$decodeUtf8z(path, path_offset); + try { + h$fs.mkdirSync(d, {mode: mode}); + } catch(e) { + // we can't directly set errno code, because numbers may not match + // e.g. e.errno is -17 for EEXIST while we would expect -20 + // this is probably an inconsistency between nodejs using the native + // environment and everything else using Emscripten-provided headers. + h$setErrno(e); + return -1; + } + return 0; +} ===================================== libraries/base/tests/IO/all.T ===================================== @@ -64,7 +64,7 @@ test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run, test('openFile001', normal, compile_and_run, ['']) test('openFile002', [exit_code(1), normalise_win32_io_errors], compile_and_run, ['']) -test('openFile003', [normalise_win32_io_errors, js_broken(22374)], compile_and_run, ['']) +test('openFile003', [normalise_win32_io_errors, js_broken(22362)], compile_and_run, ['']) test('openFile004', [], compile_and_run, ['']) test('openFile005', js_broken(22261), compile_and_run, ['']) test('openFile006', [], compile_and_run, ['']) @@ -152,3 +152,5 @@ test('T17510', expect_broken(17510), compile_and_run, ['']) test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) + +test('mkdirExists', [exit_code(1),grep_errmsg(r'already exists')], compile_and_run, ['']) ===================================== libraries/base/tests/IO/mkdirExists.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import System.Directory + +main :: IO () +main = do + createDirectory "foo" + createDirectory "foo" ===================================== libraries/base/tests/IO/mkdirExists.stderr ===================================== @@ -0,0 +1 @@ +mkdirExists: foo: createDirectory: already exists (File exists) ===================================== testsuite/tests/ghc-api/target-contents/all.T ===================================== @@ -1,6 +1,6 @@ test('TargetContents', [ extra_run_opts('"' + config.libdir + '"') - , js_broken(22374) + , js_broken(22362) ] , compile_and_run, ['-package ghc -package exceptions']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d110ecbae1b1673b0a844102208f41cc7e3d8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7d110ecbae1b1673b0a844102208f41cc7e3d8f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 09:12:55 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 05:12:55 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <6442539764ff7_178e745d66b06883657b@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 0df25f71 by Josh Meredith at 2023-04-21T09:12:26+00:00 Use unboxed codebuffers in base - - - - - 7 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let (# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let (# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let (# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let (# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0df25f713a1c9bc713da5747a888f13f9d9df133 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0df25f713a1c9bc713da5747a888f13f9d9df133 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 10:08:06 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 21 Apr 2023 06:08:06 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64426086ea5ae_178e745e55379c839054@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 41842ffb by Rodrigo Mesquita at 2023-04-21T11:07:53+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 15 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -586,12 +586,22 @@ Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~ -dcSourceArity does not take constraints into account, -but dcRepArity does. For example: +A `DataCon`'s source arity and core representation arity may differ: +`dcSourceArity` does not take constraints into account, but `dcRepArity` does. + +The additional arguments taken into account by `dcRepArity` include quantified +dictionaries and coercion arguments, lifted and unlifted (despite the unlifted +coercion arguments having a zero-width runtime representation). +For example: MkT :: Ord a => a -> T a dcSourceArity = 1 dcRepArity = 2 + MkU :: (b ~ '[]) => U b + dcSourceArity = 0 + dcRepArity = 1 + + Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A DataCon has two different sets of type variables: @@ -981,7 +991,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1405,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of value arguments (including zero-width coercions) +-- stored by the given `DataCon`'s worker in its Core representation. This may +-- differ from the number of arguments that appear in the source code; see also +-- Note [DataCon arities] dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1417,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether this `DataCon`'s worker, in its Core representation, takes +-- any arguments. +-- +-- In particular, remember that we include coercion arguments in the arity of +-- the Core representation of the `DataCon` -- both lifted and unlifted +-- coercions, despite the latter having zero-width runtime representation. +-- +-- See also Note [DataCon arities]. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,99 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +However, when an interface doesn't have a LambdaFormInfo for some Id, we +conservatively create one (in `mkLFImported`). + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, its crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146) + +In general, + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> T a` is given `LFReEntrant` + and `Nil :: (a ~# '[]) -> T a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -113,6 +113,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +163,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,8 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | This function counts all arguments post-unarisation, which includes +-- arguments with no runtime representation -- see Note [Unarisation and arity] idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -439,7 +439,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/41842ffb80d8313d043199a7ba3c94129b8fe558 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/41842ffb80d8313d043199a7ba3c94129b8fe558 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 10:33:34 2023 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 21 Apr 2023 06:33:34 -0400 Subject: [Git][ghc/ghc][wip/ghcup-metadata-nightly] testing Message-ID: <6442667ecce3c_178e745ebab464847610@gitlab.mail> Matthew Pickering pushed to branch wip/ghcup-metadata-nightly at Glasgow Haskell Compiler / GHC Commits: 6ab3d25c by GHC GitLab CI at 2023-04-21T11:33:26+01:00 testing - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -1063,11 +1063,11 @@ ghcup-metadata-nightly-push: - job: ghcup-metadata-nightly artifacts: true script: - - git config user.email "ghc-ci at gitlab-haskell.org" - - git config user.name "GHC GitLab CI" - git clone https://gitlab.haskell.org/ghc/ghcup-metadata.git - cp metadata_test.yaml ghcup-metadata/ghcup-0.0.7.yaml - cd ghcup-metadata + - git config user.email "ghc-ci at gitlab-haskell.org" + - git config user.name "GHC GitLab CI" - echo "" >> ghcup-0.0.7.yaml - git remote add gitlab_origin https://oauth2:$PROJECT_PUSH_TOKEN at gitlab.haskell.org/ghc/ghcup-metadata.git - git add . View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ab3d25c373f55e71eaa9b3c288050e5902adc8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6ab3d25c373f55e71eaa9b3c288050e5902adc8c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 11:09:04 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 07:09:04 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] JS/base: provide implementation for mkdir (issue 22374) Message-ID: <64426ed0c647_178e745f6eca4484993b@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 6591f4f1 by Josh Meredith at 2023-04-21T11:08:51+00:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 4 changed files: - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - testsuite/tests/ghc-api/target-contents/all.T Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -889,3 +889,21 @@ function h$__hscore_free_dirent(a,o) { function h$__hscore_d_name(a,o) { RETURN_UBX_TUP2(h$encodeModifiedUtf8(a.name),0); } + +function h$mkdir(path, path_offset, mode) { + if (!h$isNode()) { + throw "h$mkdir unsupported"; + } + const d = h$decodeUtf8z(path, path_offset); + try { + h$fs.mkdirSync(d, {mode: mode}); + } catch(e) { + // we can't directly set errno code, because numbers may not match + // e.g. e.errno is -17 for EEXIST while we would expect -20 + // this is probably an inconsistency between nodejs using the native + // environment and everything else using Emscripten-provided headers. + h$setErrno(e); + return -1; + } + return 0; +} ===================================== libraries/base/tests/IO/all.T ===================================== @@ -64,7 +64,7 @@ test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run, test('openFile001', normal, compile_and_run, ['']) test('openFile002', [exit_code(1), normalise_win32_io_errors], compile_and_run, ['']) -test('openFile003', [normalise_win32_io_errors, js_broken(22374)], compile_and_run, ['']) +test('openFile003', [normalise_win32_io_errors, js_broken(22362)], compile_and_run, ['']) test('openFile004', [], compile_and_run, ['']) test('openFile005', js_broken(22261), compile_and_run, ['']) test('openFile006', [], compile_and_run, ['']) @@ -152,3 +152,5 @@ test('T17510', expect_broken(17510), compile_and_run, ['']) test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) + +test('mkdirExists', [exit_code(1),grep_errmsg(r'already exists')], compile_and_run, ['']) ===================================== libraries/base/tests/IO/mkdirExists.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import System.Directory + +main :: IO () +main = do + createDirectory "foo" + createDirectory "foo" ===================================== testsuite/tests/ghc-api/target-contents/all.T ===================================== @@ -1,6 +1,6 @@ test('TargetContents', [ extra_run_opts('"' + config.libdir + '"') - , js_broken(22374) + , js_broken(22362) ] , compile_and_run, ['-package ghc -package exceptions']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6591f4f1119be2d4569c314ad460351fa6af8ab5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6591f4f1119be2d4569c314ad460351fa6af8ab5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 11:36:58 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 07:36:58 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <6442755a9c843_178e745fe5f2a4858712@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 2562ab86 by Josh Meredith at 2023-04-21T11:36:26+00:00 Use unboxed codebuffers in base - - - - - 7 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let !(# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2562ab86a22d1154da59cdfc1967d138785d5b7a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2562ab86a22d1154da59cdfc1967d138785d5b7a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 12:37:07 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 08:37:07 -0400 Subject: [Git][ghc/ghc][wip/js-base_access] JS: Fix h$base_access implementation (issue 22576) Message-ID: <64428373ebd8c_178e7460d76580873439@gitlab.mail> Josh Meredith pushed to branch wip/js-base_access at Glasgow Haskell Compiler / GHC Commits: 77794fac by Josh Meredith at 2023-04-21T12:36:44+00:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 5 changed files: - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/jsbits/base.js - testsuite/tests/ado/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -105,7 +105,11 @@ inTreeCompilerArgs stg = do tables_next_to_code <- flag TablesNextToCode targetWithSMP <- targetSupportsSMP - let ghcStage = succStage stg + cross <- flag CrossCompiling + + let ghcStage + | cross, Stage1 <- stg = Stage1 + | otherwise = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage ===================================== libraries/base/jsbits/base.js ===================================== @@ -14,11 +14,11 @@ function h$base_access(file, file_off, mode, c) { TRACE_IO("base_access") #ifndef GHCJS_BROWSER if(h$isNode()) { - h$fs.stat(fd, function(err, fs) { - if(err) { + h$fs.access(h$decodeUtf8z(file, file_off), mode, function(err) { + if (err) { h$handleErrnoC(err, -1, 0, c); } else { - c(mode & fs.mode); // fixme is this ok? + c(0); } }); } else ===================================== testsuite/tests/ado/all.T ===================================== @@ -20,5 +20,5 @@ test('T15344', normal, compile_and_run, ['']) test('T16628', normal, compile_fail, ['']) test('T17835', normal, compile, ['']) test('T20540', normal, compile, ['']) -test('T16135', [when(compiler_debugged(),expect_broken(16135)), js_broken(22576)], compile_fail, ['']) +test('T16135', [when(compiler_debugged(),expect_broken(16135))], compile_fail, ['']) test('T22483', normal, compile, ['-Wall']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', js_broken(22576), compile, ['']) +test('RepPolyWrappedVar2', js_broken(23280), compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -328,7 +328,7 @@ test('T8262', normal, compile_fail, ['']) # TcCoercibleFail times out with the compiler is compiled with -DDEBUG. # This is expected (see comment in source file). -test('TcCoercibleFail', [when(compiler_debugged(), skip), js_broken(22576)], compile_fail, ['']) +test('TcCoercibleFail', [when(compiler_debugged(), skip)], compile_fail, ['']) test('TcCoercibleFail2', [], compile_fail, ['']) test('TcCoercibleFail3', [], compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77794face29c1109a859bfadbba2e96a35320e29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77794face29c1109a859bfadbba2e96a35320e29 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 12:41:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 08:41:25 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Implement -jsem: parallelism controlled by semaphores Message-ID: <64428475d805e_178e74610f2524874024@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - 742b7bc7 by tocic at 2023-04-21T08:40:58-04:00 Fix doc typos in libraries/base/GHC - - - - - 5afb844f by Sylvain Henry at 2023-04-21T08:41:10-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 28 changed files: - .gitmodules - cabal.project-reinstall - compiler/GHC/Driver/Make.hs - + compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Session.hs - compiler/ghc.cabal.in - docs/users_guide/9.8.1-notes.rst - docs/users_guide/using.rst - hadrian/src/Packages.hs - hadrian/src/Rules/ToolArgs.hs - hadrian/src/Settings/Default.hs - libraries/base/GHC/IO/Device.hs - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Handle.hs - libraries/base/GHC/IO/SubSystem.hs - libraries/base/GHC/List.hs - libraries/base/GHC/TypeNats.hs - + libraries/semaphore-compat - packages - rts/Threads.c - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/ffi/should_run/all.T - + testsuite/tests/primops/should_run/T23071.hs - testsuite/tests/primops/should_run/all.T - testsuite/tests/rts/T15894/all.T - testsuite/tests/rts/all.T - testsuite/tests/rts/linker/all.T Changes: ===================================== .gitmodules ===================================== @@ -83,6 +83,10 @@ url = https://gitlab.haskell.org/ghc/packages/unix.git ignore = untracked branch = 2.7 +[submodule "libraries/semaphore-compat"] + path = libraries/semaphore-compat + url = https://gitlab.haskell.org/ghc/semaphore-compat.git + ignore = untracked [submodule "libraries/stm"] path = libraries/stm url = https://gitlab.haskell.org/ghc/packages/stm.git ===================================== cabal.project-reinstall ===================================== @@ -28,6 +28,7 @@ packages: ./compiler ./libraries/parsec/ -- ./libraries/pretty/ ./libraries/process/ + ./libraries/semaphore-compat ./libraries/stm -- ./libraries/template-haskell/ ./libraries/terminfo/ ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -75,6 +75,7 @@ import GHC.Driver.Env import GHC.Driver.Errors import GHC.Driver.Errors.Types import GHC.Driver.Main +import GHC.Driver.MakeSem import GHC.Parser.Header @@ -151,10 +152,10 @@ import GHC.Runtime.Loader import GHC.Rename.Names import GHC.Utils.Constants import GHC.Types.Unique.DFM (udfmRestrictKeysSet) -import qualified Data.IntSet as I import GHC.Types.Unique import GHC.Iface.Errors.Types +import qualified Data.IntSet as I -- ----------------------------------------------------------------------------- -- Loading the program @@ -664,6 +665,30 @@ createBuildPlan mod_graph maybe_top_mod = (vcat [text "Build plan missing nodes:", (text "PLAN:" <+> ppr (sum (map countMods build_plan))), (text "GRAPH:" <+> ppr (length (mgModSummaries' mod_graph )))]) build_plan +mkWorkerLimit :: DynFlags -> IO WorkerLimit +mkWorkerLimit dflags = + case parMakeCount dflags of + Nothing -> pure $ num_procs 1 + Just (ParMakeSemaphore h) -> pure (JSemLimit (SemaphoreName h)) + Just ParMakeNumProcessors -> num_procs <$> getNumProcessors + Just (ParMakeThisMany n) -> pure $ num_procs n + where + num_procs x = NumProcessorsLimit (max 1 x) + +isWorkerLimitSequential :: WorkerLimit -> Bool +isWorkerLimitSequential (NumProcessorsLimit x) = x <= 1 +isWorkerLimitSequential (JSemLimit {}) = False + +-- | This describes what we use to limit the number of jobs, either we limit it +-- ourselves to a specific number or we have an external parallelism semaphore +-- limit it for us. +data WorkerLimit + = NumProcessorsLimit Int + | JSemLimit + SemaphoreName + -- ^ Semaphore name to use + deriving Eq + -- | Generalized version of 'load' which also supports a custom -- 'Messager' (for reporting progress) and 'ModuleGraph' (generally -- produced by calling 'depanal'. @@ -744,14 +769,12 @@ load' mhmi_cache how_much mHscMessage mod_graph = do liftIO $ debugTraceMsg logger 2 (hang (text "Ready for upsweep") 2 (ppr build_plan)) - n_jobs <- case parMakeCount (hsc_dflags hsc_env) of - Nothing -> liftIO getNumProcessors - Just n -> return n + worker_limit <- liftIO $ mkWorkerLimit dflags setSession $ hscUpdateHUG (unitEnv_map pruneHomeUnitEnv) hsc_env (upsweep_ok, hsc_env1) <- withDeferredDiagnostics $ do hsc_env <- getSession - liftIO $ upsweep n_jobs hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan + liftIO $ upsweep worker_limit hsc_env mhmi_cache mHscMessage (toCache pruned_cache) build_plan setSession hsc_env1 case upsweep_ok of Failed -> loadFinish upsweep_ok @@ -1036,13 +1059,7 @@ getDependencies direct_deps build_map = type BuildM a = StateT BuildLoopState IO a --- | Abstraction over the operations of a semaphore which allows usage with the --- -j1 case -data AbstractSem = AbstractSem { acquireSem :: IO () - , releaseSem :: IO () } -withAbstractSem :: AbstractSem -> IO b -> IO b -withAbstractSem sem = MC.bracket_ (acquireSem sem) (releaseSem sem) -- | Environment used when compiling a module data MakeEnv = MakeEnv { hsc_env :: !HscEnv -- The basic HscEnv which will be augmented for each module @@ -1227,7 +1244,7 @@ withCurrentUnit uid = do local (\env -> env { hsc_env = hscSetActiveUnitId uid (hsc_env env)}) upsweep - :: Int -- ^ The number of workers we wish to run in parallel + :: WorkerLimit -- ^ The number of workers we wish to run in parallel -> HscEnv -- ^ The base HscEnv, which is augmented for each module -> Maybe ModIfaceCache -- ^ A cache to incrementally write final interface files to -> Maybe Messager @@ -2832,7 +2849,7 @@ label_self thread_name = do CC.labelThread self_tid thread_name -runPipelines :: Int -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () +runPipelines :: WorkerLimit -> HscEnv -> Maybe Messager -> [MakeAction] -> IO () -- Don't even initialise plugins if there are no pipelines runPipelines _ _ _ [] = return () runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do @@ -2840,7 +2857,7 @@ runPipelines n_job orig_hsc_env mHscMessager all_pipelines = do plugins_hsc_env <- initializePlugins orig_hsc_env case n_job of - 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines + NumProcessorsLimit n | n <= 1 -> runSeqPipelines plugins_hsc_env mHscMessager all_pipelines _n -> runParPipelines n_job plugins_hsc_env mHscMessager all_pipelines runSeqPipelines :: HscEnv -> Maybe Messager -> [MakeAction] -> IO () @@ -2850,16 +2867,38 @@ runSeqPipelines plugin_hsc_env mHscMessager all_pipelines = , compile_sem = AbstractSem (return ()) (return ()) , env_messager = mHscMessager } - in runAllPipelines 1 env all_pipelines + in runAllPipelines (NumProcessorsLimit 1) env all_pipelines +runNjobsAbstractSem :: Int -> (AbstractSem -> IO a) -> IO a +runNjobsAbstractSem n_jobs action = do + compile_sem <- newQSem n_jobs + n_capabilities <- getNumCapabilities + n_cpus <- getNumProcessors + let + asem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + set_num_caps n = unless (n_capabilities /= 1) $ setNumCapabilities n + updNumCapabilities = do + -- Setting number of capabilities more than + -- CPU count usually leads to high userspace + -- lock contention. #9221 + set_num_caps $ min n_jobs n_cpus + resetNumCapabilities = set_num_caps n_capabilities + MC.bracket_ updNumCapabilities resetNumCapabilities $ action asem + +runWorkerLimit :: WorkerLimit -> (AbstractSem -> IO a) -> IO a +runWorkerLimit worker_limit action = case worker_limit of + NumProcessorsLimit n_jobs -> + runNjobsAbstractSem n_jobs action + JSemLimit sem -> + runJSemAbstractSem sem action -- | Build and run a pipeline -runParPipelines :: Int -- ^ How many capabilities to use - -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module +runParPipelines :: WorkerLimit -- ^ How to limit work parallelism + -> HscEnv -- ^ The basic HscEnv which is augmented with specific info for each module -> Maybe Messager -- ^ Optional custom messager to use to report progress -> [MakeAction] -- ^ The build plan for all the module nodes -> IO () -runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do +runParPipelines worker_limit plugin_hsc_env mHscMessager all_pipelines = do -- A variable which we write to when an error has happened and we have to tell the @@ -2869,39 +2908,23 @@ runParPipelines n_jobs plugin_hsc_env mHscMessager all_pipelines = do -- will add it's LogQueue into this queue. log_queue_queue_var <- newTVarIO newLogQueueQueue -- Thread which coordinates the printing of logs - wait_log_thread <- logThread n_jobs (length all_pipelines) (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var + wait_log_thread <- logThread (hsc_logger plugin_hsc_env) stopped_var log_queue_queue_var -- Make the logger thread-safe, in case there is some output which isn't sent via the LogQueue. thread_safe_logger <- liftIO $ makeThreadSafe (hsc_logger plugin_hsc_env) let thread_safe_hsc_env = plugin_hsc_env { hsc_logger = thread_safe_logger } - let updNumCapabilities = liftIO $ do - n_capabilities <- getNumCapabilities - n_cpus <- getNumProcessors - -- Setting number of capabilities more than - -- CPU count usually leads to high userspace - -- lock contention. #9221 - let n_caps = min n_jobs n_cpus - unless (n_capabilities /= 1) $ setNumCapabilities n_caps - return n_capabilities - - let resetNumCapabilities orig_n = do - liftIO $ setNumCapabilities orig_n - atomically $ writeTVar stopped_var True - wait_log_thread - - compile_sem <- newQSem n_jobs - let abstract_sem = AbstractSem (waitQSem compile_sem) (signalQSem compile_sem) + runWorkerLimit worker_limit $ \abstract_sem -> do + let env = MakeEnv { hsc_env = thread_safe_hsc_env + , withLogger = withParLog log_queue_queue_var + , compile_sem = abstract_sem + , env_messager = mHscMessager + } -- Reset the number of capabilities once the upsweep ends. - let env = MakeEnv { hsc_env = thread_safe_hsc_env - , withLogger = withParLog log_queue_queue_var - , compile_sem = abstract_sem - , env_messager = mHscMessager - } - - MC.bracket updNumCapabilities resetNumCapabilities $ \_ -> - runAllPipelines n_jobs env all_pipelines + runAllPipelines worker_limit env all_pipelines + atomically $ writeTVar stopped_var True + wait_log_thread withLocalTmpFS :: RunMakeM a -> RunMakeM a withLocalTmpFS act = do @@ -2918,10 +2941,11 @@ withLocalTmpFS act = do MC.bracket initialiser finaliser $ \lcl_hsc_env -> local (\env -> env { hsc_env = lcl_hsc_env}) act -- | Run the given actions and then wait for them all to finish. -runAllPipelines :: Int -> MakeEnv -> [MakeAction] -> IO () -runAllPipelines n_jobs env acts = do - let spawn_actions :: IO [ThreadId] - spawn_actions = if n_jobs == 1 +runAllPipelines :: WorkerLimit -> MakeEnv -> [MakeAction] -> IO () +runAllPipelines worker_limit env acts = do + let single_worker = isWorkerLimitSequential worker_limit + spawn_actions :: IO [ThreadId] + spawn_actions = if single_worker then (:[]) <$> (forkIOWithUnmask $ \unmask -> void $ runLoop (\io -> io unmask) env acts) else runLoop forkIOWithUnmask env acts ===================================== compiler/GHC/Driver/MakeSem.hs ===================================== @@ -0,0 +1,545 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} +{-# LANGUAGE NumericUnderscores #-} + +-- | Implementation of a jobserver using system semaphores. +-- +-- +module GHC.Driver.MakeSem + ( -- * JSem: parallelism semaphore backed + -- by a system semaphore (Posix/Windows) + runJSemAbstractSem + + -- * System semaphores + , Semaphore, SemaphoreName(..) + + -- * Abstract semaphores + , AbstractSem(..) + , withAbstractSem + ) + where + +import GHC.Prelude +import GHC.Conc +import GHC.Data.OrdList +import GHC.IO.Exception +import GHC.Utils.Outputable +import GHC.Utils.Panic +import GHC.Utils.Json + +import System.Semaphore + +import Control.Monad +import qualified Control.Monad.Catch as MC +import Control.Concurrent.MVar +import Control.Concurrent.STM +import Data.Foldable +import Data.Functor +import GHC.Stack +import Debug.Trace + +--------------------------------------- +-- Semaphore jobserver + +-- | A jobserver based off a system 'Semaphore'. +-- +-- Keeps track of the pending jobs and resources +-- available from the semaphore. +data Jobserver + = Jobserver + { jSemaphore :: !Semaphore + -- ^ The semaphore which controls available resources + , jobs :: !(TVar JobResources) + -- ^ The currently pending jobs, and the resources + -- obtained from the semaphore + } + +data JobserverOptions + = JobserverOptions + { releaseDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between acquiring a token + -- and releasing a token. + , setNumCapsDebounce :: !Int + -- ^ Minimum delay, in milliseconds, between two consecutive + -- calls of 'setNumCapabilities'. + } + +defaultJobserverOptions :: JobserverOptions +defaultJobserverOptions = + JobserverOptions + { releaseDebounce = 1000 -- 1 second + , setNumCapsDebounce = 1000 -- 1 second + } + +-- | Resources available for running jobs, i.e. +-- tokens obtained from the parallelism semaphore. +data JobResources + = Jobs + { tokensOwned :: !Int + -- ^ How many tokens have been claimed from the semaphore + , tokensFree :: !Int + -- ^ How many tokens are not currently being used + , jobsWaiting :: !(OrdList (TMVar ())) + -- ^ Pending jobs waiting on a token, the job will be blocked on the TMVar so putting into + -- the TMVar will allow the job to continue. + } + +instance Outputable JobResources where + ppr Jobs{..} + = text "JobResources" <+> + ( braces $ hsep + [ text "owned=" <> ppr tokensOwned + , text "free=" <> ppr tokensFree + , text "num_waiting=" <> ppr (length jobsWaiting) + ] ) + +-- | Add one new token. +addToken :: JobResources -> JobResources +addToken jobs@( Jobs { tokensOwned = owned, tokensFree = free }) + = jobs { tokensOwned = owned + 1, tokensFree = free + 1 } + +-- | Free one token. +addFreeToken :: JobResources -> JobResources +addFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (tokensOwned jobs > free) + (text "addFreeToken:" <+> ppr (tokensOwned jobs) <+> ppr free) + $ jobs { tokensFree = free + 1 } + +-- | Use up one token. +removeFreeToken :: JobResources -> JobResources +removeFreeToken jobs@( Jobs { tokensFree = free }) + = assertPpr (free > 0) + (text "removeFreeToken:" <+> ppr free) + $ jobs { tokensFree = free - 1 } + +-- | Return one owned token. +removeOwnedToken :: JobResources -> JobResources +removeOwnedToken jobs@( Jobs { tokensOwned = owned }) + = assertPpr (owned > 1) + (text "removeOwnedToken:" <+> ppr owned) + $ jobs { tokensOwned = owned - 1 } + +-- | Add one new job to the end of the list of pending jobs. +addJob :: TMVar () -> JobResources -> JobResources +addJob job jobs@( Jobs { jobsWaiting = wait }) + = jobs { jobsWaiting = wait `SnocOL` job } + +-- | The state of the semaphore job server. +data JobserverState + = JobserverState + { jobserverAction :: !JobserverAction + -- ^ The current action being performed by the + -- job server. + , canChangeNumCaps :: !(TVar Bool) + -- ^ A TVar that signals whether it has been long + -- enough since we last changed 'numCapabilities'. + , canReleaseToken :: !(TVar Bool) + -- ^ A TVar that signals whether we last acquired + -- a token long enough ago that we can now release + -- a token. + } +data JobserverAction + -- | The jobserver is idle: no thread is currently + -- interacting with the semaphore. + = Idle + -- | A thread is waiting for a token on the semaphore. + | Acquiring + { activeWaitId :: WaitId + , threadFinished :: TMVar (Maybe MC.SomeException) } + +-- | Retrieve the 'TMVar' that signals if the current thread has finished, +-- if any thread is currently active in the jobserver. +activeThread_maybe :: JobserverAction -> Maybe (TMVar (Maybe MC.SomeException)) +activeThread_maybe Idle = Nothing +activeThread_maybe (Acquiring { threadFinished = tmvar }) = Just tmvar + +-- | Whether we should try to acquire a new token from the semaphore: +-- there is a pending job and no free tokens. +guardAcquire :: JobResources -> Bool +guardAcquire ( Jobs { tokensFree, jobsWaiting } ) + = tokensFree == 0 && not (null jobsWaiting) + +-- | Whether we should release a token from the semaphore: +-- there are no pending jobs and we can release a token. +guardRelease :: JobResources -> Bool +guardRelease ( Jobs { tokensFree, tokensOwned, jobsWaiting } ) + = null jobsWaiting && tokensFree > 0 && tokensOwned > 1 + +--------------------------------------- +-- Semaphore jobserver implementation + +-- | Add one pending job to the jobserver. +-- +-- Blocks, waiting on the jobserver to supply a free token. +acquireJob :: TVar JobResources -> IO () +acquireJob jobs_tvar = do + (job_tmvar, _jobs0) <- tracedAtomically "acquire" $ + modifyJobResources jobs_tvar \ jobs -> do + job_tmvar <- newEmptyTMVar + return ((job_tmvar, jobs), addJob job_tmvar jobs) + atomically $ takeTMVar job_tmvar + +-- | Signal to the job server that one job has completed, +-- releasing its corresponding token. +releaseJob :: TVar JobResources -> IO () +releaseJob jobs_tvar = do + tracedAtomically "release" do + modifyJobResources jobs_tvar \ jobs -> do + massertPpr (tokensFree jobs < tokensOwned jobs) + (text "releaseJob: more free jobs than owned jobs!") + return ((), addFreeToken jobs) + + +-- | Release all tokens owned from the semaphore (to clean up +-- the jobserver at the end). +cleanupJobserver :: Jobserver -> IO () +cleanupJobserver (Jobserver { jSemaphore = sem + , jobs = jobs_tvar }) + = do + Jobs { tokensOwned = owned } <- readTVarIO jobs_tvar + let toks_to_release = owned - 1 + -- Subtract off the implicit token: whoever spawned the ghc process + -- in the first place is responsible for that token. + releaseSemaphore sem toks_to_release + +-- | Dispatch the available tokens acquired from the semaphore +-- to the pending jobs in the job server. +dispatchTokens :: JobResources -> STM JobResources +dispatchTokens jobs@( Jobs { tokensFree = toks_free, jobsWaiting = wait } ) + | toks_free > 0 + , next `ConsOL` rest <- wait + -- There's a pending job and a free token: + -- pass on the token to that job, and recur. + = do + putTMVar next () + let jobs' = jobs { tokensFree = toks_free - 1, jobsWaiting = rest } + dispatchTokens jobs' + | otherwise + = return jobs + +-- | Update the available resources used from a semaphore, dispatching +-- any newly acquired resources. +-- +-- Invariant: if the number of available resources decreases, there +-- must be no pending jobs. +-- +-- All modifications should go through this function to ensure the contents +-- of the 'TVar' remains in normal form. +modifyJobResources :: HasCallStack => TVar JobResources + -> (JobResources -> STM (a, JobResources)) + -> STM (a, Maybe JobResources) +modifyJobResources jobs_tvar action = do + old_jobs <- readTVar jobs_tvar + (a, jobs) <- action old_jobs + + -- Check the invariant: if the number of free tokens has decreased, + -- there must be no pending jobs. + massertPpr (null (jobsWaiting jobs) || tokensFree jobs >= tokensFree old_jobs) $ + vcat [ text "modiyJobResources: pending jobs but fewer free tokens" ] + dispatched_jobs <- dispatchTokens jobs + writeTVar jobs_tvar dispatched_jobs + return (a, Just dispatched_jobs) + + +tracedAtomically_ :: String -> STM (Maybe JobResources) -> IO () +tracedAtomically_ s act = tracedAtomically s (((),) <$> act) + +tracedAtomically :: String -> STM (a, Maybe JobResources) -> IO a +tracedAtomically origin act = do + (a, mjr) <- atomically act + forM_ mjr $ \ jr -> do + -- Use the "jsem:" prefix to identify where the write traces are + traceEventIO ("jsem:" ++ renderJobResources origin jr) + return a + +renderJobResources :: String -> JobResources -> String +renderJobResources origin (Jobs own free pending) = showSDocUnsafe $ renderJSON $ + JSObject [ ("name", JSString origin) + , ("owned", JSInt own) + , ("free", JSInt free) + , ("pending", JSInt (length pending) ) + ] + + +-- | Spawn a new thread that waits on the semaphore in order to acquire +-- an additional token. +acquireThread :: Jobserver -> IO JobserverAction +acquireThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + let + wait_result_action :: Either MC.SomeException Bool -> IO () + wait_result_action wait_res = + tracedAtomically_ "acquire_thread" do + (r, jb) <- case wait_res of + Left (e :: MC.SomeException) -> do + return $ (Just e, Nothing) + Right success -> do + if success + then do + modifyJobResources jobs_tvar \ jobs -> + return (Nothing, addToken jobs) + else + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jb + wait_id <- forkWaitOnSemaphoreInterruptible sem wait_result_action + labelThread (waitingThreadId wait_id) "acquire_thread" + return $ Acquiring { activeWaitId = wait_id + , threadFinished = threadFinished_tmvar } + +-- | Spawn a thread to release ownership of one resource from the semaphore, +-- provided we have spare resources and no pending jobs. +releaseThread :: Jobserver -> IO JobserverAction +releaseThread (Jobserver { jSemaphore = sem, jobs = jobs_tvar }) = do + threadFinished_tmvar <- newEmptyTMVarIO + MC.mask_ do + -- Pre-release the resource so that another thread doesn't take control of it + -- just as we release the lock on the semaphore. + still_ok_to_release + <- tracedAtomically "pre_release" $ + modifyJobResources jobs_tvar \ jobs -> + if guardRelease jobs + -- TODO: should this also debounce? + then return (True , removeOwnedToken $ removeFreeToken jobs) + else return (False, jobs) + if not still_ok_to_release + then return Idle + else do + tid <- forkIO $ do + x <- MC.try $ releaseSemaphore sem 1 + tracedAtomically_ "post-release" $ do + (r, jobs) <- case x of + Left (e :: MC.SomeException) -> do + modifyJobResources jobs_tvar \ jobs -> + return (Just e, addToken jobs) + Right _ -> do + return (Nothing, Nothing) + putTMVar threadFinished_tmvar r + return jobs + labelThread tid "release_thread" + return Idle + +-- | When there are pending jobs but no free tokens, +-- spawn a thread to acquire a new token from the semaphore. +-- +-- See 'acquireThread'. +tryAcquire :: JobserverOptions + -> Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryAcquire opts js@( Jobserver { jobs = jobs_tvar }) + st@( JobserverState { jobserverAction = Idle } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardAcquire jobs + return do + action <- acquireThread js + -- Set a debounce after acquiring a token. + can_release_tvar <- registerDelay $ (releaseDebounce opts * 1000) + return $ st { jobserverAction = action + , canReleaseToken = can_release_tvar } +tryAcquire _ _ _ = retry + +-- | When there are free tokens and no pending jobs, +-- spawn a thread to release a token from the semamphore. +-- +-- See 'releaseThread'. +tryRelease :: Jobserver + -> JobserverState + -> STM (IO JobserverState) +tryRelease sjs@( Jobserver { jobs = jobs_tvar } ) + st@( JobserverState + { jobserverAction = Idle + , canReleaseToken = can_release_tvar } ) + = do + jobs <- readTVar jobs_tvar + guard $ guardRelease jobs + can_release <- readTVar can_release_tvar + guard can_release + return do + action <- releaseThread sjs + return $ st { jobserverAction = action } +tryRelease _ _ = retry + +-- | Wait for an active thread to finish. Once it finishes: +-- +-- - set the 'JobserverAction' to 'Idle', +-- - update the number of capabilities to reflect the number +-- of owned tokens from the semaphore. +tryNoticeIdle :: JobserverOptions + -> TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryNoticeIdle opts jobs_tvar jobserver_state + | Just threadFinished_tmvar <- activeThread_maybe $ jobserverAction jobserver_state + = sync_num_caps (canChangeNumCaps jobserver_state) threadFinished_tmvar + | otherwise + = retry -- no active thread: wait until jobserver isn't idle + where + sync_num_caps :: TVar Bool + -> TMVar (Maybe MC.SomeException) + -> STM (IO JobserverState) + sync_num_caps can_change_numcaps_tvar threadFinished_tmvar = do + mb_ex <- takeTMVar threadFinished_tmvar + for_ mb_ex MC.throwM + Jobs { tokensOwned } <- readTVar jobs_tvar + can_change_numcaps <- readTVar can_change_numcaps_tvar + guard can_change_numcaps + return do + x <- getNumCapabilities + can_change_numcaps_tvar_2 <- + if x == tokensOwned + then return can_change_numcaps_tvar + else do + setNumCapabilities tokensOwned + registerDelay $ (setNumCapsDebounce opts * 1000) + return $ + jobserver_state + { jobserverAction = Idle + , canChangeNumCaps = can_change_numcaps_tvar_2 } + +-- | Try to stop the current thread which is acquiring/releasing resources +-- if that operation is no longer relevant. +tryStopThread :: TVar JobResources + -> JobserverState + -> STM (IO JobserverState) +tryStopThread jobs_tvar jsj = do + case jobserverAction jsj of + Acquiring { activeWaitId = wait_id } -> do + jobs <- readTVar jobs_tvar + guard $ null (jobsWaiting jobs) + return do + interruptWaitOnSemaphore wait_id + return $ jsj { jobserverAction = Idle } + _ -> retry + +-- | Main jobserver loop: acquire/release resources as +-- needed for the pending jobs and available semaphore tokens. +jobserverLoop :: JobserverOptions -> Jobserver -> IO () +jobserverLoop opts sjs@(Jobserver { jobs = jobs_tvar }) + = do + true_tvar <- newTVarIO True + let init_state :: JobserverState + init_state = + JobserverState + { jobserverAction = Idle + , canChangeNumCaps = true_tvar + , canReleaseToken = true_tvar } + loop init_state + where + loop s = do + action <- atomically $ asum $ (\x -> x s) <$> + [ tryRelease sjs + , tryAcquire opts sjs + , tryNoticeIdle opts jobs_tvar + , tryStopThread jobs_tvar + ] + s <- action + loop s + +-- | Create a new jobserver using the given semaphore handle. +makeJobserver :: SemaphoreName -> IO (AbstractSem, IO ()) +makeJobserver sem_name = do + semaphore <- openSemaphore sem_name + let + init_jobs = + Jobs { tokensOwned = 1 + , tokensFree = 1 + , jobsWaiting = NilOL + } + jobs_tvar <- newTVarIO init_jobs + let + opts = defaultJobserverOptions -- TODO: allow this to be configured + sjs = Jobserver { jSemaphore = semaphore + , jobs = jobs_tvar } + loop_finished_mvar <- newEmptyMVar + loop_tid <- forkIOWithUnmask \ unmask -> do + r <- try $ unmask $ jobserverLoop opts sjs + putMVar loop_finished_mvar $ + case r of + Left e + | Just ThreadKilled <- fromException e + -> Nothing + | otherwise + -> Just e + Right () -> Nothing + labelThread loop_tid "job_server" + let + acquireSem = acquireJob jobs_tvar + releaseSem = releaseJob jobs_tvar + cleanupSem = do + -- this is interruptible + cleanupJobserver sjs + killThread loop_tid + mb_ex <- takeMVar loop_finished_mvar + for_ mb_ex MC.throwM + + return (AbstractSem{..}, cleanupSem) + +-- | Implement an abstract semaphore using a semaphore 'Jobserver' +-- which queries the system semaphore of the given name for resources. +runJSemAbstractSem :: SemaphoreName -- ^ the system semaphore to use + -> (AbstractSem -> IO a) -- ^ the operation to run + -- which requires a semaphore + -> IO a +runJSemAbstractSem sem action = MC.mask \ unmask -> do + (abs, cleanup) <- makeJobserver sem + r <- try $ unmask $ action abs + case r of + Left (e1 :: MC.SomeException) -> do + (_ :: Either MC.SomeException ()) <- MC.try cleanup + MC.throwM e1 + Right x -> cleanup $> x + +{- Note [Architecture of the Job Server] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In `-jsem` mode, the amount of parallelism that GHC can use is controlled by a +system semaphore. We take resources from the semaphore when we need them, and +give them back if we don't have enough to do. + +A naive implementation would just take and release the semaphore around performing +the action, but this leads to two issues: + +* When taking a token in the semaphore, we must call `setNumCapabilities` in order + to adjust how many capabilities are available for parallel garbage collection. + This causes unnecessary synchronisations. +* We want to implement a debounce, so that whilst there is pending work in the + current process we prefer to keep hold of resources from the semaphore. + This reduces overall memory usage, as there are fewer live GHC processes at once. + +Therefore, the obtention of semaphore resources is separated away from the +request for the resource in the driver. + +A token from the semaphore is requested using `acquireJob`. This creates a pending +job, which is a MVar that can be filled in to signal that the requested token is ready. + +When the job is finished, the token is released by calling `releaseJob`, which just +increases the number of `free` jobs. If there are more pending jobs when the free count +is increased, the token is immediately reused (see `modifyJobResources`). + +The `jobServerLoop` interacts with the system semaphore: when there are pending +jobs, `acquireThread` blocks, waiting for a token from the semaphore. Once a +token is obtained, it increases the owned count. + +When GHC has free tokens (tokens from the semaphore that it is not using), +no pending jobs, and the debounce has expired, then `releaseThread` will +release tokens back to the global semaphore. + +`tryStopThread` attempts to kill threads which are waiting to acquire a resource +when we no longer need it. For example, consider that we attempt to acquire two +tokens, but the first job finishes before we acquire the second token. +This second token is no longer needed, so we should cancel the wait +(as it would not be used to do any work, and not be returned until the debounce). +We only need to kill `acquireJob`, because `releaseJob` never blocks. + +Note [Eventlog Messages for jsem] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It can be tricky to verify that the work is shared adequately across different +processes. To help debug this, we output the values of `JobResource` to the +eventlog whenever the global state changes. There are some scripts which can be used +to analyse this output and report statistics about core saturation in the +GitHub repo (https://github.com/mpickering/ghc-jsem-analyse). + +-} ===================================== compiler/GHC/Driver/Pipeline/LogQueue.hs ===================================== @@ -100,10 +100,10 @@ dequeueLogQueueQueue (LogQueueQueue n lqq) = case IM.minViewWithKey lqq of Just ((k, v), lqq') | k == n -> Just (v, LogQueueQueue (n + 1) lqq') _ -> Nothing -logThread :: Int -> Int -> Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit +logThread :: Logger -> TVar Bool -- Signal that no more new logs will be added, clear the queue and exit -> TVar LogQueueQueue -- Queue for logs -> IO (IO ()) -logThread _ _ logger stopped lqq_var = do +logThread logger stopped lqq_var = do finished_var <- newEmptyMVar _ <- forkIO $ print_logs *> putMVar finished_var () return (takeMVar finished_var) ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Driver.Session ( needSourceNotes, OnOff(..), DynFlags(..), + ParMakeCount(..), outputFile, objectSuf, ways, FlagSpec(..), HasDynFlags(..), ContainsDynFlags(..), @@ -467,9 +468,9 @@ data DynFlags = DynFlags { ruleCheck :: Maybe String, strictnessBefore :: [Int], -- ^ Additional demand analysis - parMakeCount :: Maybe Int, -- ^ The number of modules to compile in parallel - -- in --make mode, where Nothing ==> compile as - -- many in parallel as there are CPUs. + parMakeCount :: Maybe ParMakeCount, + -- ^ The number of modules to compile in parallel + -- If unspecified, compile with a single job. enableTimeStats :: Bool, -- ^ Enable RTS timing statistics? ghcHeapSize :: Maybe Int, -- ^ The heap size to set. @@ -791,6 +792,16 @@ instance (Monad m, HasDynFlags m) => HasDynFlags (ExceptT e m) where class ContainsDynFlags t where extractDynFlags :: t -> DynFlags +-- | The type for the -jN argument, specifying that -j on its own represents +-- using the number of machine processors. +data ParMakeCount + -- | Use this many processors (@-j@ flag). + = ParMakeThisMany Int + -- | Use parallelism with as many processors as possible (@-j@ flag without an argument). + | ParMakeNumProcessors + -- | Use the specific semaphore @@ to control parallelism (@-jsem @ flag). + | ParMakeSemaphore FilePath + ----------------------------------------------------------------------------- -- Accessors from 'DynFlags' @@ -1154,7 +1165,7 @@ defaultDynFlags mySettings = historySize = 20, strictnessBefore = [], - parMakeCount = Just 1, + parMakeCount = Nothing, enableTimeStats = False, ghcHeapSize = Nothing, @@ -2120,14 +2131,16 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "j" (OptIntSuffix (\n -> case n of Just n - | n > 0 -> upd (\d -> d { parMakeCount = Just n }) + | n > 0 -> upd (\d -> d { parMakeCount = Just (ParMakeThisMany n) }) | otherwise -> addErr "Syntax: -j[n] where n > 0" - Nothing -> upd (\d -> d { parMakeCount = Nothing }))) + Nothing -> upd (\d -> d { parMakeCount = Just ParMakeNumProcessors }))) -- When the number of parallel builds -- is omitted, it is the same -- as specifying that the number of -- parallel builds is equal to the -- result of getNumProcessors + , make_ord_flag defGhcFlag "jsem" $ hasArg $ \f d -> d { parMakeCount = Just (ParMakeSemaphore f) } + , make_ord_flag defFlag "instantiated-with" (sepArg setUnitInstantiations) , make_ord_flag defFlag "this-component-id" (sepArg setUnitInstanceOf) ===================================== compiler/ghc.cabal.in ===================================== @@ -85,6 +85,7 @@ Library hpc == 0.6.*, transformers >= 0.5 && < 0.7, exceptions == 0.10.*, + semaphore-compat, stm, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, @@ -436,6 +437,7 @@ Library GHC.Driver.GenerateCgIPEStub GHC.Driver.Hooks GHC.Driver.LlvmConfigCache + GHC.Driver.MakeSem GHC.Driver.Main GHC.Driver.Make GHC.Driver.MakeFile ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -87,6 +87,13 @@ Compiler deriving instance TypeError (Text "Boo") => Bar Baz +- GHC Proposal `#540 https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0540-jsem.rst`_ has been implemented. + This adds the `-jsem`:ghc-flag: flag, which instructs GHC to act as a jobserver client. + This enables multiple GHC processes running at once to share system resources + with each other, communicating via the system semaphore specified by + the flag argument. + + GHCi ~~~~ ===================================== docs/users_guide/using.rst ===================================== @@ -751,6 +751,60 @@ search path (see :ref:`search-path`). number of processors. Note that compilation of a module may not begin until its dependencies have been built. + +GHC Jobserver Protocol +~~~~~~~~~~~~~~~~~~~~~~ + +The GHC Jobserver Protocol was specified in `GHC proposal #540 `__. + +This protocol allows +a server to dynamically invoke many instances of a client process, +while restricting all of those instances to use no more than capabilities. +This is achieved by coordination over a system semaphore (either a POSIX +semaphore in the case of Linux and Darwin, or a Win32 semaphore +in the case of Windows platforms). + +There are two kinds of participants in the GHC Jobserver protocol: + +- The *jobserver* creates a system semaphore with a certain number of + available tokens. + + Each time the jobserver wants to spawn a new jobclient subprocess, it **must** + first acquire a single token from the semaphore, before spawning + the subprocess. This token **must** be released once the subprocess terminates. + + Once work is finished, the jobserver **must** destroy the semaphore it created. + +- A *jobclient* is a subprocess spawned by the jobserver or another jobclient. + + Each jobclient starts with one available token (its *implicit token*, + which was acquired by the parent which spawned it), and can request more + tokens through the Jobserver Protocol by waiting on the semaphore. + + Each time a jobclient wants to spawn a new jobclient subprocess, it **must** + pass on a single token to the child jobclient. This token can either be the + jobclient's implicit token, or another token which the jobclient acquired + from the semaphore. + + Each jobclient **must** release exactly as many tokens as it has acquired from + the semaphore (this does not include the implicit tokens). + + GHC itself acts as a jobclient which can be enabled by using the flag ``-jsem``. + +.. ghc-flag:: -jsem + :shortdesc: When compiling with :ghc-flag:`--make`, coordinate with + other processes through the semaphore ⟨sem⟩ to compile + modules in parallel. + :type: dynamic + :category: misc + + Perform compilation in parallel when possible, coordinating with other + processes through the semaphore ⟨sem⟩ (specified as a string). + Error if the semaphore doesn't exist. + + Use of ``-jsem`` will override use of :ghc-flag:``-j[⟨n⟩]``, + and vice-versa. + .. _multi-home-units: Multiple Home Units ===================================== hadrian/src/Packages.hs ===================================== @@ -8,7 +8,7 @@ module Packages ( ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, libffi, mtl, parsec, pretty, primitive, process, remoteIserv, rts, - runGhc, stm, templateHaskell, terminfo, text, time, timeout, touchy, + runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, touchy, transformers, unlit, unix, win32, xhtml, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace, ghcPackages, isGhcPackage, @@ -39,7 +39,7 @@ ghcPackages = , exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh , ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl - , parsec, pretty, process, rts, runGhc, stm, templateHaskell + , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell , terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml , timeout , lintersCommon @@ -55,7 +55,7 @@ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, count exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcCompact, ghcConfig, ghcHeap, ghci, ghciWrapper, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl, - parsec, pretty, primitive, process, rts, runGhc, stm, templateHaskell, + parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml, timeout, lintersCommon, lintNotes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace @@ -110,6 +110,7 @@ process = lib "process" remoteIserv = util "remote-iserv" rts = top "rts" runGhc = util "runghc" +semaphoreCompat = lib "semaphore-compat" stm = lib "stm" templateHaskell = lib "template-haskell" terminfo = lib "terminfo" ===================================== hadrian/src/Rules/ToolArgs.hs ===================================== @@ -171,6 +171,7 @@ toolTargets = [ binary , templateHaskell , text , transformers + , semaphoreCompat , unlit -- # executable ] ++ if windowsHost then [ win32 ] else [ unix ] ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -95,6 +95,7 @@ stage0Packages = do , hpcBin , mtl , parsec + , semaphoreCompat , time , templateHaskell , text @@ -142,6 +143,7 @@ stage1Packages = do , integerGmp , pretty , rts + , semaphoreCompat , stm , unlit , xhtml ===================================== libraries/base/GHC/IO/Device.hs ===================================== @@ -35,7 +35,7 @@ import {-# SOURCE #-} GHC.IO.Exception ( unsupportedOperation ) -- | A low-level I/O provider where the data is bytes in memory. -- The Word64 offsets currently have no effect on POSIX system or consoles --- where the implicit behaviour of the C runtime is assume to move the file +-- where the implicit behaviour of the C runtime is assumed to move the file -- pointer on every read/write without needing an explicit seek. class RawIO a where -- | Read up to the specified number of bytes starting from a specified @@ -107,7 +107,7 @@ class IODevice a where -- | some devices (e.g. terminals) support a "raw" mode where -- characters entered are immediately made available to the program. - -- If available, this operations enables raw mode. + -- If available, this operation enables raw mode. setRaw :: a -> Bool -> IO () setRaw _ _ = ioe_unsupportedOperation ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -268,7 +268,7 @@ char8 = Latin1.latin1 -- -- 2. If the underlying encoding is not itself roundtrippable, this mechanism -- can fail. Roundtrippable encodings are those which have an injective mapping --- into Unicode. Almost all encodings meet this criteria, but some do not. Notably, +-- into Unicode. Almost all encodings meet this criterion, but some do not. Notably, -- Shift-JIS (CP932) and Big5 contain several different encodings of the same -- Unicode codepoint. -- ===================================== libraries/base/GHC/IO/Handle.hs ===================================== @@ -193,7 +193,7 @@ hLookAhead handle = -- -- * if @hdl@ is writable, the buffer is flushed as for 'hFlush'; -- --- * if @hdl@ is not writable, the contents of the buffer is discarded. +-- * if @hdl@ is not writable, the contents of the buffer are discarded. -- -- This operation may fail with: -- @@ -296,7 +296,7 @@ hFlush handle = wantWritableHandle "hFlush" handle flushWriteBuffer -- | The action 'hFlushAll' @hdl@ flushes all buffered data in @hdl@, -- including any buffered read data. Buffered read data is flushed --- by seeking the file position back to the point before the bufferred +-- by seeking the file position back to the point before the buffered -- data was read, and hence only works if @hdl@ is seekable (see -- 'hIsSeekable'). -- ===================================== libraries/base/GHC/IO/SubSystem.hs ===================================== @@ -39,7 +39,7 @@ infixl 7 -- | Conditionally execute an action depending on the configured I/O subsystem. -- On POSIX systems always execute the first action. --- On windows execute the second action if WINIO as active, otherwise fall back to +-- On Windows execute the second action if WINIO as active, otherwise fall back to -- the first action. conditional :: a -> a -> a #if defined(mingw32_HOST_OS) ===================================== libraries/base/GHC/List.hs ===================================== @@ -1084,7 +1084,7 @@ splitAt n ls #endif /* USE_REPORT_PRELUDE */ -- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where --- first element is longest prefix (possibly empty) of @xs@ of elements that +-- first element is the longest prefix (possibly empty) of @xs@ of elements that -- satisfy @p@ and second element is the remainder of the list: -- -- >>> span (< 3) [1,2,3,4,1,2,3,4] ===================================== libraries/base/GHC/TypeNats.hs ===================================== @@ -68,7 +68,7 @@ import GHC.TypeNats.Internal(CmpNat) -- | A type synonym for 'Natural'. -- --- Prevously, this was an opaque data type, but it was changed to a type +-- Previously, this was an opaque data type, but it was changed to a type -- synonym. -- -- @since 4.16.0.0 ===================================== libraries/semaphore-compat ===================================== @@ -0,0 +1 @@ +Subproject commit 663ef75467995acf41c51d3e21d03347e85b844e ===================================== packages ===================================== @@ -65,5 +65,6 @@ libraries/Win32 - - https:/ libraries/xhtml - - https://github.com/haskell/xhtml.git libraries/exceptions - - https://github.com/ekmett/exceptions.git nofib nofib - - +libraries/semaphore-compat - - - libraries/stm - - ssh://git at github.com/haskell/stm.git . - ghc.git - ===================================== rts/Threads.c ===================================== @@ -872,6 +872,7 @@ StgMutArrPtrs *listThreads(Capability *cap) const StgWord size = n_threads + mutArrPtrsCardTableSize(n_threads); StgMutArrPtrs *arr = (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size); + SET_HDR(arr, &stg_MUT_ARR_PTRS_DIRTY_info, CCS_SYSTEM); TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0); arr->ptrs = n_threads; arr->size = size; ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -260,7 +260,7 @@ test('hs_try_putmvar001', [ when(opsys('mingw32'),skip), # uses pthread APIs in the C code only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip + req_c ], compile_and_run, ['hs_try_putmvar001_c.c']) @@ -270,7 +270,7 @@ test('hs_try_putmvar001', test('hs_try_putmvar002', [pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar002_setup'), omit_ways(['ghci']), - js_skip, + req_c, extra_run_opts('1 8 10000')], compile_and_run, ['hs_try_putmvar002_c.c']) @@ -280,7 +280,7 @@ test('hs_try_putmvar003', when(opsys('mingw32'),skip), # uses pthread APIs in the C code pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar003_setup'), only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip, + req_c, extra_run_opts('1 16 32 100'), fragile_for(16361, ['threaded1']) ], ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -192,7 +192,7 @@ test('T9274', [omit_ways(['ghci'])], compile_and_run, ['']) test('ffi023', [ omit_ways(['ghci']), extra_run_opts('1000 4'), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory ffi023_setup') ], # The ffi023_setup hack is to ensure that we generate # ffi023_stub.h before compiling ffi023_c.c, which @@ -206,7 +206,7 @@ test('rts_clearMemory', [ extra_ways(['g1', 'nursery_chunks', 'nonmoving', 'compacting_gc']), # On windows, nonmoving way fails with bad exit code (2816) when(opsys('mingw32'), fragile(23091)), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory rts_clearMemory_setup') ], # Same hack as ffi023 compile_and_run, ['rts_clearMemory_c.c -no-hs-main']) ===================================== testsuite/tests/primops/should_run/T23071.hs ===================================== @@ -0,0 +1,5 @@ +import Control.Monad +import GHC.Conc.Sync + +main = replicateM_ 1000000 $ listThreads >>= print + ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -60,3 +60,4 @@ test('UnliftedTVar2', normal, compile_and_run, ['']) test('UnliftedWeakPtr', normal, compile_and_run, ['']) test('T21624', normal, compile_and_run, ['']) +test('T23071', ignore_stdout, compile_and_run, ['']) ===================================== testsuite/tests/rts/T15894/all.T ===================================== @@ -1,5 +1,5 @@ test('T15894', [ extra_files(['copysign.c', 'main.hs']), when(ghc_dynamic(), skip) - , js_broken(22359) + , req_c ], makefile_test, ['T15894']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -251,7 +251,7 @@ test('T5993', extra_run_opts('+RTS -k8 -RTS'), compile_and_run, ['']) test('T6006', [ omit_ways(prof_ways + ['ghci']), pre_cmd('$MAKE -s --no-print-directory T6006_setup'), - js_skip + req_c ], # The T6006_setup hack is to ensure that we generate # T6006_stub.h before compiling T6006_c.c, which ===================================== testsuite/tests/rts/linker/all.T ===================================== @@ -93,13 +93,13 @@ test('T5435_v_gcc', test('T5435_dyn_asm', [extra_files(['T5435.hs', 'T5435_asm.c']), fragile(22970), - js_skip, # dynamic linking not supported by the JS backend + req_c, check_stdout(checkDynAsm)], makefile_test, ['T5435_dyn_asm']) test('T5435_dyn_gcc', [extra_files(['T5435.hs', 'T5435_gcc.c']), fragile(22970), - js_skip], # dynamic linking not supported by the JS backend + req_c], makefile_test, ['T5435_dyn_gcc']) ###################################### View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12497eb922d04fd0f53362b932402ba158dc8bd2...5afb844f3534c59f5867ac6458e3bb04dcd6c119 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12497eb922d04fd0f53362b932402ba158dc8bd2...5afb844f3534c59f5867ac6458e3bb04dcd6c119 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 13:09:32 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 21 Apr 2023 09:09:32 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] WIP #23158 Message-ID: <64428b0c4b63a_178e74616b90d48871c0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 61633df8 by Rodrigo Mesquita at 2023-04-21T14:09:12+01:00 WIP #23158 - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/DataCon.hs - compiler/GHC/StgToCmm/Layout.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -30,6 +30,7 @@ module GHC.Cmm.CLabel ( mkApEntryLabel, mkApInfoTableLabel, mkClosureTableLabel, + mkShortConAppLabel, mkBytesLabel, mkLocalBlockLabel, @@ -521,6 +522,8 @@ data IdLabelInfo | ClosureTable -- ^ Table of closures for Enum tycons + | ShortConApp -- ^ Temporary name, temporary documentation. A special static closure for nullarydatacons + | Bytes -- ^ Content of a string literal. See -- Note [Bytes label]. | BlockInfoTable -- ^ Like LocalInfoTable but for a proc-point block @@ -554,6 +557,7 @@ instance Outputable IdLabelInfo where ppr (ConEntry mn) = text "ConEntry" <+> ppr mn ppr (ConInfoTable mn) = text "ConInfoTable" <+> ppr mn ppr ClosureTable = text "ClosureTable" + ppr ShortConApp = text "ShortConApp" -- ROMES:TODO: name ppr Bytes = text "Bytes" ppr BlockInfoTable = text "BlockInfoTable" ppr (IdTickyInfo info) = text "IdTickyInfo" <+> ppr info @@ -619,6 +623,7 @@ mkClosureLabel :: Name -> CafInfo -> CLabel mkInfoTableLabel :: Name -> CafInfo -> CLabel mkEntryLabel :: Name -> CafInfo -> CLabel mkClosureTableLabel :: Name -> CafInfo -> CLabel +mkShortConAppLabel :: Name -> CafInfo -> CLabel mkConInfoTableLabel :: Name -> ConInfoTableLocation -> CLabel mkBytesLabel :: Name -> CLabel mkClosureLabel name c = IdLabel name c Closure @@ -628,6 +633,7 @@ mkInfoTableLabel name c | otherwise = IdLabel name c LocalInfoTable mkEntryLabel name c = IdLabel name c Entry mkClosureTableLabel name c = IdLabel name c ClosureTable +mkShortConAppLabel name c = IdLabel name c ShortConApp -- Special case for the normal 'DefinitionSite' case so that the 'ConInfoTable' application can be floated to a CAF. mkConInfoTableLabel name DefinitionSite = IdLabel name NoCafRefs (ConInfoTable DefinitionSite) mkConInfoTableLabel name k = IdLabel name NoCafRefs (ConInfoTable k) @@ -780,6 +786,7 @@ isForeignLabel _lbl = False isStaticClosureLabel :: CLabel -> Bool -- Closure defined in haskell (.hs) isStaticClosureLabel (IdLabel _ _ Closure) = True +isStaticClosureLabel (IdLabel _ _ ShortConApp) = True -- Closure defined in cmm isStaticClosureLabel (CmmLabel _ _ _ CmmClosure) = True isStaticClosureLabel _lbl = False @@ -1251,6 +1258,7 @@ idInfoLabelType info = ConInfoTable {} -> DataLabel ClosureTable -> DataLabel IdTickyInfo{} -> DataLabel + ShortConApp -> DataLabel Bytes -> DataLabel _ -> CodeLabel @@ -1655,6 +1663,7 @@ ppIdFlavor x = pp_cSEP <> case x of UsageSite m n -> pprModule m <> pp_cSEP <> int n <> pp_cSEP <> text "con_info" ClosureTable -> text "closure_tbl" + ShortConApp -> text "special_con_app" -- ROMES:TODO: Name Bytes -> text "bytes" BlockInfoTable -> text "info" ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -233,15 +233,16 @@ mkModuleInit cost_centre_info this_mod hpc_info cgEnumerationTyCon :: TyCon -> FCode () cgEnumerationTyCon tycon = do platform <- getPlatform + -- ROMES:TODO: Kind of code I need to emit conapp declarations for nullary gadt emitRODataLits (mkClosureTableLabel (tyConName tycon) NoCafRefs) [ CmmLabelOff (mkClosureLabel (dataConName con) NoCafRefs) (tagForCon platform con) | con <- tyConDataCons tycon] +-- | Generate the entry code and associated info table for a constructor. +-- Where are generating the static closure at all? cgDataCon :: ConInfoTableLocation -> DataCon -> FCode () --- Generate the entry code, info tables, and (for niladic constructor) --- the static closure, for a constructor. cgDataCon mn data_con = do { massert (not (isUnboxedTupleDataCon data_con || isUnboxedSumDataCon data_con)) ; profile <- getProfile @@ -264,6 +265,12 @@ cgDataCon mn data_con , rep_ty <- typePrimRep (scaledThing ty) , not (isVoidRep rep_ty) ] + -- In the case of a data con that isn't nullary in its core + -- representation, but that has no zero-width args, we generate a + -- special static closure alongside its normal _closure + -- ROMES:TODO: Write a long note about it + ; when (not (isNullaryRepDataCon data_con) && hasNoNonZeroWidthArgs data_con) (cgNullaryDataConApp data_con) + ; emitClosureAndInfoTable platform dyn_info_tbl NativeDirectCall [] $ -- NB: the closure pointer is assumed *untagged* on -- entry to a constructor. If the pointer is tagged, ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -92,6 +92,24 @@ cgTopRhsClosure platform rec id ccs upd_flag args body = gen_code :: LambdaFormInfo -> CLabel -> FCode () + -- special case for a datacon worker only takes zero-width arguments: + -- + -- since the RHS is a fully saturated application of the worker (the void + -- args are dropped after unarisation), and because we generate precomputed + -- static closures for these nullary data constructors that take zero-width + -- arguments, the closure's body must be the pointer to the con_info table + -- ROMES:TODO: I think this path no longer works + -- gen_code _ closure_label + -- | StgConApp con _ conargs _ <- body + -- , null (assertNonVoidStgArgs conargs) -- After unarisation, StgConApp are guaranteed + -- -- not to be applied to void arguments, but we + -- -- might not have run unarisation yet at this + -- -- point. Right? Otherwise, we could have a match + -- -- on empty list of args + -- = assert (hasNoNonZeroWidthArgs con) $ + -- assert (null (nonVoidIds args)) $ + -- emitDataCon closure_label indStaticInfoTable ccs [] + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -12,7 +12,8 @@ ----------------------------------------------------------------------------- module GHC.StgToCmm.DataCon ( - cgTopRhsCon, buildDynCon, bindConArgs + cgTopRhsCon, buildDynCon, bindConArgs, + cgNullaryDataConApp ) where import GHC.Prelude @@ -328,7 +329,15 @@ precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid St precomputedStaticConInfo_maybe cfg binder con [] -- Nullary constructors (list of nonvoid args is null) = assert (hasNoNonZeroWidthArgs con) $ - Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + if isDataConWorkId binder && not (isNullaryRepDataCon con) + -- this data con worker (TODO: what about wrappers?) only has zero-width + -- args, so we point to its short con app closure instead of its + -- function ( rememeber, we generate 2 closures for a data con that only + -- has zero-width args: one for the function it actually is, another for + -- the precomputed static closure we can still have for it ) + then Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + (CmmLabel (mkShortConAppLabel (dataConName con) NoCafRefs)) + else Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS @@ -373,6 +382,14 @@ precomputedStaticConInfo_maybe cfg binder con [arg] precomputedStaticConInfo_maybe _ _ _ _ = Nothing +-- Closely related to precomputed static things,,, write long note: ROMES:TODO +cgNullaryDataConApp :: DataCon -> FCode () +cgNullaryDataConApp con + = emitRODataLits (mkShortConAppLabel (dataConName con) NoCafRefs) + [ CmmLabel (mkConInfoTableLabel (dataConName con) DefinitionSite) + ] + + --------------------------------------------------------------- -- Binding constructor arguments --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Layout.hs ===================================== @@ -653,6 +653,6 @@ emitClosureAndInfoTable :: Platform -> CmmInfoTable -> Convention -> [LocalReg] -> FCode () -> FCode () emitClosureAndInfoTable platform info_tbl conv args body = do { (_, blks) <- getCodeScoped body - ; let entry_lbl = toEntryLbl platform (cit_lbl info_tbl) + ; let entry_lbl = toEntryLbl platform (cit_lbl info_tbl) -- _entry label for this declaration ; emitProcWithConvention conv (Just info_tbl) entry_lbl args blks } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61633df8f4c0d85c8eb13c10be2b20932def4004 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61633df8f4c0d85c8eb13c10be2b20932def4004 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 13:13:33 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Fri, 21 Apr 2023 09:13:33 -0400 Subject: [Git][ghc/ghc][wip/sized-literals] Add sized primitive literal syntax Message-ID: <64428bfd33376_178e7461bea2d88876f3@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/sized-literals at Glasgow Haskell Compiler / GHC Commits: c35c9dbf by Ben Orchard at 2023-04-21T15:13:12+02:00 Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - 26 changed files: - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Lit.hs - docs/users_guide/9.8.1-notes.rst - + docs/users_guide/exts/extended_literals.rst - docs/users_guide/exts/literals.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/exts/stolen_syntax.rst - libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs - testsuite/tests/driver/T4437.hs - + testsuite/tests/extendedliterals/all.T - + testsuite/tests/extendedliterals/extendedliterals01.hs - + testsuite/tests/extendedliterals/extendedliterals02.hs - + testsuite/tests/extendedliterals/extendedliterals03.hs - + testsuite/tests/extendedliterals/extendedliterals03.stdout - − testsuite/tests/ghci/should_run/SizedLiterals.hs - − testsuite/tests/ghci/should_run/SizedLiteralsA.hs - testsuite/tests/ghci/should_run/all.T - testsuite/tests/printer/Ppr038.hs - utils/check-exact/ExactPrint.hs - utils/haddock Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3745,6 +3745,7 @@ xFlagsDeps = [ flagSpec "ExplicitForAll" LangExt.ExplicitForAll, flagSpec "ExplicitNamespaces" LangExt.ExplicitNamespaces, flagSpec "ExtendedDefaultRules" LangExt.ExtendedDefaultRules, + flagSpec "ExtendedLiterals" LangExt.ExtendedLiterals, flagSpec "FlexibleContexts" LangExt.FlexibleContexts, flagSpec "FlexibleInstances" LangExt.FlexibleInstances, flagSpec "ForeignFunctionInterface" LangExt.ForeignFunctionInterface, ===================================== compiler/GHC/Hs/Lit.hs ===================================== @@ -50,7 +50,13 @@ type instance XHsStringPrim (GhcPass _) = SourceText type instance XHsInt (GhcPass _) = NoExtField type instance XHsIntPrim (GhcPass _) = SourceText type instance XHsWordPrim (GhcPass _) = SourceText +type instance XHsInt8Prim (GhcPass _) = SourceText +type instance XHsInt16Prim (GhcPass _) = SourceText +type instance XHsInt32Prim (GhcPass _) = SourceText type instance XHsInt64Prim (GhcPass _) = SourceText +type instance XHsWord8Prim (GhcPass _) = SourceText +type instance XHsWord16Prim (GhcPass _) = SourceText +type instance XHsWord32Prim (GhcPass _) = SourceText type instance XHsWord64Prim (GhcPass _) = SourceText type instance XHsInteger (GhcPass _) = SourceText type instance XHsRat (GhcPass _) = NoExtField @@ -128,14 +134,20 @@ hsLitNeedsParens p = go go (HsString {}) = False go (HsStringPrim {}) = False go (HsInt _ x) = p > topPrec && il_neg x - go (HsIntPrim {}) = False - go (HsWordPrim {}) = False - go (HsInt64Prim {}) = False - go (HsWord64Prim {}) = False go (HsInteger _ x _) = p > topPrec && x < 0 go (HsRat _ x _) = p > topPrec && fl_neg x go (HsFloatPrim {}) = False go (HsDoublePrim {}) = False + go (HsIntPrim {}) = False + go (HsInt8Prim {}) = False + go (HsInt16Prim {}) = False + go (HsInt32Prim {}) = False + go (HsInt64Prim {}) = False + go (HsWordPrim {}) = False + go (HsWord8Prim {}) = False + go (HsWord16Prim {}) = False + go (HsWord64Prim {}) = False + go (HsWord32Prim {}) = False go (XLit _) = False -- | Convert a literal from one index type to another @@ -147,7 +159,13 @@ convertLit (HsStringPrim a x) = HsStringPrim a x convertLit (HsInt a x) = HsInt a x convertLit (HsIntPrim a x) = HsIntPrim a x convertLit (HsWordPrim a x) = HsWordPrim a x +convertLit (HsInt8Prim a x) = HsInt8Prim a x +convertLit (HsInt16Prim a x) = HsInt16Prim a x +convertLit (HsInt32Prim a x) = HsInt32Prim a x convertLit (HsInt64Prim a x) = HsInt64Prim a x +convertLit (HsWord8Prim a x) = HsWord8Prim a x +convertLit (HsWord16Prim a x) = HsWord16Prim a x +convertLit (HsWord32Prim a x) = HsWord32Prim a x convertLit (HsWord64Prim a x) = HsWord64Prim a x convertLit (HsInteger a x b) = HsInteger a x b convertLit (HsRat a x b) = HsRat a x b @@ -182,8 +200,14 @@ instance Outputable (HsLit (GhcPass p)) where ppr (HsFloatPrim _ f) = ppr f <> primFloatSuffix ppr (HsDoublePrim _ d) = ppr d <> primDoubleSuffix ppr (HsIntPrim st i) = pprWithSourceText st (pprPrimInt i) - ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsInt8Prim st i) = pprWithSourceText st (pprPrimInt8 i) + ppr (HsInt16Prim st i) = pprWithSourceText st (pprPrimInt16 i) + ppr (HsInt32Prim st i) = pprWithSourceText st (pprPrimInt32 i) ppr (HsInt64Prim st i) = pprWithSourceText st (pprPrimInt64 i) + ppr (HsWordPrim st w) = pprWithSourceText st (pprPrimWord w) + ppr (HsWord8Prim st w) = pprWithSourceText st (pprPrimWord8 w) + ppr (HsWord16Prim st w) = pprWithSourceText st (pprPrimWord16 w) + ppr (HsWord32Prim st w) = pprWithSourceText st (pprPrimWord32 w) ppr (HsWord64Prim st w) = pprWithSourceText st (pprPrimWord64 w) -- in debug mode, print the expression that it's resolved to, too @@ -211,7 +235,13 @@ pmPprHsLit (HsStringPrim _ s) = pprHsBytes s pmPprHsLit (HsInt _ i) = integer (il_value i) pmPprHsLit (HsIntPrim _ i) = integer i pmPprHsLit (HsWordPrim _ w) = integer w +pmPprHsLit (HsInt8Prim _ i) = integer i +pmPprHsLit (HsInt16Prim _ i) = integer i +pmPprHsLit (HsInt32Prim _ i) = integer i pmPprHsLit (HsInt64Prim _ i) = integer i +pmPprHsLit (HsWord8Prim _ w) = integer w +pmPprHsLit (HsWord16Prim _ w) = integer w +pmPprHsLit (HsWord32Prim _ w) = integer w pmPprHsLit (HsWord64Prim _ w) = integer w pmPprHsLit (HsInteger _ i _) = integer i pmPprHsLit (HsRat _ f _) = ppr f ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -77,7 +77,13 @@ hsLitType (HsStringPrim _ _) = addrPrimTy hsLitType (HsInt _ _) = intTy hsLitType (HsIntPrim _ _) = intPrimTy hsLitType (HsWordPrim _ _) = wordPrimTy +hsLitType (HsInt8Prim _ _) = int8PrimTy +hsLitType (HsInt16Prim _ _) = int16PrimTy +hsLitType (HsInt32Prim _ _) = int32PrimTy hsLitType (HsInt64Prim _ _) = int64PrimTy +hsLitType (HsWord8Prim _ _) = word8PrimTy +hsLitType (HsWord16Prim _ _) = word16PrimTy +hsLitType (HsWord32Prim _ _) = word32PrimTy hsLitType (HsWord64Prim _ _) = word64PrimTy hsLitType (HsInteger _ _ ty) = ty hsLitType (HsRat _ _ ty) = ty ===================================== compiler/GHC/HsToCore/Match/Literal.hs ===================================== @@ -106,7 +106,13 @@ dsLit l = do HsCharPrim _ c -> return (Lit (LitChar c)) HsIntPrim _ i -> return (Lit (mkLitIntWrap platform i)) HsWordPrim _ w -> return (Lit (mkLitWordWrap platform w)) + HsInt8Prim _ i -> return (Lit (mkLitInt8Wrap i)) + HsInt16Prim _ i -> return (Lit (mkLitInt16Wrap i)) + HsInt32Prim _ i -> return (Lit (mkLitInt32Wrap i)) HsInt64Prim _ i -> return (Lit (mkLitInt64Wrap i)) + HsWord8Prim _ w -> return (Lit (mkLitWord8Wrap w)) + HsWord16Prim _ w -> return (Lit (mkLitWord16Wrap w)) + HsWord32Prim _ w -> return (Lit (mkLitWord32Wrap w)) HsWord64Prim _ w -> return (Lit (mkLitWord64Wrap w)) -- This can be slow for very large literals. See Note [FractionalLit representation] @@ -455,10 +461,23 @@ getSimpleIntegralLit :: HsLit GhcTc -> Maybe (Integer, Type) getSimpleIntegralLit (HsInt _ IL{ il_value = i }) = Just (i, intTy) getSimpleIntegralLit (HsIntPrim _ i) = Just (i, intPrimTy) getSimpleIntegralLit (HsWordPrim _ i) = Just (i, wordPrimTy) +getSimpleIntegralLit (HsInt8Prim _ i) = Just (i, int8PrimTy) +getSimpleIntegralLit (HsInt16Prim _ i) = Just (i, int16PrimTy) +getSimpleIntegralLit (HsInt32Prim _ i) = Just (i, int32PrimTy) getSimpleIntegralLit (HsInt64Prim _ i) = Just (i, int64PrimTy) +getSimpleIntegralLit (HsWord8Prim _ i) = Just (i, word8PrimTy) +getSimpleIntegralLit (HsWord16Prim _ i) = Just (i, word16PrimTy) +getSimpleIntegralLit (HsWord32Prim _ i) = Just (i, word32PrimTy) getSimpleIntegralLit (HsWord64Prim _ i) = Just (i, word64PrimTy) getSimpleIntegralLit (HsInteger _ i ty) = Just (i, ty) -getSimpleIntegralLit _ = Nothing + +getSimpleIntegralLit HsChar{} = Nothing +getSimpleIntegralLit HsCharPrim{} = Nothing +getSimpleIntegralLit HsString{} = Nothing +getSimpleIntegralLit HsStringPrim{} = Nothing +getSimpleIntegralLit HsRat{} = Nothing +getSimpleIntegralLit HsFloatPrim{} = Nothing +getSimpleIntegralLit HsDoublePrim{} = Nothing -- | Extract the Char if the expression is a Char literal. getLHsCharLit :: LHsExpr GhcTc -> Maybe Char @@ -638,7 +657,13 @@ hsLitKey :: Platform -> HsLit GhcTc -> Literal -- HsLit does not. hsLitKey platform (HsIntPrim _ i) = mkLitIntWrap platform i hsLitKey platform (HsWordPrim _ w) = mkLitWordWrap platform w +hsLitKey _ (HsInt8Prim _ i) = mkLitInt8Wrap i +hsLitKey _ (HsInt16Prim _ i) = mkLitInt16Wrap i +hsLitKey _ (HsInt32Prim _ i) = mkLitInt32Wrap i hsLitKey _ (HsInt64Prim _ i) = mkLitInt64Wrap i +hsLitKey _ (HsWord8Prim _ w) = mkLitWord8Wrap w +hsLitKey _ (HsWord16Prim _ w) = mkLitWord16Wrap w +hsLitKey _ (HsWord32Prim _ w) = mkLitWord32Wrap w hsLitKey _ (HsWord64Prim _ w) = mkLitWord64Wrap w hsLitKey _ (HsCharPrim _ c) = mkLitChar c -- This following two can be slow. See Note [FractionalLit representation] ===================================== compiler/GHC/Parser.y ===================================== @@ -718,6 +718,14 @@ are the most common patterns, rewritten as regular expressions for clarity: PRIMSTRING { L _ (ITprimstring _ _) } PRIMINTEGER { L _ (ITprimint _ _) } PRIMWORD { L _ (ITprimword _ _) } + PRIMINTEGER8 { L _ (ITprimint8 _ _) } + PRIMINTEGER16 { L _ (ITprimint16 _ _) } + PRIMINTEGER32 { L _ (ITprimint32 _ _) } + PRIMINTEGER64 { L _ (ITprimint64 _ _) } + PRIMWORD8 { L _ (ITprimword8 _ _) } + PRIMWORD16 { L _ (ITprimword16 _ _) } + PRIMWORD32 { L _ (ITprimword32 _ _) } + PRIMWORD64 { L _ (ITprimword64 _ _) } PRIMFLOAT { L _ (ITprimfloat _) } PRIMDOUBLE { L _ (ITprimdouble _) } @@ -3876,6 +3884,22 @@ literal :: { Located (HsLit GhcPs) } $ getPRIMINTEGER $1 } | PRIMWORD { sL1 $1 $ HsWordPrim (getPRIMWORDs $1) $ getPRIMWORD $1 } + | PRIMINTEGER8 { sL1 $1 $ HsInt8Prim (getPRIMINTEGER8s $1) + $ getPRIMINTEGER8 $1 } + | PRIMINTEGER16 { sL1 $1 $ HsInt16Prim (getPRIMINTEGER16s $1) + $ getPRIMINTEGER16 $1 } + | PRIMINTEGER32 { sL1 $1 $ HsInt32Prim (getPRIMINTEGER32s $1) + $ getPRIMINTEGER32 $1 } + | PRIMINTEGER64 { sL1 $1 $ HsInt64Prim (getPRIMINTEGER64s $1) + $ getPRIMINTEGER64 $1 } + | PRIMWORD8 { sL1 $1 $ HsWord8Prim (getPRIMWORD8s $1) + $ getPRIMWORD8 $1 } + | PRIMWORD16 { sL1 $1 $ HsWord16Prim (getPRIMWORD16s $1) + $ getPRIMWORD16 $1 } + | PRIMWORD32 { sL1 $1 $ HsWord32Prim (getPRIMWORD32s $1) + $ getPRIMWORD32 $1 } + | PRIMWORD64 { sL1 $1 $ HsWord64Prim (getPRIMWORD64s $1) + $ getPRIMWORD64 $1 } | PRIMCHAR { sL1 $1 $ HsCharPrim (getPRIMCHARs $1) $ getPRIMCHAR $1 } | PRIMSTRING { sL1 $1 $ HsStringPrim (getPRIMSTRINGs $1) @@ -3916,43 +3940,59 @@ bars :: { ([SrcSpan],Int) } -- One or more bars happyError :: P a happyError = srcParseFail -getVARID (L _ (ITvarid x)) = x -getCONID (L _ (ITconid x)) = x -getVARSYM (L _ (ITvarsym x)) = x -getCONSYM (L _ (ITconsym x)) = x -getDO (L _ (ITdo x)) = x -getMDO (L _ (ITmdo x)) = x -getQVARID (L _ (ITqvarid x)) = x -getQCONID (L _ (ITqconid x)) = x -getQVARSYM (L _ (ITqvarsym x)) = x -getQCONSYM (L _ (ITqconsym x)) = x -getIPDUPVARID (L _ (ITdupipvarid x)) = x -getLABELVARID (L _ (ITlabelvarid _ x)) = x -getCHAR (L _ (ITchar _ x)) = x -getSTRING (L _ (ITstring _ x)) = x -getINTEGER (L _ (ITinteger x)) = x -getRATIONAL (L _ (ITrational x)) = x -getPRIMCHAR (L _ (ITprimchar _ x)) = x -getPRIMSTRING (L _ (ITprimstring _ x)) = x -getPRIMINTEGER (L _ (ITprimint _ x)) = x -getPRIMWORD (L _ (ITprimword _ x)) = x -getPRIMFLOAT (L _ (ITprimfloat x)) = x -getPRIMDOUBLE (L _ (ITprimdouble x)) = x -getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) -getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) -getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) +getVARID (L _ (ITvarid x)) = x +getCONID (L _ (ITconid x)) = x +getVARSYM (L _ (ITvarsym x)) = x +getCONSYM (L _ (ITconsym x)) = x +getDO (L _ (ITdo x)) = x +getMDO (L _ (ITmdo x)) = x +getQVARID (L _ (ITqvarid x)) = x +getQCONID (L _ (ITqconid x)) = x +getQVARSYM (L _ (ITqvarsym x)) = x +getQCONSYM (L _ (ITqconsym x)) = x +getIPDUPVARID (L _ (ITdupipvarid x)) = x +getLABELVARID (L _ (ITlabelvarid _ x)) = x +getCHAR (L _ (ITchar _ x)) = x +getSTRING (L _ (ITstring _ x)) = x +getINTEGER (L _ (ITinteger x)) = x +getRATIONAL (L _ (ITrational x)) = x +getPRIMCHAR (L _ (ITprimchar _ x)) = x +getPRIMSTRING (L _ (ITprimstring _ x)) = x +getPRIMINTEGER (L _ (ITprimint _ x)) = x +getPRIMWORD (L _ (ITprimword _ x)) = x +getPRIMINTEGER8 (L _ (ITprimint8 _ x)) = x +getPRIMINTEGER16 (L _ (ITprimint16 _ x)) = x +getPRIMINTEGER32 (L _ (ITprimint32 _ x)) = x +getPRIMINTEGER64 (L _ (ITprimint64 _ x)) = x +getPRIMWORD8 (L _ (ITprimword8 _ x)) = x +getPRIMWORD16 (L _ (ITprimword16 _ x)) = x +getPRIMWORD32 (L _ (ITprimword32 _ x)) = x +getPRIMWORD64 (L _ (ITprimword64 _ x)) = x +getPRIMFLOAT (L _ (ITprimfloat x)) = x +getPRIMDOUBLE (L _ (ITprimdouble x)) = x +getINLINE (L _ (ITinline_prag _ inl conl)) = (inl,conl) +getSPEC_INLINE (L _ (ITspec_inline_prag src True)) = (Inline src,FunLike) +getSPEC_INLINE (L _ (ITspec_inline_prag src False)) = (NoInline src,FunLike) getCOMPLETE_PRAGs (L _ (ITcomplete_prag x)) = x -getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l - -getINTEGERs (L _ (ITinteger (IL src _ _))) = src -getCHARs (L _ (ITchar src _)) = src -getSTRINGs (L _ (ITstring src _)) = src -getPRIMCHARs (L _ (ITprimchar src _)) = src -getPRIMSTRINGs (L _ (ITprimstring src _)) = src -getPRIMINTEGERs (L _ (ITprimint src _)) = src -getPRIMWORDs (L _ (ITprimword src _)) = src - -getLABELVARIDs (L _ (ITlabelvarid src _)) = src +getVOCURLY (L (RealSrcSpan l _) ITvocurly) = srcSpanStartCol l + +getINTEGERs (L _ (ITinteger (IL src _ _))) = src +getCHARs (L _ (ITchar src _)) = src +getSTRINGs (L _ (ITstring src _)) = src +getPRIMCHARs (L _ (ITprimchar src _)) = src +getPRIMSTRINGs (L _ (ITprimstring src _)) = src +getPRIMINTEGERs (L _ (ITprimint src _)) = src +getPRIMWORDs (L _ (ITprimword src _)) = src +getPRIMINTEGER8s (L _ (ITprimint8 src _)) = src +getPRIMINTEGER16s (L _ (ITprimint16 src _)) = src +getPRIMINTEGER32s (L _ (ITprimint32 src _)) = src +getPRIMINTEGER64s (L _ (ITprimint64 src _)) = src +getPRIMWORD8s (L _ (ITprimword8 src _)) = src +getPRIMWORD16s (L _ (ITprimword16 src _)) = src +getPRIMWORD32s (L _ (ITprimword32 src _)) = src +getPRIMWORD64s (L _ (ITprimword64 src _)) = src + +getLABELVARIDs (L _ (ITlabelvarid src _)) = src -- See Note [Pragma source text] in "GHC.Types.SourceText" for the following getINLINE_PRAGs (L _ (ITinline_prag _ inl _)) = inlineSpecSource inl ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -194,6 +194,10 @@ $docsym = [\| \^ \* \$] @exponent = @numspc [eE] [\-\+]? @decimal @bin_exponent = @numspc [pP] [\-\+]? @decimal + at binarylit = 0[bB] @numspc @binary + at octallit = 0[oO] @numspc @octal + at hexadecimallit = 0[xX] @numspc @hexadecimal + @qual = (@conid \.)+ @qvarid = @qual @varid @qconid = @qual @conid @@ -517,15 +521,15 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- <0> { -- Normal integral literals (:: Num a => a, from Integer) - @decimal { tok_num positive 0 0 decimal } - 0[bB] @numspc @binary / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } - 0[oO] @numspc @octal { tok_num positive 2 2 octal } - 0[xX] @numspc @hexadecimal { tok_num positive 2 2 hexadecimal } - @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } - @negative 0[bB] @numspc @binary / { negLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } - @negative 0[oO] @numspc @octal / { negLitPred } { tok_num negative 3 3 octal } - @negative 0[xX] @numspc @hexadecimal / { negLitPred } { tok_num negative 3 3 hexadecimal } + @decimal { tok_num positive 0 0 decimal } + @binarylit / { ifExtension BinaryLiteralsBit } { tok_num positive 2 2 binary } + @octallit { tok_num positive 2 2 octal } + @hexadecimallit { tok_num positive 2 2 hexadecimal } + @negative @decimal / { negLitPred } { tok_num negative 1 1 decimal } + @negative @binarylit / { negLitPred `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_num negative 3 3 binary } + @negative @octallit / { negLitPred } { tok_num negative 3 3 octal } + @negative @hexadecimallit / { negLitPred } { tok_num negative 3 3 hexadecimal } -- Normal rational literals (:: Fractional a => a, from Rational) @floating_point { tok_frac 0 tok_float } @@ -540,31 +544,116 @@ $unigraphic / { isSmartQuote } { smart_quote_error } -- Unboxed ints (:: Int#) and words (:: Word#) -- It's simpler (and faster?) to give separate cases to the negatives, -- especially considering octal/hexadecimal prefixes. - @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } - 0[bB] @numspc @binary \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } - 0[oO] @numspc @octal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } - 0[xX] @numspc @hexadecimal \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } - @negative @decimal \# / { negHashLitPred } { tok_primint negative 1 2 decimal } - @negative 0[bB] @numspc @binary \# / { negHashLitPred `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } - @negative 0[oO] @numspc @octal \# / { negHashLitPred } { tok_primint negative 3 4 octal } - @negative 0[xX] @numspc @hexadecimal \# - / { negHashLitPred } { tok_primint negative 3 4 hexadecimal } - - @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } - 0[bB] @numspc @binary \# \# / { ifExtension MagicHashBit `alexAndPred` - ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } - 0[oO] @numspc @octal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } - 0[xX] @numspc @hexadecimal \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } + @decimal \# / { ifExtension MagicHashBit } { tok_primint positive 0 1 decimal } + @binarylit \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 3 binary } + @octallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 octal } + @hexadecimallit \# / { ifExtension MagicHashBit } { tok_primint positive 2 3 hexadecimal } + @negative @decimal \# / { negHashLitPred MagicHashBit } { tok_primint negative 1 2 decimal } + @negative @binarylit \# / { negHashLitPred MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 4 binary } + @negative @octallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 octal } + @negative @hexadecimallit \# / { negHashLitPred MagicHashBit } { tok_primint negative 3 4 hexadecimal } + + @decimal \# \# / { ifExtension MagicHashBit } { tok_primword 0 2 decimal } + @binarylit \# \# / { ifExtension MagicHashBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 4 binary } + @octallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 octal } + @hexadecimallit \# \# / { ifExtension MagicHashBit } { tok_primword 2 4 hexadecimal } -- Unboxed floats and doubles (:: Float#, :: Double#) -- prim_{float,double} work with signed literals @floating_point \# / { ifExtension MagicHashBit } { tok_frac 1 tok_primfloat } @floating_point \# \# / { ifExtension MagicHashBit } { tok_frac 2 tok_primdouble } - @negative @floating_point \# / { negHashLitPred } { tok_frac 1 tok_primfloat } - @negative @floating_point \# \# / { negHashLitPred } { tok_frac 2 tok_primdouble } + @negative @floating_point \# / { negHashLitPred MagicHashBit } { tok_frac 1 tok_primfloat } + @negative @floating_point \# \# / { negHashLitPred MagicHashBit } { tok_frac 2 tok_primdouble } + + @decimal \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 0 decimal } + @binarylit \#"Int8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 positive 2 binary } + @octallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 octal } + @hexadecimallit \#"Int8" / { ifExtension ExtendedLiteralsBit } { tok_primint8 positive 2 hexadecimal } + @negative @decimal \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 1 decimal } + @negative @binarylit \#"Int8" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint8 negative 3 binary } + @negative @octallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 octal } + @negative @hexadecimallit \#"Int8" / { negHashLitPred ExtendedLiteralsBit } { tok_primint8 negative 3 hexadecimal } + + @decimal \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 0 decimal } + @binarylit \#"Int16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 positive 2 binary } + @octallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 octal } + @hexadecimallit \#"Int16" / { ifExtension ExtendedLiteralsBit } { tok_primint16 positive 2 hexadecimal } + @negative @decimal \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 1 decimal } + @negative @binarylit \#"Int16" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint16 negative 3 binary } + @negative @octallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 octal } + @negative @hexadecimallit \#"Int16" / { negHashLitPred ExtendedLiteralsBit} { tok_primint16 negative 3 hexadecimal } + + @decimal \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 0 decimal } + @binarylit \#"Int32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 positive 2 binary } + @octallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 octal } + @hexadecimallit \#"Int32" / { ifExtension ExtendedLiteralsBit } { tok_primint32 positive 2 hexadecimal } + @negative @decimal \#"Int32" / { negHashLitPred ExtendedLiteralsBit } { tok_primint32 negative 1 decimal } + @negative @binarylit \#"Int32" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint32 negative 3 binary } + @negative @octallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 octal } + @negative @hexadecimallit \#"Int32" / { negHashLitPred ExtendedLiteralsBit} { tok_primint32 negative 3 hexadecimal } + + @decimal \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 0 decimal } + @binarylit \#"Int64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 positive 2 binary } + @octallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 octal } + @hexadecimallit \#"Int64" / { ifExtension ExtendedLiteralsBit } { tok_primint64 positive 2 hexadecimal } + @negative @decimal \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 1 decimal } + @negative @binarylit \#"Int64" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint64 negative 3 binary } + @negative @octallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 octal } + @negative @hexadecimallit \#"Int64" / { negHashLitPred ExtendedLiteralsBit } { tok_primint64 negative 3 hexadecimal } + + @decimal \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 0 4 decimal } + @binarylit \#"Int" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint positive 2 6 binary } + @octallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 octal } + @hexadecimallit \#"Int" / { ifExtension ExtendedLiteralsBit } { tok_primint positive 2 6 hexadecimal } + @negative @decimal \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 1 5 decimal } + @negative @binarylit \#"Int" / { negHashLitPred ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primint negative 3 7 binary } + @negative @octallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 octal } + @negative @hexadecimallit \#"Int" / { negHashLitPred ExtendedLiteralsBit } { tok_primint negative 3 7 hexadecimal } + + @decimal \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 0 decimal } + @binarylit \#"Word8" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword8 2 binary } + @octallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 octal } + @hexadecimallit \#"Word8" / { ifExtension ExtendedLiteralsBit } { tok_primword8 2 hexadecimal } + + @decimal \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 0 decimal } + @binarylit \#"Word16" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword16 2 binary } + @octallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 octal } + @hexadecimallit \#"Word16" / { ifExtension ExtendedLiteralsBit } { tok_primword16 2 hexadecimal } + + @decimal \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 0 decimal } + @binarylit \#"Word32" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword32 2 binary } + @octallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 octal } + @hexadecimallit \#"Word32" / { ifExtension ExtendedLiteralsBit } { tok_primword32 2 hexadecimal } + + @decimal \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 0 decimal } + @binarylit \#"Word64" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword64 2 binary } + @octallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 octal } + @hexadecimallit \#"Word64" / { ifExtension ExtendedLiteralsBit } { tok_primword64 2 hexadecimal } + + @decimal \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 0 5 decimal } + @binarylit \#"Word" / { ifExtension ExtendedLiteralsBit `alexAndPred` + ifExtension BinaryLiteralsBit } { tok_primword 2 7 binary } + @octallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 octal } + @hexadecimallit \#"Word" / { ifExtension ExtendedLiteralsBit } { tok_primword 2 7 hexadecimal } + } -- Strings and chars are lexed by hand-written code. The reason is @@ -866,6 +955,14 @@ data Token | ITprimstring SourceText ByteString -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimint SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimword SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimint64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword8 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword16 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword32 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" + | ITprimword64 SourceText Integer -- Note [Literal source text] in "GHC.Types.SourceText" | ITprimfloat FractionalLit | ITprimdouble FractionalLit @@ -1281,10 +1378,10 @@ negLitPred = alexNotPred precededByClosingToken -- Check if we should parse an unboxed negative literal (e.g. -123#) as a single token. -negHashLitPred :: AlexAccPred ExtsBitmap -negHashLitPred = prefix_minus `alexAndPred` magic_hash +negHashLitPred :: ExtBits -> AlexAccPred ExtsBitmap +negHashLitPred ext = prefix_minus `alexAndPred` magic_hash where - magic_hash = ifExtension MagicHashBit + magic_hash = ifExtension ext -- Either MagicHashBit or ExtendedLiteralsBit prefix_minus = -- Note [prefix_minus in negLitPred and negHashLitPred] alexNotPred precededByClosingToken @@ -1829,6 +1926,40 @@ binary = (2,octDecDigit) octal = (8,octDecDigit) hexadecimal = (16,hexDigit) +-- | Helper for defining @IntX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @123#Int8@). +tok_primintX :: (SourceText -> Integer -> Token) + -> Int + -> (Integer -> Integer) + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primintX itint addlen transint transbuf = + tok_integral itint transint transbuf (transbuf+addlen) + +tok_primint8, tok_primint16, tok_primint32, tok_primint64 + :: (Integer -> Integer) + -> Int -> (Integer, (Char->Int)) -> Action +tok_primint8 = tok_primintX ITprimint8 5 +tok_primint16 = tok_primintX ITprimint16 6 +tok_primint32 = tok_primintX ITprimint32 6 +tok_primint64 = tok_primintX ITprimint64 6 + +-- | Helper for defining @WordX@ primitive literal parsers (specifically for +-- the ExtendedLiterals extension, such as @234#Word8@). +tok_primwordX :: (SourceText -> Integer -> Token) + -> Int + -> Int + -> (Integer, (Char->Int)) -> Action +tok_primwordX itint addlen transbuf = + tok_integral itint positive transbuf (transbuf+addlen) + +tok_primword8, tok_primword16, tok_primword32, tok_primword64 + :: Int -> (Integer, (Char->Int)) -> Action +tok_primword8 = tok_primwordX ITprimword8 6 +tok_primword16 = tok_primwordX ITprimword16 7 +tok_primword32 = tok_primwordX ITprimword32 7 +tok_primword64 = tok_primwordX ITprimword64 7 + -- readSignificandExponentPair can understand negative rationals, exponents, everything. tok_frac :: Int -> (String -> Token) -> Action tok_frac drop f span buf len _buf2 = do @@ -2903,6 +3034,7 @@ data ExtBits | NoLexicalNegationBit -- See Note [Why not LexicalNegationBit] | OverloadedRecordDotBit | OverloadedRecordUpdateBit + | ExtendedLiteralsBit -- Flags that are updated once parsing starts | InRulePragBit @@ -2982,6 +3114,7 @@ mkParserOpts extensionFlags diag_opts supported .|. NoLexicalNegationBit `xoptNotBit` LangExt.LexicalNegation -- See Note [Why not LexicalNegationBit] .|. OverloadedRecordDotBit `xoptBit` LangExt.OverloadedRecordDot .|. OverloadedRecordUpdateBit `xoptBit` LangExt.OverloadedRecordUpdate -- Enable testing via 'getBit OverloadedRecordUpdateBit' in the parser (RecordDotSyntax parsing uses that information). + .|. ExtendedLiteralsBit `xoptBit` LangExt.ExtendedLiterals optBits = HaddockBit `setBitIf` isHaddock .|. RawTokenStreamBit `setBitIf` rawTokStream ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -568,7 +568,13 @@ type family XHsStringPrim x type family XHsInt x type family XHsIntPrim x type family XHsWordPrim x +type family XHsInt8Prim x +type family XHsInt16Prim x +type family XHsInt32Prim x type family XHsInt64Prim x +type family XHsWord8Prim x +type family XHsWord16Prim x +type family XHsWord32Prim x type family XHsWord64Prim x type family XHsInteger x type family XHsRat x ===================================== compiler/Language/Haskell/Syntax/Lit.hs ===================================== @@ -63,8 +63,20 @@ data HsLit x -- ^ literal @Int#@ | HsWordPrim (XHsWordPrim x) {- SourceText -} Integer -- ^ literal @Word#@ + | HsInt8Prim (XHsInt8Prim x) {- SourceText -} Integer + -- ^ literal @Int8#@ + | HsInt16Prim (XHsInt16Prim x) {- SourceText -} Integer + -- ^ literal @Int16#@ + | HsInt32Prim (XHsInt32Prim x) {- SourceText -} Integer + -- ^ literal @Int32#@ | HsInt64Prim (XHsInt64Prim x) {- SourceText -} Integer -- ^ literal @Int64#@ + | HsWord8Prim (XHsWord8Prim x) {- SourceText -} Integer + -- ^ literal @Word8#@ + | HsWord16Prim (XHsWord16Prim x) {- SourceText -} Integer + -- ^ literal @Word16#@ + | HsWord32Prim (XHsWord32Prim x) {- SourceText -} Integer + -- ^ literal @Word32#@ | HsWord64Prim (XHsWord64Prim x) {- SourceText -} Integer -- ^ literal @Word64#@ | HsInteger (XHsInteger x) {- SourceText -} Integer Type @@ -149,4 +161,3 @@ instance Ord OverLitVal where compare (HsIsString _ s1) (HsIsString _ s2) = s1 `lexicalCompareFS` s2 compare (HsIsString _ _) (HsIntegral _) = GT compare (HsIsString _ _) (HsFractional _) = GT - ===================================== docs/users_guide/9.8.1-notes.rst ===================================== @@ -6,6 +6,10 @@ Version 9.8.1 Language ~~~~~~~~ +- There is a new extension :extension:`ExtendedLiterals`, which enables + sized primitive literals, e.g. ``123#Int8`` is a literal of type ``Int8#``. + See the GHC proposal `#451 `_. + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/extended_literals.rst ===================================== @@ -0,0 +1,47 @@ +.. _extended-literals: + +Sized primitive literal syntax +------------------------------ + +.. extension:: ExtendedLiterals + :shortdesc: Enable numeric literal postfix syntax for unboxed integers. + + :since: 9.8.1 + + Allows defining unboxed numeric primitive values through ``#Type`` suffixes + on numeric literals e.g. ``0xFF#Word8 :: Word8#``. + +The :extension:`MagicHash` extension enables some new literals, including ``3# +:: Int#``, ``3## :: Word#``. This does not extend to all unboxed values. For +example, there is no literal syntax for ``Word8#``: you must write something +such as ``wordToWord8 (3## :: Word#) :: Word8#``. + +:extension:`ExtendedLiterals` enables further syntax for defining primitive +numeric literals. Suffix any Haskell integer lexeme with a hash sign ``#`` +followed by a primitive numeric type (without its hash suffix) to obtain a value +of that type. For example, ``0xFF#Word8 :: Word8#``. There must be no spaces +between the parts of the literal. + +The primitive numeric types allowed are: + +- ``Int8#`` +- ``Int16#`` +- ``Int32#`` +- ``Int64#`` +- ``Int#`` +- ``Word8#`` +- ``Word16#`` +- ``Word32#`` +- ``Word64#`` +- ``Word#`` + +All types permit any nonnegative Haskell integer lexeme, e.g. ``70``, ``0x2A``, +``0o1276``, ``0b1010`` (with :extension:`BinaryLiterals`). The signed ``Int`` +types also permit negative integer lexemes. Defining a literal with a value that +can't fit in its requested type will emit an overflow warning by default, the +same as boxed numeric literals. + +As with :extension:`MagicHash`, this extension does not bring anything into +scope, nor change any semantics. The syntax only applies to numeric literals. +You may want to import ``GHC.Exts`` (see :ref:`primitives`) to refer to the +types of the literals you define. ===================================== docs/users_guide/exts/literals.rst ===================================== @@ -10,6 +10,7 @@ Literals binary_literals hex_float_literals num_decimals + extended_literals numeric_underscores overloaded_strings overloaded_labels ===================================== docs/users_guide/exts/primitives.rst ===================================== @@ -19,6 +19,9 @@ your program, you must first import ``GHC.Exts`` to bring them into scope. Many of them have names ending in ``#``, and to mention such names you need the :extension:`MagicHash` extension. +To enable defining literals for other primitive data types, see the +:extension:`ExtendedLiterals` extension. + The primops make extensive use of `unboxed types <#glasgow-unboxed>`__ and `unboxed tuples <#unboxed-tuples>`__, which we briefly summarise here. ===================================== docs/users_guide/exts/stolen_syntax.rst ===================================== @@ -80,6 +80,9 @@ The following syntax is stolen: ⟨varid⟩, ``#``\ ⟨char⟩, ``#``, ⟨string⟩, ``#``, ⟨integer⟩, ``#``, ⟨float⟩, ``#``, ⟨float⟩, ``##`` Stolen by: :extension:`MagicHash` +⟨integer⟩, ``#(Int|Word)(8|16|32|64)?`` + Stolen by: :extension:`ExtendedLiterals` + ``(#``, ``#)`` Stolen by: :extension:`UnboxedTuples` ===================================== libraries/ghc-boot-th/GHC/LanguageExtensions/Type.hs ===================================== @@ -152,6 +152,7 @@ data Extension | OverloadedRecordDot | OverloadedRecordUpdate | TypeAbstractions + | ExtendedLiterals deriving (Eq, Enum, Show, Generic, Bounded) -- 'Ord' and 'Bounded' are provided for GHC API users (see discussions -- in https://gitlab.haskell.org/ghc/ghc/merge_requests/2707 and ===================================== testsuite/tests/driver/T4437.hs ===================================== @@ -37,7 +37,8 @@ check title expected got -- See Note [Adding a language extension] in compiler/GHC/Driver/Session.hs. expectedGhcOnlyExtensions :: [String] expectedGhcOnlyExtensions = - [ "TypeAbstractions" + [ "TypeAbstractions", + "ExtendedLiterals" ] expectedCabalOnlyExtensions :: [String] ===================================== testsuite/tests/extendedliterals/all.T ===================================== @@ -0,0 +1,3 @@ +test('extendedliterals01', normal, compile, ['']) +test('extendedliterals02', normal, compile, ['']) +test('extendedliterals03', [extra_ways(['ghci']), js_skip], compile_and_run, ['']) ===================================== testsuite/tests/extendedliterals/extendedliterals01.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE UnboxedSums, UnboxedTuples #-} + +-- needed on 32bit +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +import GHC.Exts +import GHC.Word +import GHC.Int + +-- Precise 'Int8#'/'Int8' range tests +exI8g1, exI8g2, exI8g3 :: Int8 +exI8g1 = I8# 0x00#Int8 +exI8g2 = I8# 0x7F#Int8 +exI8g3 = I8# -0x80#Int8 + +-- Showcase various syntax for equivalent 'Int' terms +exIg1, exIg2, exIg3 :: Int +exIg1 = 0x7FFFFFFFFFFFFFFF +exIg2 = I# 0x7FFFFFFFFFFFFFFF# +exIg3 = I# 0x7FFFFFFFFFFFFFFF#Int + +-- Motivating example: unboxed 'Word8#' parsing +data CEnum = Cons00 | Cons01 | ConsFF deriving Show +parseCEnum :: Word8# -> (# (##) | CEnum #) +parseCEnum = \case 0x00#Word8 -> (# | Cons00 #) + 0x01#Word8 -> (# | Cons01 #) + 0xFF#Word8 -> (# | ConsFF #) + _ -> (# (##) | #) + +w8ToBool# :: Word8# -> Int# +w8ToBool# = \case 0#Word8 -> 0# + _ -> 1# + +i8IsPole# :: Int8# -> Int# +i8IsPole# = \case 0x7F#Int8 -> 1# + -0x80#Int8 -> 1# + _ -> 0# ===================================== testsuite/tests/extendedliterals/extendedliterals02.hs ===================================== @@ -0,0 +1,15 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +{-# OPTIONS_GHC -fno-warn-overflowed-literals #-} + +module Ex where + +--import GHC.Exts +import GHC.Int + +-- Overflowed 'Int8#' literals +exI8b1, exI8b2, exI8b3, exI8b4, exI8b5 :: Int8 +exI8b1 = I8# 0x80#Int8 +exI8b2 = I8# -0x81#Int8 +exI8b3 = I8# 0xFF#Int8 +exI8b4 = I8# -0xFF#Int8 +exI8b5 = I8# 0xFFFFFFFFFFFFFFFF#Int8 ===================================== testsuite/tests/extendedliterals/extendedliterals03.hs ===================================== @@ -0,0 +1,260 @@ +{-# LANGUAGE MagicHash, ExtendedLiterals #-} +import GHC.Word +import GHC.Int +import GHC.Exts + +main = do + print (W8# (fibw8 6#Word8), + W16# (fibw16 6#Word16), + W32# (fibw32 6#Word32), + W64# (fibw64 6#Word64)) + print (I8# (fibi8 6#Int8), + I16# (fibi16 6#Int16), + I32# (fibi32 6#Int32), + I64# (fibi64 6#Int64)) + + print (W64# 0xFFFFFFFFFFFFFFFF#Word64) + print (I64# 0x7FFFFFFFFFFFFFFF#Int64) + print (I64# -0x8000000000000000#Int64) + print (W64# (x () `timesWord64#` y ())) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> False + 276447233#Word64 -> False + 276447234#Word64 -> False + 276047234#Word64 -> False + 5000000004#Word64 -> False + 100000000000000#Word64 -> True + _ -> False) + print (case x () `timesWord64#` y () of + 276447232#Word64 -> True + _ -> False) + + print [ W8# (branchi8 0#Int8) + , W8# (branchi8 1#Int8) + , W8# (branchi8 -1#Int8) + , W8# (branchi8 126#Int8) + , W8# (branchi8 127#Int8) + , W8# (branchi8 -127#Int8) + , W8# (branchi8 -128#Int8) + , W8# (branchi8 2#Int8) + ] + + print [ W16# (branchi16 0#Int16) + , W16# (branchi16 1#Int16) + , W16# (branchi16 (-1#Int16)) + , W16# (branchi16 32767#Int16) + , W16# (branchi16 32766#Int16) + , W16# (branchi16 (-32768#Int16)) + , W16# (branchi16 (-32767#Int16)) + , W16# (branchi16 2#Int16) + ] + + print [ W32# (branchi32 0#Int32) + , W32# (branchi32 1#Int32) + , W32# (branchi32 (-1#Int32)) + , W32# (branchi32 2147483646#Int32) + , W32# (branchi32 2147483647#Int32) + , W32# (branchi32 (-2147483648#Int32)) + , W32# (branchi32 (-2147483647#Int32)) + , W32# (branchi32 2#Int32) + ] + + print [ W64# (branchi64 0#Int64) + , W64# (branchi64 1#Int64) + , W64# (branchi64 (-1#Int64)) + , W64# (branchi64 2147483647#Int64) + , W64# (branchi64 2147483648#Int64) + , W64# (branchi64 4294967297#Int64) + , W64# (branchi64 (-2147483648#Int64)) + , W64# (branchi64 (-2147483649#Int64)) + , W64# (branchi64 (-4294967295#Int64)) + , W64# (branchi64 9223372036854775807#Int64) + , W64# (branchi64 9223372036854775806#Int64) + , W64# (branchi64 (-9223372036854775808#Int64)) + , W64# (branchi64 (-9223372036854775807#Int64)) + , W64# (branchi64 2#Int64) + ] + + print [ I8# (branchw8 0#Word8) + , I8# (branchw8 1#Word8) + , I8# (branchw8 254#Word8) + , I8# (branchw8 255#Word8) + , I8# (branchw8 2#Word8) + ] + + print [ I16# (branchw16 0#Word16) + , I16# (branchw16 1#Word16) + , I16# (branchw16 255#Word16) + , I16# (branchw16 256#Word16) + , I16# (branchw16 65534#Word16) + , I16# (branchw16 65535#Word16) + , I16# (branchw16 2#Word16) + ] + + print [ I32# (branchw32 0#Word32) + , I32# (branchw32 1#Word32) + , I32# (branchw32 65534#Word32) + , I32# (branchw32 65535#Word32) + , I32# (branchw32 65536#Word32) + , I32# (branchw32 4294967295#Word32) + , I32# (branchw32 4294967294#Word32) + , I32# (branchw32 4294967293#Word32) + , I32# (branchw32 2#Word32) + ] + + print [ I64# (branchw64 0#Word64) + , I64# (branchw64 1#Word64) + , I64# (branchw64 65536#Word64) + , I64# (branchw64 4294967295#Word64) + , I64# (branchw64 4294967296#Word64) + , I64# (branchw64 4294967297#Word64) + , I64# (branchw64 18446744073709551615#Word64) + , I64# (branchw64 18446744073709551614#Word64) + , I64# (branchw64 18446744073709551613#Word64) + , I64# (branchw64 2#Word64) + ] + +fibw8 :: Word8# -> Word8# +fibw8 0#Word8 = 0#Word8 +fibw8 1#Word8 = 1#Word8 +fibw8 n = fibw8 (n `subWord8#` 1#Word8) `plusWord8#` fibw8 (n `subWord8#` 2#Word8) + +fibw16 :: Word16# -> Word16# +fibw16 0#Word16 = 0#Word16 +fibw16 1#Word16 = 1#Word16 +fibw16 n = fibw16 (n `subWord16#` 1#Word16) `plusWord16#` fibw16 (n `subWord16#` 2#Word16) + +fibw32 :: Word32# -> Word32# +fibw32 0#Word32 = 0#Word32 +fibw32 1#Word32 = 1#Word32 +fibw32 n = fibw32 (n `subWord32#` 1#Word32) `plusWord32#` fibw32 (n `subWord32#` 2#Word32) + +fibw64 :: Word64# -> Word64# +fibw64 0#Word64 = 0#Word64 +fibw64 1#Word64 = 1#Word64 +fibw64 n = fibw64 (n `subWord64#` 1#Word64) `plusWord64#` fibw64 (n `subWord64#` 2#Word64) + +-- + +fibi8 :: Int8# -> Int8# +fibi8 0#Int8 = 0#Int8 +fibi8 1#Int8 = 1#Int8 +fibi8 n = fibi8 (n `subInt8#` 1#Int8) `plusInt8#` fibi8 (n `subInt8#` 2#Int8) + +fibi16 :: Int16# -> Int16# +fibi16 0#Int16 = 0#Int16 +fibi16 1#Int16 = 1#Int16 +fibi16 n = fibi16 (n `subInt16#` 1#Int16) `plusInt16#` fibi16 (n `subInt16#` 2#Int16) + +fibi32 :: Int32# -> Int32# +fibi32 0#Int32 = 0#Int32 +fibi32 1#Int32 = 1#Int32 +fibi32 n = fibi32 (n `subInt32#` 1#Int32) `plusInt32#` fibi32 (n `subInt32#` 2#Int32) + +fibi64 :: Int64# -> Int64# +fibi64 0#Int64 = 0#Int64 +fibi64 1#Int64 = 1#Int64 +fibi64 n = fibi64 (n `subInt64#` 1#Int64) `plusInt64#` fibi64 (n `subInt64#` 2#Int64) + +-- + +branchi8 :: Int8# -> Word8# +branchi8 0#Int8 = 1#Word8 +branchi8 1#Int8 = 2#Word8 +branchi8 (-1#Int8) = 3#Word8 +branchi8 126#Int8 = 4#Word8 +branchi8 127#Int8 = 5#Word8 +branchi8 (-127#Int8) = 6#Word8 +branchi8 (-128#Int8) = 7#Word8 +branchi8 _ = 0#Word8 +{-# NOINLINE branchi8 #-} + +branchi16 :: Int16# -> Word16# +branchi16 0#Int16 = 1#Word16 +branchi16 1#Int16 = 2#Word16 +branchi16 (-1#Int16) = 3#Word16 +branchi16 32767#Int16 = 255#Word16 +branchi16 32766#Int16 = 256#Word16 +branchi16 (-32768#Int16) = 65534#Word16 +branchi16 (-32767#Int16) = 65535#Word16 +branchi16 _ = 0#Word16 +{-# NOINLINE branchi16 #-} + +branchi32 :: Int32# -> Word32# +branchi32 0#Int32 = 1#Word32 +branchi32 1#Int32 = 2#Word32 +branchi32 (-1#Int32) = 3#Word32 +branchi32 2147483646#Int32 = 65535#Word32 +branchi32 2147483647#Int32 = 65536#Word32 +branchi32 (-2147483648#Int32) = 4294967294#Word32 +branchi32 (-2147483647#Int32) = 4294967295#Word32 +branchi32 _ = 0#Word32 +{-# NOINLINE branchi32 #-} + +branchi64 :: Int64# -> Word64# +branchi64 0#Int64 = 18446744073709551615#Word64 +branchi64 1#Int64 = 2147483648#Word64 +branchi64 (-1#Int64) = 4294967296#Word64 +branchi64 2147483647#Int64 = 4294967297#Word64 +branchi64 2147483648#Int64 = 9#Word64 +branchi64 4294967297#Int64 = 1#Word64 +branchi64 (-2147483648#Int64) = 18446744073709551614#Word64 +branchi64 (-2147483649#Int64) = 3#Word64 +branchi64 (-4294967295#Int64) = 4#Word64 +branchi64 9223372036854775807#Int64 = 5#Word64 +branchi64 9223372036854775806#Int64 = 6#Word64 +branchi64 (-9223372036854775808#Int64) = 7#Word64 +branchi64 (-9223372036854775807#Int64) = 8#Word64 +branchi64 _ = 0#Word64 +{-# NOINLINE branchi64 #-} + +branchw8 :: Word8# -> Int8# +branchw8 0#Word8 = 1#Int8 +branchw8 1#Word8 = (-1#Int8) +branchw8 254#Word8 = 2#Int8 +branchw8 255#Word8 = (-2#Int8) +branchw8 _ = 0#Int8 +{-# NOINLINE branchw8 #-} + +branchw16 :: Word16# -> Int16# +branchw16 0#Word16 = 256#Int16 +branchw16 1#Word16 = (-256#Int16) +branchw16 255#Word16 = 32767#Int16 +branchw16 256#Word16 = (-32768#Int16) +branchw16 65534#Word16 = (-1#Int16) +branchw16 65535#Word16 = 1#Int16 +branchw16 _ = 0#Int16 +{-# NOINLINE branchw16 #-} + +branchw32 :: Word32# -> Int32# +branchw32 0#Word32 = 2147483647#Int32 +branchw32 1#Word32 = (-2147483648#Int32) +branchw32 65534#Word32 = 65535#Int32 +branchw32 65535#Word32 = 65536#Int32 +branchw32 65536#Word32 = (-1#Int32) +branchw32 4294967295#Word32 = (-65536#Int32) +branchw32 4294967294#Word32 = (-65537#Int32) +branchw32 4294967293#Word32 = 1#Int32 +branchw32 _ = 0#Int32 +{-# NOINLINE branchw32 #-} + +branchw64 :: Word64# -> Int64# +branchw64 0#Word64 = 9223372036854775807#Int64 +branchw64 1#Word64 = 2147483648#Int64 +branchw64 65536#Word64 = 4294967296#Int64 +branchw64 4294967295#Word64 = 4294967297#Int64 +branchw64 4294967296#Word64 = (-1#Int64) +branchw64 4294967297#Word64 = 9223372036854775806#Int64 +branchw64 18446744073709551615#Word64 = (-9223372036854775808#Int64) +branchw64 18446744073709551614#Word64 = (-9223372036854775807#Int64) +branchw64 18446744073709551613#Word64 = 1#Int64 +branchw64 _ = 0#Int64 +{-# NOINLINE branchw64 #-} + +x :: () -> Word64# +x () = 2000000000#Word64 +{-# NOINLINE x #-} + +y :: () -> Word64# +y () = 50000#Word64 +{-# NOINLINE y #-} ===================================== testsuite/tests/extendedliterals/extendedliterals03.stdout ===================================== @@ -0,0 +1,16 @@ +(8,8,8,8) +(8,8,8,8) +18446744073709551615 +9223372036854775807 +-9223372036854775808 +100000000000000 +True +False +[1,2,3,4,5,6,7,0] +[1,2,3,255,256,65534,65535,0] +[1,2,3,65535,65536,4294967294,4294967295,0] +[18446744073709551615,2147483648,4294967296,4294967297,9,1,18446744073709551614,3,4,5,6,7,8,0] +[1,-1,2,-2,0] +[256,-256,32767,-32768,-1,1,0] +[2147483647,-2147483648,65535,65536,-1,-65536,-65537,1,0] +[9223372036854775807,2147483648,4294967296,4294967297,-1,9223372036854775806,-9223372036854775808,-9223372036854775807,1,0] ===================================== testsuite/tests/ghci/should_run/SizedLiterals.hs deleted ===================================== @@ -1,117 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} - -import SizedLiteralsA -import Language.Haskell.TH - -{- - - This file is compiled with the GHC flags: - - -O -fbyte-code-and-object-code -fprefer-byte-code - - This makes sure that the Template Haskell runs in the bytecode - interpreter with optimized bytecode, allowing us to test the - sized unboxed literals. - - Running the test in GHCi directly would disable optimization. - - -} - -main :: IO () -main = do - print $(pure $ ListE [ ie (fibw8 5) - , ie (fibw16 5) - , ie (fibw32 5) - , ie (fibw64 5) - ]) - - print $(pure $ ListE [ ie (fibi8 5) - , ie (fibi16 5) - , ie (fibi32 5) - , ie (fibi64 5) - ]) - - print $(pure $ ListE [ ie (branchi8 0) - , ie (branchi8 1) - , ie (branchi8 (-1)) - , ie (branchi8 126) - , ie (branchi8 127) - , ie (branchi8 (-127)) - , ie (branchi8 (-128)) - , ie (branchi8 2) - ]) - - print $(pure $ ListE [ ie (branchi16 0) - , ie (branchi16 1) - , ie (branchi16 (-1)) - , ie (branchi16 32767) - , ie (branchi16 32766) - , ie (branchi16 (-32768)) - , ie (branchi16 (-32767)) - , ie (branchi16 2) - ]) - - print $(pure $ ListE [ ie (branchi32 0) - , ie (branchi32 1) - , ie (branchi32 (-1)) - , ie (branchi32 2147483646) - , ie (branchi32 2147483647) - , ie (branchi32 (-2147483648)) - , ie (branchi32 (-2147483647)) - , ie (branchi32 2) - ]) - - print $(pure $ ListE [ ie (branchi64 0) - , ie (branchi64 1) - , ie (branchi64 (-1)) - , ie (branchi64 2147483647) - , ie (branchi64 2147483648) - , ie (branchi64 4294967297) - , ie (branchi64 (-2147483648)) - , ie (branchi64 (-2147483649)) - , ie (branchi64 (-4294967295)) - , ie (branchi64 9223372036854775807) - , ie (branchi64 9223372036854775806) - , ie (branchi64 (-9223372036854775808)) - , ie (branchi64 (-9223372036854775807)) - , ie (branchi64 2) - ]) - - print $(pure $ ListE [ ie (branchw8 0) - , ie (branchw8 1) - , ie (branchw8 254) - , ie (branchw8 255) - , ie (branchw8 2) - ]) - - print $(pure $ ListE [ ie (branchw16 0) - , ie (branchw16 1) - , ie (branchw16 255) - , ie (branchw16 256) - , ie (branchw16 65534) - , ie (branchw16 65535) - , ie (branchw16 2) - ]) - - print $(pure $ ListE [ ie (branchw32 0) - , ie (branchw32 1) - , ie (branchw32 65534) - , ie (branchw32 65535) - , ie (branchw32 65536) - , ie (branchw32 4294967295) - , ie (branchw32 4294967294) - , ie (branchw32 4294967293) - , ie (branchw32 2) - ]) - - print $(pure $ ListE [ ie (branchw64 0) - , ie (branchw64 1) - , ie (branchw64 65536) - , ie (branchw64 4294967295) - , ie (branchw64 4294967296) - , ie (branchw64 4294967297) - , ie (branchw64 18446744073709551615) - , ie (branchw64 18446744073709551614) - , ie (branchw64 18446744073709551613) - , ie (branchw64 2) - ]) \ No newline at end of file ===================================== testsuite/tests/ghci/should_run/SizedLiteralsA.hs deleted ===================================== @@ -1,139 +0,0 @@ -module SizedLiteralsA where - -import GHC.Word -import GHC.Int -import Language.Haskell.TH.Syntax - -fibw8 :: Word8 -> Word8 -fibw8 0 = 0 -fibw8 1 = 1 -fibw8 n = fibw8 (n-1) + fibw8 (n-2) - -fibw16 :: Word16 -> Word16 -fibw16 0 = 0 -fibw16 1 = 1 -fibw16 n = fibw16 (n-1) + fibw16 (n-2) - -fibw32 :: Word32 -> Word32 -fibw32 0 = 0 -fibw32 1 = 1 -fibw32 n = fibw32 (n-1) + fibw32 (n-2) - -fibw64 :: Word64 -> Word64 -fibw64 0 = 0 -fibw64 1 = 1 -fibw64 n = fibw64 (n-1) + fibw64 (n-2) - --- - -fibi8 :: Int8 -> Int8 -fibi8 0 = 0 -fibi8 1 = 1 -fibi8 n = fibi8 (n-1) + fibi8 (n-2) - -fibi16 :: Int16 -> Int16 -fibi16 0 = 0 -fibi16 1 = 1 -fibi16 n = fibi16 (n-1) + fibi16 (n-2) - -fibi32 :: Int32 -> Int32 -fibi32 0 = 0 -fibi32 1 = 1 -fibi32 n = fibi32 (n-1) + fibi32 (n-2) - -fibi64 :: Int64 -> Int64 -fibi64 0 = 0 -fibi64 1 = 1 -fibi64 n = fibi64 (n-1) + fibi64 (n-2) - --- - -branchi8 :: Int8 -> Word8 -branchi8 0 = 1 -branchi8 1 = 2 -branchi8 (-1) = 3 -branchi8 126 = 4 -branchi8 127 = 5 -branchi8 (-127) = 6 -branchi8 (-128) = 7 -branchi8 _ = 0 - -branchi16 :: Int16 -> Word16 -branchi16 0 = 1 -branchi16 1 = 2 -branchi16 (-1) = 3 -branchi16 32767 = 255 -branchi16 32766 = 256 -branchi16 (-32768) = 65534 -branchi16 (-32767) = 65535 -branchi16 _ = 0 - -branchi32 :: Int32 -> Word32 -branchi32 0 = 1 -branchi32 1 = 2 -branchi32 (-1) = 3 -branchi32 2147483646 = 65535 -branchi32 2147483647 = 65536 -branchi32 (-2147483648) = 4294967294 -branchi32 (-2147483647) = 4294967295 -branchi32 _ = 0 - -branchi64 :: Int64 -> Word64 -branchi64 0 = 18446744073709551615 -branchi64 1 = 2147483648 -branchi64 (-1) = 4294967296 -branchi64 2147483647 = 4294967297 -branchi64 2147483648 = 9 -branchi64 4294967297 = 1 -branchi64 (-2147483648) = 18446744073709551614 -branchi64 (-2147483649) = 3 -branchi64 (-4294967295) = 4 -branchi64 9223372036854775807 = 5 -branchi64 9223372036854775806 = 6 -branchi64 (-9223372036854775808) = 7 -branchi64 (-9223372036854775807) = 8 -branchi64 _ = 0 - -branchw8 :: Word8 -> Int8 -branchw8 0 = 1 -branchw8 1 = (-1) -branchw8 254 = 2 -branchw8 255 = (-2) -branchw8 _ = 0 - -branchw16 :: Word16 -> Int16 -branchw16 0 = 256 -branchw16 1 = (-256) -branchw16 255 = 32767 -branchw16 256 = (-32768) -branchw16 65534 = (-1) -branchw16 65535 = 1 -branchw16 _ = 0 - -branchw32 :: Word32 -> Int32 -branchw32 0 = 2147483647 -branchw32 1 = (-2147483648) -branchw32 65534 = 65535 -branchw32 65535 = 65536 -branchw32 65536 = (-1) -branchw32 4294967295 = (-65536) -branchw32 4294967294 = (-65537) -branchw32 4294967293 = 1 -branchw32 _ = 0 - -branchw64 :: Word64 -> Int64 -branchw64 0 = 9223372036854775807 -branchw64 1 = 2147483648 -branchw64 65536 = 4294967296 -branchw64 4294967295 = 4294967297 -branchw64 4294967296 = (-1) -branchw64 4294967297 = 9223372036854775806 -branchw64 18446744073709551615 = (-9223372036854775808) -branchw64 18446744073709551614 = (-9223372036854775807) -branchw64 18446744073709551613 = 1 -branchw64 _ = 0 - --- - -ie :: Integral a => a -> Exp -ie x = LitE (IntegerL (toInteger x)) ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -85,7 +85,6 @@ test('T19628', [extra_files(['T19628a.hs']), only_ways(['ghci']) ], compile_and_ test('T21052', just_ghci, ghci_script, ['T21052.script']) test('T21300', just_ghci, ghci_script, ['T21300.script']) test('UnliftedDataType2', just_ghci, compile_and_run, ['']) -test('SizedLiterals', [req_interp, extra_files(["SizedLiteralsA.hs"]),extra_hc_opts("-O -fbyte-code-and-object-code -fprefer-byte-code")], compile_and_run, ['']) test('T22829', just_ghci + [extra_hc_opts("-Wmissing-import-lists -Werror")], compile_and_run, ['']) test('T23229', just_ghci + [extra_hc_opts("-this-unit-id my-package -Wno-missing-methods T23229")], ghci_script, ['T23229.script']) ===================================== testsuite/tests/printer/Ppr038.hs ===================================== @@ -21,6 +21,14 @@ blah = x wordH = 005## floatH = 3.20# doubleH = 04.16## - -- int64H = 00456L# - -- word64H = 00456L## + intNH = 1000#Int + int8H = 1008#Int8 + int16H = 1016#Int8 + int32H = 1032#Int32 + int64H = 1064#Int64 + wordNH = 2000#Word + word8H = 2008#Word8 + word16H = 2016#Word16 + word32H = 2032#Word32 + word64H = 2064#Word64 x = 1 ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4706,7 +4706,13 @@ hsLit2String lit = HsInt _ (IL src _ v) -> toSourceTextWithSuffix src v "" HsIntPrim src v -> toSourceTextWithSuffix src v "" HsWordPrim src v -> toSourceTextWithSuffix src v "" + HsInt8Prim src v -> toSourceTextWithSuffix src v "" + HsInt16Prim src v -> toSourceTextWithSuffix src v "" + HsInt32Prim src v -> toSourceTextWithSuffix src v "" HsInt64Prim src v -> toSourceTextWithSuffix src v "" + HsWord8Prim src v -> toSourceTextWithSuffix src v "" + HsWord16Prim src v -> toSourceTextWithSuffix src v "" + HsWord32Prim src v -> toSourceTextWithSuffix src v "" HsWord64Prim src v -> toSourceTextWithSuffix src v "" HsInteger src v _ -> toSourceTextWithSuffix src v "" HsRat _ fl@(FL{fl_text = src }) _ -> toSourceTextWithSuffix src fl "" ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 03ba53ca764f56a13d12607c110f923f129e809a +Subproject commit e16e20d592a6f5d9ed1af17b77fafd6495242345 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c35c9dbf66dea84136926c52709f1f83ce734bf6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c35c9dbf66dea84136926c52709f1f83ce734bf6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 16:14:19 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Fri, 21 Apr 2023 12:14:19 -0400 Subject: [Git][ghc/ghc][wip/expand-do] changes to correctly identify the `>>` function and emitting warning if a... Message-ID: <6442b65b2fc15_178e74649d05e490046d@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 9f799f1b by Apoorv Ingle at 2023-04-21T11:13:27-05:00 changes to correctly identify the `>>` function and emitting warning if a value of non-unit type is used in a do block expanded generated code - - - - - 10 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Rename/Expr.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/Gen/Match.hs - compiler/GHC/Types/Error/Codes.hs - testsuite/tests/deSugar/should_compile/T3263-2.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -2011,13 +2011,6 @@ matchDoContextErrString (MDoExpr m) = prependQualified m (text "'mdo' block") matchDoContextErrString ListComp = text "list comprehension" matchDoContextErrString MonadComp = text "monad comprehension" -instance Outputable HsDoFlavour where - ppr (DoExpr m) = text "DoExpr" <+> parens (ppr m) - ppr (MDoExpr m) = text "MDoExpr" <+> parens (ppr m) - ppr GhciStmtCtxt = text "GhciStmtCtxt" - ppr ListComp = text "ListComp" - ppr MonadComp = text "MonadComp" - pprMatchInCtxt :: (OutputableBndrId idR, Outputable body) => Match (GhcPass idR) body -> SDoc pprMatchInCtxt match = hang (text "In" <+> pprMatchContext (m_ctxt match) ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -307,6 +307,7 @@ dsExpr (HsLamCase _ lc_variant matches) dsExpr e@(HsApp _ fun arg) = do { fun' <- dsLExpr fun ; arg' <- dsLExpr arg + ; warnUnusedBindValue fun arg (exprType arg') ; return $ mkCoreAppDs (text "HsApp" <+> ppr e) fun' arg' } dsExpr e@(HsAppType {}) = dsHsWrapped e @@ -682,7 +683,7 @@ dsDo ctx stmts go _ (BodyStmt _ rhs then_expr _) stmts = do { rhs2 <- dsLExpr rhs - ; warnDiscardedDoBindings rhs (exprType rhs2) + --; warnDiscardedDoBindings rhs (exprType rhs2) ; rest <- goL stmts ; dsSyntaxExpr then_expr [rhs2, rest] } @@ -851,6 +852,29 @@ warnDiscardedDoBindings rhs rhs_ty | otherwise -- RHS does have type of form (m ty), which is weird = return () -- but at least this warning is irrelevant + +warnUnusedBindValue :: LHsExpr GhcTc -> LHsExpr GhcTc -> Type -> DsM () +warnUnusedBindValue fun arg arg_ty + | Just (SrcSpanAnn _ l, f) <- fish_var fun + , is_gen_then f + , isNoSrcSpan l + = warnDiscardedDoBindings arg arg_ty + where + -- retrieve the location info and the head of the application + fish_var :: LHsExpr GhcTc -> Maybe (SrcSpanAnnA , LIdP GhcTc) + fish_var (L l (HsVar _ id)) = return (l, id) + fish_var (L _ (HsAppType _ e _ _)) = fish_var e + fish_var (L l (XExpr (WrapExpr (HsWrap _ e)))) = do (l, e') <- fish_var (L l e) + return (l, e') + fish_var _ = Nothing + + -- is this id a compiler generated (>>) with expanded do + is_gen_then :: LIdP GhcTc -> Bool + is_gen_then (L _ f) = f `hasKey` thenMClassOpKey + +warnUnusedBindValue _ _ _ = return () + + {- ************************************************************************ * * ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -78,7 +78,7 @@ import qualified GHC.LanguageExtensions as LangExt import Language.Haskell.Syntax.Basic (FieldLabelString(..)) import Control.Monad -import Data.List (unzip4, minimumBy, (\\)) +import Data.List (unzip4, minimumBy) import Data.List.NonEmpty ( NonEmpty(..), nonEmpty ) import Control.Arrow (first) import Data.Ord ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1304,7 +1304,6 @@ instance Diagnostic TcRnMessage where TcRnUnexpectedStatementInContext ctxt (UnexpectedStatement stmt) _ -> mkSimpleDecorated $ sep [ text "Unexpected" <+> pprStmtCat stmt <+> text "statement" , text "in" <+> pprAStmtContext ctxt ] - TcRnUnUsedDoBind ty -> mkSimpleDecorated $ pprBadMonadBind ty TcRnIllegalTupleSection -> mkSimpleDecorated $ text "Illegal tuple section" TcRnIllegalImplicitParameterBindings eBinds -> mkSimpleDecorated $ @@ -2136,8 +2135,6 @@ instance Diagnostic TcRnMessage where -> ErrorWithoutFlag TcRnLastStmtNotExpr{} -> ErrorWithoutFlag - TcRnUnUsedDoBind{} - -> WarningWithFlag Opt_WarnUnusedDoBind TcRnUnexpectedStatementInContext{} -> ErrorWithoutFlag TcRnSectionWithoutParentheses{} @@ -2721,8 +2718,6 @@ instance Diagnostic TcRnMessage where -> noHints TcRnLastStmtNotExpr{} -> noHints - TcRnUnUsedDoBind {} - -> noHints TcRnUnexpectedStatementInContext _ _ mExt | Nothing <- mExt -> noHints | Just ext <- mExt -> [suggestExtension ext] @@ -5039,8 +5034,47 @@ pprPatSynInvalidRhsReason = \case text "Pattern" <+> quotes (ppr p) <+> text "is not invertible" PatSynUnboundVar var -> quotes (ppr var) <+> text "is not bound by the LHS of the pattern synonym" - -pprBadMonadBind :: Type -> SDoc -pprBadMonadBind elt_ty - = hang (text "A do-notation statement discarded a result of type") - 2 (quotes (ppr elt_ty)) +pprBadFieldAnnotationReason :: BadFieldAnnotationReason -> SDoc +pprBadFieldAnnotationReason = \case + LazyFieldsDisabled -> + text "Lazy field annotations (~) are disabled" + UnpackWithoutStrictness -> + text "UNPACK pragma lacks '!'" + BackpackUnpackAbstractType -> + text "Ignoring unusable UNPACK pragma" + +pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc +pprSuperclassCycleDetail = \case + SCD_HeadTyVar pred -> + hang (text "one of whose superclass constraints is headed by a type variable:") + 2 (quotes (ppr pred)) + SCD_HeadTyFam pred -> + hang (text "one of whose superclass constraints is headed by a type family:") + 2 (quotes (ppr pred)) + SCD_Superclass cls -> + text "one of whose superclasses is" <+> quotes (ppr cls) + +pprRoleValidationFailedReason :: Role -> RoleValidationFailedReason -> SDoc +pprRoleValidationFailedReason role = \case + TyVarRoleMismatch tv role' -> + text "type variable" <+> quotes (ppr tv) <+> + text "cannot have role" <+> ppr role <+> + text "because it was assigned role" <+> ppr role' + TyVarMissingInEnv tv -> + text "type variable" <+> quotes (ppr tv) <+> text "missing in environment" + BadCoercionRole co -> + text "coercion" <+> ppr co <+> text "has bad role" <+> ppr role + +pprDisabledClassExtension :: Class -> DisabledClassExtension -> SDoc +pprDisabledClassExtension cls = \case + MultiParamDisabled n -> + text howMany <+> text "parameters for class" <+> quotes (ppr cls) + where + howMany | n == 0 = "No" + | otherwise = "Too many" + FunDepsDisabled -> + text "Fundeps in class" <+> quotes (ppr cls) + ConstrainedClassMethodsDisabled sel_id pred -> + vcat [ hang (text "Constraint" <+> quotes (ppr pred) + <+> text "in the type of" <+> quotes (ppr sel_id)) + 2 (text "constrains only the class type variables")] ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2903,17 +2903,6 @@ data TcRnMessage where -> Maybe LangExt.Extension -> TcRnMessage - {-| A do statment that discards a non-unit value - Example: do return 10 -- value discarded - return 10 - - Test cases: testsuite/tests/deSugar/should_compile/T3263-2 - - -} - TcRnUnUsedDoBind - :: Type - -> TcRnMessage - {-| TcRnIllegalTupleSection is an error triggered by usage of a tuple section without enabling the TupleSections extension. ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -39,7 +39,6 @@ import GHC.Core.TyCo.Subst (substTyWithInScope) import GHC.Core.TyCo.FVs( shallowTyCoVarsOfType ) import GHC.Core.Type import GHC.Core.Coercion -import GHC.Core.FamInstEnv import GHC.Tc.Types.Evidence import GHC.Types.Var.Set import GHC.Builtin.PrimOps( tagToEnumKey ) @@ -328,7 +327,7 @@ tcApp rn_expr exp_res_ty vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args - + -- Instantiate ; do_ql <- wantQuickLook rn_fun ; (delta, inst_args, app_res_rho) <- tcInstFun do_ql True fun fun_sigma rn_args @@ -397,44 +396,9 @@ tcApp rn_expr exp_res_ty , text "tc_args:" <+> ppr tc_args , text "tc_expr:" <+> ppr tc_expr ]) } - -- Emit a warning if the bind value in a do statement is discarded - ; warnUnusedBindValue rn_fun tc_args - -- Wrap the result ; return (mkHsWrap res_wrap tc_expr) } --- emit a warning if the argument expression is not of type unit -warnUnusedBindValue :: HsExpr GhcRn -> [HsExprArg 'TcpTc] -> TcM () -warnUnusedBindValue fun args - | is_gen_then fun - , (_ : _ : arg : _) <- args - = do { -- arg <- zonkArg arg - fam_inst_envs <- tcGetFamInstEnvs - ; let app_ty' = (scaledThing . eva_arg_ty) arg -- usually /m a/ - ; app_ty <- zonkTcType app_ty' - ; let (_, (ret_ty':_)) = tcSplitAppTys app_ty -- /a/ - ; ret_ty <- zonkTcType ret_ty' -- ANI this maynot work as ret_ty' is an unsolved type variable and it gives rise to spurious unused bind warnings - ; let norm_elt_ty = topNormaliseType fam_inst_envs ret_ty - -- normalize /a/ as it might be a type family - not_unit_ty = (not . isUnitTy) norm_elt_ty - -- is /a/ not /()/? - ; traceTc "warnUnusedBindValue" (vcat [ text "arg" <+> ppr arg - , text "arg_ty" <+> ppr (eva_arg_ty arg) - , text "app_ty" <+> ppr app_ty - , text "split" <+> ppr (tcSplitAppTys app_ty) - , text "norm_elt_ty" <+> ppr norm_elt_ty - ]) - ; diagnosticTc not_unit_ty (TcRnUnUsedDoBind norm_elt_ty) - } - where - -- is this function a generated (>>) - is_gen_then :: HsExpr GhcRn -> Bool - is_gen_then (HsVar _ (L (SrcSpanAnn _ l) fun)) = fun `hasKey` thenMClassOpKey - && isNoSrcSpan l - is_gen_then _ = False - -warnUnusedBindValue _ _ = return () - -------------------- wantQuickLook :: HsExpr GhcRn -> TcM Bool wantQuickLook (HsVar _ (L _ f)) ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -54,7 +54,6 @@ import GHC.Tc.Gen.Head import GHC.Tc.Gen.Bind ( tcLocalBinds ) import GHC.Tc.Instance.Family ( tcGetFamInstEnvs ) import GHC.Core.FamInstEnv ( FamInstEnvs ) -import GHC.Rename.Expr ( mkExpandedExpr ) import GHC.Rename.Env ( addUsedGRE, getUpdFieldLbls ) import GHC.Tc.Utils.Env import GHC.Tc.Gen.Arrow ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -1238,7 +1238,7 @@ expand_do_stmts do_or_lc ((L _ (BindStmt xbsrn pat e)): lstmts) ] | otherwise = -- just use the Prelude.>>= TODO: Necessary? --- stmts ~~> stmts' +-- stmts ~~> stmts' -- ------------------------------------------------------- -- pat <- e ; stmts ~~> (Prelude.>>=) e (\ pat -> stmts') do traceTc "expand_do_stmts: generic binop" empty @@ -1359,7 +1359,7 @@ expand_do_stmts _ (stmt@(L _ (ParStmt {})):_) = pprPanic "expand_do_stmts: ParStmt" $ ppr stmt -expand_do_stmts do_flavor stmts = pprPanic "expand_do_stmts: impossible happened" $ (ppr do_flavor $$ ppr stmts) +expand_do_stmts _ stmts = pprPanic "expand_do_stmts: impossible happened" $ (ppr stmts) ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -430,12 +430,15 @@ type family GhcDiagnosticCode c = n | n -> c where GhcDiagnosticCode "TcRnIllegalStaticFormInSplice" = 12219 GhcDiagnosticCode "TcRnListComprehensionDuplicateBinding" = 81232 GhcDiagnosticCode "TcRnLastStmtNotExpr" = 55814 - GhcDiagnosticCode "TcRnUnUsedDoBind" = 61315 GhcDiagnosticCode "TcRnUnexpectedStatementInContext" = 42026 GhcDiagnosticCode "TcRnSectionWithoutParentheses" = 95880 GhcDiagnosticCode "TcRnIllegalImplicitParameterBindings" = 50730 GhcDiagnosticCode "TcRnIllegalTupleSection" = 59155 GhcDiagnosticCode "TcRnTermNameInType" = 37479 + GhcDiagnosticCode "TcRnUnexpectedKindVar" = 12875 + GhcDiagnosticCode "TcRnNegativeNumTypeLiteral" = 93632 + GhcDiagnosticCode "TcRnUnusedQuantifiedTypeVar" = 54180 + GhcDiagnosticCode "TcRnUntickedPromotedThing" = 49957 GhcDiagnosticCode "TcRnIllegalBuiltinSyntax" = 39716 GhcDiagnosticCode "TcRnWarnDefaulting" = 18042 ===================================== testsuite/tests/deSugar/should_compile/T3263-2.hs ===================================== @@ -14,14 +14,14 @@ t2 :: Monad m => m (m Int) t2 = return (return 10) -- No warning -t3 :: Monad m => m (m Int) -t3 = do +asdft3 :: Monad m => m (m Int) +asdft3 = do return 10 return (return 10) -- Warning -t4 :: forall m. Monad m => m Int -t4 = do +asdft4 :: forall m. Monad m => m Int +asdft4 = do return (return 10 :: m Int) return 10 @@ -38,11 +38,15 @@ t6 = mdo return (return 10 :: m Int) return 10 --- unit :: () +unit :: () unit = () --- No warning +-- -- No warning t7 :: forall m. Monad m => m Int t7 = do return unit return 10 + +-- No warning +t8 :: Monad m => m Int +t8 = return 10 >> return 10 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f799f1b2d0b141c6c3a15e0e16095ad74db6f45 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f799f1b2d0b141c6c3a15e0e16095ad74db6f45 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 17:17:13 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 13:17:13 -0400 Subject: [Git][ghc/ghc][wip/js-mkdir] JS/base: provide implementation for mkdir (issue 22374) Message-ID: <6442c5197e151_178e7465c4b2009162e3@gitlab.mail> Josh Meredith pushed to branch wip/js-mkdir at Glasgow Haskell Compiler / GHC Commits: 8b9132c3 by Josh Meredith at 2023-04-21T17:17:01+00:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 5 changed files: - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - + libraries/base/tests/IO/mkdirExists.stderr - testsuite/tests/ghc-api/target-contents/all.T Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -889,3 +889,21 @@ function h$__hscore_free_dirent(a,o) { function h$__hscore_d_name(a,o) { RETURN_UBX_TUP2(h$encodeModifiedUtf8(a.name),0); } + +function h$mkdir(path, path_offset, mode) { + if (!h$isNode()) { + throw "h$mkdir unsupported"; + } + const d = h$decodeUtf8z(path, path_offset); + try { + h$fs.mkdirSync(d, {mode: mode}); + } catch(e) { + // we can't directly set errno code, because numbers may not match + // e.g. e.errno is -17 for EEXIST while we would expect -20 + // this is probably an inconsistency between nodejs using the native + // environment and everything else using Emscripten-provided headers. + h$setErrno(e); + return -1; + } + return 0; +} ===================================== libraries/base/tests/IO/all.T ===================================== @@ -64,7 +64,7 @@ test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run, test('openFile001', normal, compile_and_run, ['']) test('openFile002', [exit_code(1), normalise_win32_io_errors], compile_and_run, ['']) -test('openFile003', [normalise_win32_io_errors, js_broken(22374)], compile_and_run, ['']) +test('openFile003', [normalise_win32_io_errors, js_broken(22362)], compile_and_run, ['']) test('openFile004', [], compile_and_run, ['']) test('openFile005', js_broken(22261), compile_and_run, ['']) test('openFile006', [], compile_and_run, ['']) @@ -152,3 +152,5 @@ test('T17510', expect_broken(17510), compile_and_run, ['']) test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) + +test('mkdirExists', [exit_code(1), when(opsys('mingw32'), ignore_stderr)], compile_and_run, ['']) ===================================== libraries/base/tests/IO/mkdirExists.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import System.Directory + +main :: IO () +main = do + createDirectory "foo" + createDirectory "foo" ===================================== libraries/base/tests/IO/mkdirExists.stderr ===================================== @@ -0,0 +1 @@ +mkdirExists: foo: createDirectory: already exists (File exists) ===================================== testsuite/tests/ghc-api/target-contents/all.T ===================================== @@ -1,6 +1,6 @@ test('TargetContents', [ extra_run_opts('"' + config.libdir + '"') - , js_broken(22374) + , js_broken(22362) ] , compile_and_run, ['-package ghc -package exceptions']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b9132c39a150dae18d93822a6b419543e5bc4a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b9132c39a150dae18d93822a6b419543e5bc4a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 17:31:36 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 13:31:36 -0400 Subject: [Git][ghc/ghc][master] Fix doc typos in libraries/base/GHC Message-ID: <6442c8781b00b_178e746614451891973d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 6 changed files: - libraries/base/GHC/IO/Device.hs - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Handle.hs - libraries/base/GHC/IO/SubSystem.hs - libraries/base/GHC/List.hs - libraries/base/GHC/TypeNats.hs Changes: ===================================== libraries/base/GHC/IO/Device.hs ===================================== @@ -35,7 +35,7 @@ import {-# SOURCE #-} GHC.IO.Exception ( unsupportedOperation ) -- | A low-level I/O provider where the data is bytes in memory. -- The Word64 offsets currently have no effect on POSIX system or consoles --- where the implicit behaviour of the C runtime is assume to move the file +-- where the implicit behaviour of the C runtime is assumed to move the file -- pointer on every read/write without needing an explicit seek. class RawIO a where -- | Read up to the specified number of bytes starting from a specified @@ -107,7 +107,7 @@ class IODevice a where -- | some devices (e.g. terminals) support a "raw" mode where -- characters entered are immediately made available to the program. - -- If available, this operations enables raw mode. + -- If available, this operation enables raw mode. setRaw :: a -> Bool -> IO () setRaw _ _ = ioe_unsupportedOperation ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -268,7 +268,7 @@ char8 = Latin1.latin1 -- -- 2. If the underlying encoding is not itself roundtrippable, this mechanism -- can fail. Roundtrippable encodings are those which have an injective mapping --- into Unicode. Almost all encodings meet this criteria, but some do not. Notably, +-- into Unicode. Almost all encodings meet this criterion, but some do not. Notably, -- Shift-JIS (CP932) and Big5 contain several different encodings of the same -- Unicode codepoint. -- ===================================== libraries/base/GHC/IO/Handle.hs ===================================== @@ -193,7 +193,7 @@ hLookAhead handle = -- -- * if @hdl@ is writable, the buffer is flushed as for 'hFlush'; -- --- * if @hdl@ is not writable, the contents of the buffer is discarded. +-- * if @hdl@ is not writable, the contents of the buffer are discarded. -- -- This operation may fail with: -- @@ -296,7 +296,7 @@ hFlush handle = wantWritableHandle "hFlush" handle flushWriteBuffer -- | The action 'hFlushAll' @hdl@ flushes all buffered data in @hdl@, -- including any buffered read data. Buffered read data is flushed --- by seeking the file position back to the point before the bufferred +-- by seeking the file position back to the point before the buffered -- data was read, and hence only works if @hdl@ is seekable (see -- 'hIsSeekable'). -- ===================================== libraries/base/GHC/IO/SubSystem.hs ===================================== @@ -39,7 +39,7 @@ infixl 7 -- | Conditionally execute an action depending on the configured I/O subsystem. -- On POSIX systems always execute the first action. --- On windows execute the second action if WINIO as active, otherwise fall back to +-- On Windows execute the second action if WINIO as active, otherwise fall back to -- the first action. conditional :: a -> a -> a #if defined(mingw32_HOST_OS) ===================================== libraries/base/GHC/List.hs ===================================== @@ -1084,7 +1084,7 @@ splitAt n ls #endif /* USE_REPORT_PRELUDE */ -- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where --- first element is longest prefix (possibly empty) of @xs@ of elements that +-- first element is the longest prefix (possibly empty) of @xs@ of elements that -- satisfy @p@ and second element is the remainder of the list: -- -- >>> span (< 3) [1,2,3,4,1,2,3,4] ===================================== libraries/base/GHC/TypeNats.hs ===================================== @@ -68,7 +68,7 @@ import GHC.TypeNats.Internal(CmpNat) -- | A type synonym for 'Natural'. -- --- Prevously, this was an opaque data type, but it was changed to a type +-- Previously, this was an opaque data type, but it was changed to a type -- synonym. -- -- @since 4.16.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dae514f9835f7fe8e6643f8759cc4d0b0af9a657 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dae514f9835f7fe8e6643f8759cc4d0b0af9a657 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 17:32:18 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 13:32:18 -0400 Subject: [Git][ghc/ghc][master] Testsuite: replace some js_broken/js_skip predicates with req_c Message-ID: <6442c8a29d314_178e74661e0148923074@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 5 changed files: - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/ffi/should_run/all.T - testsuite/tests/rts/T15894/all.T - testsuite/tests/rts/all.T - testsuite/tests/rts/linker/all.T Changes: ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -260,7 +260,7 @@ test('hs_try_putmvar001', [ when(opsys('mingw32'),skip), # uses pthread APIs in the C code only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip + req_c ], compile_and_run, ['hs_try_putmvar001_c.c']) @@ -270,7 +270,7 @@ test('hs_try_putmvar001', test('hs_try_putmvar002', [pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar002_setup'), omit_ways(['ghci']), - js_skip, + req_c, extra_run_opts('1 8 10000')], compile_and_run, ['hs_try_putmvar002_c.c']) @@ -280,7 +280,7 @@ test('hs_try_putmvar003', when(opsys('mingw32'),skip), # uses pthread APIs in the C code pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar003_setup'), only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip, + req_c, extra_run_opts('1 16 32 100'), fragile_for(16361, ['threaded1']) ], ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -192,7 +192,7 @@ test('T9274', [omit_ways(['ghci'])], compile_and_run, ['']) test('ffi023', [ omit_ways(['ghci']), extra_run_opts('1000 4'), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory ffi023_setup') ], # The ffi023_setup hack is to ensure that we generate # ffi023_stub.h before compiling ffi023_c.c, which @@ -206,7 +206,7 @@ test('rts_clearMemory', [ extra_ways(['g1', 'nursery_chunks', 'nonmoving', 'compacting_gc']), # On windows, nonmoving way fails with bad exit code (2816) when(opsys('mingw32'), fragile(23091)), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory rts_clearMemory_setup') ], # Same hack as ffi023 compile_and_run, ['rts_clearMemory_c.c -no-hs-main']) ===================================== testsuite/tests/rts/T15894/all.T ===================================== @@ -1,5 +1,5 @@ test('T15894', [ extra_files(['copysign.c', 'main.hs']), when(ghc_dynamic(), skip) - , js_broken(22359) + , req_c ], makefile_test, ['T15894']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -251,7 +251,7 @@ test('T5993', extra_run_opts('+RTS -k8 -RTS'), compile_and_run, ['']) test('T6006', [ omit_ways(prof_ways + ['ghci']), pre_cmd('$MAKE -s --no-print-directory T6006_setup'), - js_skip + req_c ], # The T6006_setup hack is to ensure that we generate # T6006_stub.h before compiling T6006_c.c, which ===================================== testsuite/tests/rts/linker/all.T ===================================== @@ -93,13 +93,13 @@ test('T5435_v_gcc', test('T5435_dyn_asm', [extra_files(['T5435.hs', 'T5435_asm.c']), fragile(22970), - js_skip, # dynamic linking not supported by the JS backend + req_c, check_stdout(checkDynAsm)], makefile_test, ['T5435_dyn_asm']) test('T5435_dyn_gcc', [extra_files(['T5435.hs', 'T5435_gcc.c']), fragile(22970), - js_skip], # dynamic linking not supported by the JS backend + req_c], makefile_test, ['T5435_dyn_gcc']) ###################################### View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/113e21d763678ea7e7666b708e6c2dba7e52382f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/113e21d763678ea7e7666b708e6c2dba7e52382f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 18:03:03 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 14:03:03 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fix doc typos in libraries/base/GHC Message-ID: <6442cfd7b5a9c_178e7466ed25a49268e0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - bd8b6813 by Krzysztof Gogolewski at 2023-04-21T14:02:53-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - 2de6d874 by amesgen at 2023-04-21T14:02:57-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 17 changed files: - .gitignore - docs/users_guide/exts/control.rst - docs/users_guide/exts/multiway_if.rst - docs/users_guide/javascript.rst - docs/users_guide/phases.rst - docs/users_guide/using-warnings.rst - libraries/base/GHC/IO/Device.hs - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Handle.hs - libraries/base/GHC/IO/SubSystem.hs - libraries/base/GHC/List.hs - libraries/base/GHC/TypeNats.hs - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/ffi/should_run/all.T - testsuite/tests/rts/T15894/all.T - testsuite/tests/rts/all.T - testsuite/tests/rts/linker/all.T Changes: ===================================== .gitignore ===================================== @@ -115,6 +115,7 @@ _darcs/ /compiler/ghc.cabal.old /distrib/configure.ac /distrib/ghc.iss +/docs/index.html /docs/man /docs/users_guide/.log /docs/users_guide/users_guide ===================================== docs/users_guide/exts/control.rst ===================================== @@ -98,6 +98,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`DoAndIfThenElse` * :extension:`EmptyDataDecls` * :extension:`FieldSelectors` @@ -120,6 +121,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`FieldSelectors` * :extension:`ImplicitPrelude` * :extension:`MonomorphismRestriction` ===================================== docs/users_guide/exts/multiway_if.rst ===================================== @@ -51,3 +51,11 @@ except that the semi-colons between guards in a multi-way if are optional. So it is not necessary to line up all the guards at the same column; this is consistent with the way guards work in function definitions and case expressions. + +Note that multi-way if supports guards other than boolean conditions: :: + + if | parseNumbers settings + , Just (exponent, mantissa) <- decomposeNumber str + , let (integralPart, fractionPart) = parse mantissa + , integralPart >= 0 = ... + | otherwise = ... ===================================== docs/users_guide/javascript.rst ===================================== @@ -1,4 +1,4 @@ -.. _ffi-javascript +.. _ffi-javascript: FFI and the JavaScript Backend ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ look like: js_add :: Int -> Int -> Int JSVal -^^^^^ +~~~~~ The JavaScript backend has a concept of an untyped 'plain' JavaScript value, under the guise of the type ``JSVal``. Values having this type @@ -47,7 +47,7 @@ It also contains functions for working with objects: * ``getProp :: JSVal -> String -> JSVal`` - object field access JavaScript FFI Types -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ Some types are able to be used directly in the type signatures of foreign exports, without conversion to a ``JSVal``. We saw in the first example @@ -75,7 +75,7 @@ for the Haskell `Bool` type: type_error :: Bool -> Bool JavaScript Callbacks -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The JavaScript execution model is based around callback functions, and GHC's JavaScript backend implements these as a type in order to support @@ -146,7 +146,7 @@ passed as an ``Int`` to a ``Callback`` that accepts a ``JSVal``: releaseCallback add3 Callbacks as Foreign Exports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JavaScript callbacks allow for a sort of FFI exports via FFI imports. To do this, a global JavaScript variable is set, and that global variable can then ===================================== docs/users_guide/phases.rst ===================================== @@ -247,13 +247,6 @@ the following flags: Pass ⟨option⟩ to the linker when merging object files. In the case of a standard ``ld``-style linker this should generally include the ``-r`` flag. -.. ghc-flag:: -optdll ⟨option⟩ - :shortdesc: pass ⟨option⟩ to the DLL generator - :type: dynamic - :category: phase-options - - Pass ⟨option⟩ to the DLL generator. - .. ghc-flag:: -optwindres ⟨option⟩ :shortdesc: pass ⟨option⟩ to ``windres``. :type: dynamic ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -2358,7 +2358,7 @@ of ``-W(no-)*``. :since: 9.6.1 - As explained in :ref:`undecidable_instances`, when using + As explained in :ref:`undecidable-instances`, when using :extension:`UndecidableInstances` it is possible for GHC to construct non-terminating evidence for certain superclass constraints. ===================================== libraries/base/GHC/IO/Device.hs ===================================== @@ -35,7 +35,7 @@ import {-# SOURCE #-} GHC.IO.Exception ( unsupportedOperation ) -- | A low-level I/O provider where the data is bytes in memory. -- The Word64 offsets currently have no effect on POSIX system or consoles --- where the implicit behaviour of the C runtime is assume to move the file +-- where the implicit behaviour of the C runtime is assumed to move the file -- pointer on every read/write without needing an explicit seek. class RawIO a where -- | Read up to the specified number of bytes starting from a specified @@ -107,7 +107,7 @@ class IODevice a where -- | some devices (e.g. terminals) support a "raw" mode where -- characters entered are immediately made available to the program. - -- If available, this operations enables raw mode. + -- If available, this operation enables raw mode. setRaw :: a -> Bool -> IO () setRaw _ _ = ioe_unsupportedOperation ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -268,7 +268,7 @@ char8 = Latin1.latin1 -- -- 2. If the underlying encoding is not itself roundtrippable, this mechanism -- can fail. Roundtrippable encodings are those which have an injective mapping --- into Unicode. Almost all encodings meet this criteria, but some do not. Notably, +-- into Unicode. Almost all encodings meet this criterion, but some do not. Notably, -- Shift-JIS (CP932) and Big5 contain several different encodings of the same -- Unicode codepoint. -- ===================================== libraries/base/GHC/IO/Handle.hs ===================================== @@ -193,7 +193,7 @@ hLookAhead handle = -- -- * if @hdl@ is writable, the buffer is flushed as for 'hFlush'; -- --- * if @hdl@ is not writable, the contents of the buffer is discarded. +-- * if @hdl@ is not writable, the contents of the buffer are discarded. -- -- This operation may fail with: -- @@ -296,7 +296,7 @@ hFlush handle = wantWritableHandle "hFlush" handle flushWriteBuffer -- | The action 'hFlushAll' @hdl@ flushes all buffered data in @hdl@, -- including any buffered read data. Buffered read data is flushed --- by seeking the file position back to the point before the bufferred +-- by seeking the file position back to the point before the buffered -- data was read, and hence only works if @hdl@ is seekable (see -- 'hIsSeekable'). -- ===================================== libraries/base/GHC/IO/SubSystem.hs ===================================== @@ -39,7 +39,7 @@ infixl 7 -- | Conditionally execute an action depending on the configured I/O subsystem. -- On POSIX systems always execute the first action. --- On windows execute the second action if WINIO as active, otherwise fall back to +-- On Windows execute the second action if WINIO as active, otherwise fall back to -- the first action. conditional :: a -> a -> a #if defined(mingw32_HOST_OS) ===================================== libraries/base/GHC/List.hs ===================================== @@ -1084,7 +1084,7 @@ splitAt n ls #endif /* USE_REPORT_PRELUDE */ -- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where --- first element is longest prefix (possibly empty) of @xs@ of elements that +-- first element is the longest prefix (possibly empty) of @xs@ of elements that -- satisfy @p@ and second element is the remainder of the list: -- -- >>> span (< 3) [1,2,3,4,1,2,3,4] ===================================== libraries/base/GHC/TypeNats.hs ===================================== @@ -68,7 +68,7 @@ import GHC.TypeNats.Internal(CmpNat) -- | A type synonym for 'Natural'. -- --- Prevously, this was an opaque data type, but it was changed to a type +-- Previously, this was an opaque data type, but it was changed to a type -- synonym. -- -- @since 4.16.0.0 ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -260,7 +260,7 @@ test('hs_try_putmvar001', [ when(opsys('mingw32'),skip), # uses pthread APIs in the C code only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip + req_c ], compile_and_run, ['hs_try_putmvar001_c.c']) @@ -270,7 +270,7 @@ test('hs_try_putmvar001', test('hs_try_putmvar002', [pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar002_setup'), omit_ways(['ghci']), - js_skip, + req_c, extra_run_opts('1 8 10000')], compile_and_run, ['hs_try_putmvar002_c.c']) @@ -280,7 +280,7 @@ test('hs_try_putmvar003', when(opsys('mingw32'),skip), # uses pthread APIs in the C code pre_cmd('$MAKE -s --no-print-directory hs_try_putmvar003_setup'), only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), - js_skip, + req_c, extra_run_opts('1 16 32 100'), fragile_for(16361, ['threaded1']) ], ===================================== testsuite/tests/ffi/should_run/all.T ===================================== @@ -192,7 +192,7 @@ test('T9274', [omit_ways(['ghci'])], compile_and_run, ['']) test('ffi023', [ omit_ways(['ghci']), extra_run_opts('1000 4'), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory ffi023_setup') ], # The ffi023_setup hack is to ensure that we generate # ffi023_stub.h before compiling ffi023_c.c, which @@ -206,7 +206,7 @@ test('rts_clearMemory', [ extra_ways(['g1', 'nursery_chunks', 'nonmoving', 'compacting_gc']), # On windows, nonmoving way fails with bad exit code (2816) when(opsys('mingw32'), fragile(23091)), - js_broken(22363), + req_c, pre_cmd('$MAKE -s --no-print-directory rts_clearMemory_setup') ], # Same hack as ffi023 compile_and_run, ['rts_clearMemory_c.c -no-hs-main']) ===================================== testsuite/tests/rts/T15894/all.T ===================================== @@ -1,5 +1,5 @@ test('T15894', [ extra_files(['copysign.c', 'main.hs']), when(ghc_dynamic(), skip) - , js_broken(22359) + , req_c ], makefile_test, ['T15894']) ===================================== testsuite/tests/rts/all.T ===================================== @@ -251,7 +251,7 @@ test('T5993', extra_run_opts('+RTS -k8 -RTS'), compile_and_run, ['']) test('T6006', [ omit_ways(prof_ways + ['ghci']), pre_cmd('$MAKE -s --no-print-directory T6006_setup'), - js_skip + req_c ], # The T6006_setup hack is to ensure that we generate # T6006_stub.h before compiling T6006_c.c, which ===================================== testsuite/tests/rts/linker/all.T ===================================== @@ -93,13 +93,13 @@ test('T5435_v_gcc', test('T5435_dyn_asm', [extra_files(['T5435.hs', 'T5435_asm.c']), fragile(22970), - js_skip, # dynamic linking not supported by the JS backend + req_c, check_stdout(checkDynAsm)], makefile_test, ['T5435_dyn_asm']) test('T5435_dyn_gcc', [extra_files(['T5435.hs', 'T5435_gcc.c']), fragile(22970), - js_skip], # dynamic linking not supported by the JS backend + req_c], makefile_test, ['T5435_dyn_gcc']) ###################################### View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5afb844f3534c59f5867ac6458e3bb04dcd6c119...2de6d8747f7804b2bb5e421d858d8bd432f55cbe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5afb844f3534c59f5867ac6458e3bb04dcd6c119...2de6d8747f7804b2bb5e421d858d8bd432f55cbe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 18:11:26 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 21 Apr 2023 14:11:26 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <6442d1ced6668_178e7466ed25e09323b8@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 2d740ddb by Josh Meredith at 2023-04-21T18:10:58+00:00 Use unboxed codebuffers in base - - - - - 8 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/CodePage/API.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/CodePage/API.hs ===================================== @@ -1,6 +1,7 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude, NondecreasingIndentation, - RecordWildCards, ScopedTypeVariables #-} + RecordWildCards, ScopedTypeVariables, + UnboxedTuples #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} module GHC.IO.Encoding.CodePage.API ( @@ -157,11 +158,15 @@ newCP rec fn cp = do utf16_native_encode' :: EncodeBuffer utf16_native_decode' :: DecodeBuffer #if defined(WORDS_BIGENDIAN) -utf16_native_encode' = utf16be_encode -utf16_native_decode' = utf16be_decode +utf16_native_encode' = IO $ \st -> case utf16be_encode st of + (# st', c, i, o #) -> (# st', (c, i, o) #) +utf16_native_decode' = IO $ \st -> case utf16be_decode st of + (# st', i, o #) -> (# st', (i, o) #) #else -utf16_native_encode' = utf16le_encode -utf16_native_decode' = utf16le_decode +utf16_native_encode' = IO $ \st -> case utf16le_encode st of + (# st', c, i, o #) -> (# st', (c, i, o) #) +utf16_native_decode' = IO $ \st -> case utf16le_decode st of + (# st', i, o #) -> (# st', (i, o) #) #endif saner :: CodeBuffer from to ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let !(# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d740ddbe4b6ba9540d4235043788c0745517446 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d740ddbe4b6ba9540d4235043788c0745517446 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 19:44:25 2023 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Fri, 21 Apr 2023 15:44:25 -0400 Subject: [Git][ghc/ghc][wip/T23247] 42 commits: Add support for -debug in the testsuite Message-ID: <6442e799c4551_178e74689514209342be@gitlab.mail> Cheng Shao pushed to branch wip/T23247 at Glasgow Haskell Compiler / GHC Commits: bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 4ee7ae9b by Ben Gamari at 2023-04-21T19:43:58+00:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 30 changed files: - .gitlab-ci.yml - .gitmodules - cabal.project-reinstall - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe34804e2eb88f76a5823323913e0a1474ffd682...4ee7ae9b5a81466042dee7857b41438879de885e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe34804e2eb88f76a5823323913e0a1474ffd682...4ee7ae9b5a81466042dee7857b41438879de885e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 21:12:48 2023 From: gitlab at gitlab.haskell.org (Melanie Brown (@mixphix)) Date: Fri, 21 Apr 2023 17:12:48 -0400 Subject: [Git][ghc/ghc][wip/clc-86] no deprecation warnings on GHC.Data.Bag Message-ID: <6442fc50561d5_178e746a326878945529@gitlab.mail> Melanie Brown pushed to branch wip/clc-86 at Glasgow Haskell Compiler / GHC Commits: 055f5daf by Melanie Phoenix at 2023-04-21T17:12:43-04:00 no deprecation warnings on GHC.Data.Bag - - - - - 1 changed file: - compiler/GHC/Data/Bag.hs Changes: ===================================== compiler/GHC/Data/Bag.hs ===================================== @@ -7,6 +7,7 @@ Bag: an unordered collection with duplicates -} {-# LANGUAGE ScopedTypeVariables, DeriveTraversable, TypeFamilies #-} +{-# OPTIONS_GHC -Wno-deprecations #-} module GHC.Data.Bag ( Bag, -- abstract type View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/055f5daf6728917fee5bb0b5aed99852fb8c6a28 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/055f5daf6728917fee5bb0b5aed99852fb8c6a28 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 22:03:21 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 18:03:21 -0400 Subject: [Git][ghc/ghc][master] Minor doc fixes Message-ID: <64430829a15d5_178e746b32c0b09496ba@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - 5 changed files: - .gitignore - docs/users_guide/exts/multiway_if.rst - docs/users_guide/javascript.rst - docs/users_guide/phases.rst - docs/users_guide/using-warnings.rst Changes: ===================================== .gitignore ===================================== @@ -115,6 +115,7 @@ _darcs/ /compiler/ghc.cabal.old /distrib/configure.ac /distrib/ghc.iss +/docs/index.html /docs/man /docs/users_guide/.log /docs/users_guide/users_guide ===================================== docs/users_guide/exts/multiway_if.rst ===================================== @@ -51,3 +51,11 @@ except that the semi-colons between guards in a multi-way if are optional. So it is not necessary to line up all the guards at the same column; this is consistent with the way guards work in function definitions and case expressions. + +Note that multi-way if supports guards other than boolean conditions: :: + + if | parseNumbers settings + , Just (exponent, mantissa) <- decomposeNumber str + , let (integralPart, fractionPart) = parse mantissa + , integralPart >= 0 = ... + | otherwise = ... ===================================== docs/users_guide/javascript.rst ===================================== @@ -1,4 +1,4 @@ -.. _ffi-javascript +.. _ffi-javascript: FFI and the JavaScript Backend ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ look like: js_add :: Int -> Int -> Int JSVal -^^^^^ +~~~~~ The JavaScript backend has a concept of an untyped 'plain' JavaScript value, under the guise of the type ``JSVal``. Values having this type @@ -47,7 +47,7 @@ It also contains functions for working with objects: * ``getProp :: JSVal -> String -> JSVal`` - object field access JavaScript FFI Types -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ Some types are able to be used directly in the type signatures of foreign exports, without conversion to a ``JSVal``. We saw in the first example @@ -75,7 +75,7 @@ for the Haskell `Bool` type: type_error :: Bool -> Bool JavaScript Callbacks -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The JavaScript execution model is based around callback functions, and GHC's JavaScript backend implements these as a type in order to support @@ -146,7 +146,7 @@ passed as an ``Int`` to a ``Callback`` that accepts a ``JSVal``: releaseCallback add3 Callbacks as Foreign Exports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JavaScript callbacks allow for a sort of FFI exports via FFI imports. To do this, a global JavaScript variable is set, and that global variable can then ===================================== docs/users_guide/phases.rst ===================================== @@ -247,13 +247,6 @@ the following flags: Pass ⟨option⟩ to the linker when merging object files. In the case of a standard ``ld``-style linker this should generally include the ``-r`` flag. -.. ghc-flag:: -optdll ⟨option⟩ - :shortdesc: pass ⟨option⟩ to the DLL generator - :type: dynamic - :category: phase-options - - Pass ⟨option⟩ to the DLL generator. - .. ghc-flag:: -optwindres ⟨option⟩ :shortdesc: pass ⟨option⟩ to ``windres``. :type: dynamic ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -2358,7 +2358,7 @@ of ``-W(no-)*``. :since: 9.6.1 - As explained in :ref:`undecidable_instances`, when using + As explained in :ref:`undecidable-instances`, when using :extension:`UndecidableInstances` it is possible for GHC to construct non-terminating evidence for certain superclass constraints. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/038bb03157cabf53bd08426cbd86a38486b9752d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/038bb03157cabf53bd08426cbd86a38486b9752d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 21 22:04:02 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 21 Apr 2023 18:04:02 -0400 Subject: [Git][ghc/ghc][master] User's guide: DeepSubsumption is implied by Haskell{98,2010} Message-ID: <64430852e9854_178e746b42d6f89533ca@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 1 changed file: - docs/users_guide/exts/control.rst Changes: ===================================== docs/users_guide/exts/control.rst ===================================== @@ -98,6 +98,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`DoAndIfThenElse` * :extension:`EmptyDataDecls` * :extension:`FieldSelectors` @@ -120,6 +121,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`FieldSelectors` * :extension:`ImplicitPrelude` * :extension:`MonomorphismRestriction` View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e826cdb213e9b900dfc8f604220d8f3538b98763 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e826cdb213e9b900dfc8f604220d8f3538b98763 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 22 04:09:23 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Sat, 22 Apr 2023 00:09:23 -0400 Subject: [Git][ghc/ghc][wip/expand-do] run the pattern match check in generated lambda exprs to avoid getting... Message-ID: <64435df35ec0c_178e747167593c960897@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 96efd55c by Apoorv Ingle at 2023-04-21T22:57:48-05:00 run the pattern match check in generated lambda exprs to avoid getting suprious pattern match failures. c.f. pmcheck/should_compile/DoubleMatch.hs - - - - - 7 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc.hs - compiler/GHC/HsToCore/Pmc/Utils.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Match.hs - + testsuite/tests/pmcheck/should_compile/DoubleMatch.hs Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -150,6 +150,7 @@ dsHsBind dflags (VarBind { var_id = var force_var = if xopt LangExt.Strict dflags then [id] else [] + -- ; tracePm "dsHsBind" (vcat [text "VarBind:", ppr force_var, ppr core_bind]) ; return (force_var, [core_bind]) } dsHsBind dflags b@(FunBind { fun_id = L loc fun @@ -179,10 +180,11 @@ dsHsBind dflags b@(FunBind { fun_id = L loc fun = [id] | otherwise = [] - ; --pprTrace "dsHsBind" (vcat [ ppr fun <+> ppr (idInlinePragma fun) - -- , ppr (mg_alts matches) - -- , ppr args, ppr core_binds, ppr body']) $ - return (force_var, [core_binds]) } } + -- ; tracePm "dsHsBind" (vcat [ text "FunBind:", + -- , ppr fun <+> ppr (idInlinePragma fun) + -- , ppr (mg_alts matches) + -- , ppr args, ppr core_binds, ppr body']) + ; return (force_var, [core_binds]) } } dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss , pat_ext = (ty, (rhs_tick, var_ticks)) @@ -197,6 +199,9 @@ dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss ; let force_var' = if isBangedLPat pat' then [force_var] else [] + -- ; tracePm "dsHsBind" (vcat [text "PatBind" + -- , ppr force_var' + -- , ppr sel_binds]) ; return (force_var', sel_binds) } dsHsBind ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -783,6 +783,9 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches -- Pattern match check warnings for /this match-group/. -- @rhss_nablas@ is a flat list of covered Nablas for each RHS. -- Each Match will split off one Nablas for its RHSs from this. + -- ; tracePm "matchWrapper" (vcat [ppr ctxt + -- , text "matchPmChecked" + -- , ppr $ isMatchContextPmChecked dflags origin ctxt]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt then addHsScrutTmCs (concat scrs) new_vars $ -- See Note [Long-distance information] ===================================== compiler/GHC/HsToCore/Pmc.hs ===================================== @@ -159,7 +159,7 @@ pmcMatches ctxt vars matches = {-# SCC "pmcMatches" #-} do tracePm "pmcMatches {" $ hang (vcat [ppr ctxt, ppr vars, text "Matches:"]) 2 - (vcat (map ppr matches) $$ ppr missing) + (vcat (map ppr matches) $$ (text "missing:" <+> ppr missing)) case NE.nonEmpty matches of Nothing -> do -- This must be an -XEmptyCase. See Note [Checking EmptyCase] ===================================== compiler/GHC/HsToCore/Pmc/Utils.hs ===================================== @@ -108,6 +108,9 @@ arrowMatchContextExhaustiveWarningFlag = \ case -- 'HsMatchContext' (does not matter whether it is the redundancy check or the -- exhaustiveness check). isMatchContextPmChecked :: DynFlags -> Origin -> HsMatchContext id -> Bool +isMatchContextPmChecked _ origin LambdaExpr + | isGenerated origin + = True isMatchContextPmChecked dflags origin kind | isGenerated origin = False ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -326,6 +326,7 @@ tcApp rn_expr exp_res_ty = do { traceTc "tcApp {" $ vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] + ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args -- Instantiate ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -326,7 +326,9 @@ tcDoStmts doExpr@(DoExpr _) (L l stmts) res_ty ; let expand_do_expr = mkExpandedExpr (HsDo noExtField doExpr (L l stmts)) (unLoc expand_expr) -- Do expansion on the fly - ; traceTc "tcDoStmts do" (text "tcExpr:" <+> ppr expand_do_expr) + ; traceTc "tcDoStmts do" (vcat [ text "original:" <+> ppr expand_do_expr + , text "expnd:" <+> ppr expand_expr + ]) ; tcExpr expand_do_expr res_ty } ===================================== testsuite/tests/pmcheck/should_compile/DoubleMatch.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE CApiFFI, CPP, DeriveDataTypeable, NondecreasingIndentation #-} +{-# OPTIONS_GHC -Wincomplete-patterns #-} +{-# OPTIONS_GHC -fno-cse #-} +module DoubleMatch where + +data Handler = Default + | Handler1 + +doingThing :: Handler -> IO Int +doingThing handler = do + v <- case handler of + Default -> return 0 + _other_Handler -> do + asdf <- return 1 + let action = case handler of + Handler1 -> 1 + return action + return v View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96efd55c5b3cbcbc01327521e36c8aba7a16b165 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/96efd55c5b3cbcbc01327521e36c8aba7a16b165 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 22 04:09:55 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Sat, 22 Apr 2023 00:09:55 -0400 Subject: [Git][ghc/ghc][wip/expand-do] run the pattern match check in generated lambda exprs to avoid getting... Message-ID: <64435e132f07b_178e747167593c96139f@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 6b575d48 by Apoorv Ingle at 2023-04-21T23:09:47-05:00 run the pattern match check in generated lambda exprs to avoid getting suprious pattern match failures. c.f. pmcheck/should_compile/DoubleMatch.hs - - - - - 8 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc.hs - compiler/GHC/HsToCore/Pmc/Utils.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Match.hs - + testsuite/tests/pmcheck/should_compile/DoubleMatch.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -150,6 +150,7 @@ dsHsBind dflags (VarBind { var_id = var force_var = if xopt LangExt.Strict dflags then [id] else [] + -- ; tracePm "dsHsBind" (vcat [text "VarBind:", ppr force_var, ppr core_bind]) ; return (force_var, [core_bind]) } dsHsBind dflags b@(FunBind { fun_id = L loc fun @@ -179,10 +180,11 @@ dsHsBind dflags b@(FunBind { fun_id = L loc fun = [id] | otherwise = [] - ; --pprTrace "dsHsBind" (vcat [ ppr fun <+> ppr (idInlinePragma fun) - -- , ppr (mg_alts matches) - -- , ppr args, ppr core_binds, ppr body']) $ - return (force_var, [core_binds]) } } + -- ; tracePm "dsHsBind" (vcat [ text "FunBind:", + -- , ppr fun <+> ppr (idInlinePragma fun) + -- , ppr (mg_alts matches) + -- , ppr args, ppr core_binds, ppr body']) + ; return (force_var, [core_binds]) } } dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss , pat_ext = (ty, (rhs_tick, var_ticks)) @@ -197,6 +199,9 @@ dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss ; let force_var' = if isBangedLPat pat' then [force_var] else [] + -- ; tracePm "dsHsBind" (vcat [text "PatBind" + -- , ppr force_var' + -- , ppr sel_binds]) ; return (force_var', sel_binds) } dsHsBind ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -783,6 +783,9 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches -- Pattern match check warnings for /this match-group/. -- @rhss_nablas@ is a flat list of covered Nablas for each RHS. -- Each Match will split off one Nablas for its RHSs from this. + -- ; tracePm "matchWrapper" (vcat [ppr ctxt + -- , text "matchPmChecked" + -- , ppr $ isMatchContextPmChecked dflags origin ctxt]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt then addHsScrutTmCs (concat scrs) new_vars $ -- See Note [Long-distance information] ===================================== compiler/GHC/HsToCore/Pmc.hs ===================================== @@ -159,7 +159,7 @@ pmcMatches ctxt vars matches = {-# SCC "pmcMatches" #-} do tracePm "pmcMatches {" $ hang (vcat [ppr ctxt, ppr vars, text "Matches:"]) 2 - (vcat (map ppr matches) $$ ppr missing) + (vcat (map ppr matches) $$ (text "missing:" <+> ppr missing)) case NE.nonEmpty matches of Nothing -> do -- This must be an -XEmptyCase. See Note [Checking EmptyCase] ===================================== compiler/GHC/HsToCore/Pmc/Utils.hs ===================================== @@ -108,6 +108,9 @@ arrowMatchContextExhaustiveWarningFlag = \ case -- 'HsMatchContext' (does not matter whether it is the redundancy check or the -- exhaustiveness check). isMatchContextPmChecked :: DynFlags -> Origin -> HsMatchContext id -> Bool +isMatchContextPmChecked _ origin LambdaExpr + | isGenerated origin + = True isMatchContextPmChecked dflags origin kind | isGenerated origin = False ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -326,6 +326,7 @@ tcApp rn_expr exp_res_ty = do { traceTc "tcApp {" $ vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] + ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args -- Instantiate ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -326,7 +326,9 @@ tcDoStmts doExpr@(DoExpr _) (L l stmts) res_ty ; let expand_do_expr = mkExpandedExpr (HsDo noExtField doExpr (L l stmts)) (unLoc expand_expr) -- Do expansion on the fly - ; traceTc "tcDoStmts do" (text "tcExpr:" <+> ppr expand_do_expr) + ; traceTc "tcDoStmts do" (vcat [ text "original:" <+> ppr expand_do_expr + , text "expnd:" <+> ppr expand_expr + ]) ; tcExpr expand_do_expr res_ty } ===================================== testsuite/tests/pmcheck/should_compile/DoubleMatch.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE CApiFFI, CPP, DeriveDataTypeable, NondecreasingIndentation #-} +{-# OPTIONS_GHC -Wincomplete-patterns #-} +{-# OPTIONS_GHC -fno-cse #-} +module DoubleMatch where + +data Handler = Default + | Handler1 + +doingThing :: Handler -> IO Int +doingThing handler = do + v <- case handler of + Default -> return 0 + _other_Handler -> do + asdf <- return 1 + let action = case handler of + Handler1 -> 1 + return action + return v ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -159,3 +159,4 @@ test('EmptyCase010', [], compile, [overlapping_incomplete]) test('T19271', [], compile, [overlapping_incomplete]) test('T21761', [], compile, [overlapping_incomplete]) test('T22964', [], compile, [overlapping_incomplete]) +test('DoubleMatch', normal, compile, [overlapping_incomplete]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6b575d48c5e9ecc629354e15ceb0d6db5d9e02e1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6b575d48c5e9ecc629354e15ceb0d6db5d9e02e1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 22 14:24:31 2023 From: gitlab at gitlab.haskell.org (tocic (@tocic)) Date: Sat, 22 Apr 2023 10:24:31 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/fix/base_ghc_typos Message-ID: <6443ee1f34d9b_178e747b23befc9852ac@gitlab.mail> tocic deleted branch wip/fix/base_ghc_typos at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 09:19:10 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 23 Apr 2023 05:19:10 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 5 commits: Haddock Message-ID: <6444f80e28869_178e748ceff24010049c9@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 08e8e362 by Sven Tennie at 2023-04-23T08:45:10+00:00 Haddock - - - - - 03521011 by Sven Tennie at 2023-04-23T08:53:15+00:00 Simplify stackHead - - - - - 0fc54d87 by Sven Tennie at 2023-04-23T09:00:51+00:00 Formatting - - - - - 8a30e8e7 by Sven Tennie at 2023-04-23T09:07:49+00:00 Rename: getBoxedClosure -> getStackClosure - - - - - e071fa31 by Sven Tennie at 2023-04-23T09:18:10+00:00 Document Cmm return values - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Stack.hs - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs - libraries/ghc-heap/cbits/Stack.c - libraries/ghc-heap/cbits/Stack.cmm Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -390,38 +390,38 @@ data StgStackClosure = StgStackClosure -- matches and complicates the whole implementation (and breaks existing code.) data StackFrame = UpdateFrame - { info_tbl :: !StgInfoTable - , updatee :: !Closure + { info_tbl :: !StgInfoTable + , updatee :: !Closure } | CatchFrame { info_tbl :: !StgInfoTable - , exceptions_blocked :: Word - , handler :: !Closure + , exceptions_blocked :: Word + , handler :: !Closure } | CatchStmFrame { info_tbl :: !StgInfoTable - , catchFrameCode :: !Closure - , handler :: !Closure + , catchFrameCode :: !Closure + , handler :: !Closure } | CatchRetryFrame { info_tbl :: !StgInfoTable - , running_alt_code :: !Word - , first_code :: !Closure - , alt_code :: !Closure + , running_alt_code :: !Word + , first_code :: !Closure + , alt_code :: !Closure } | AtomicallyFrame { info_tbl :: !StgInfoTable , atomicallyFrameCode :: !Closure - , result :: !Closure + , result :: !Closure } | UnderflowFrame { info_tbl :: !StgInfoTable - , nextChunk :: !StgStackClosure + , nextChunk :: !StgStackClosure } | StopFrame @@ -429,26 +429,26 @@ data StackFrame = | RetSmall { info_tbl :: !StgInfoTable - , stack_payload :: ![Closure] + , stack_payload :: ![Closure] } | RetBig { info_tbl :: !StgInfoTable - , stack_payload :: ![Closure] + , stack_payload :: ![Closure] } | RetFun { info_tbl :: !StgInfoTable - , retFunType :: RetFunType - , retFunSize :: Word - , retFunFun :: !Closure - , retFunPayload :: ![Closure] + , retFunType :: RetFunType + , retFunSize :: Word + , retFunFun :: !Closure + , retFunPayload :: ![Closure] } | RetBCO { info_tbl :: !StgInfoTable - , bco :: !Closure -- must be a BCOClosure - , bcoArgs :: ![Closure] + , bco :: !Closure -- must be a BCOClosure + , bcoArgs :: ![Closure] } deriving (Show, Generic) ===================================== libraries/ghc-heap/GHC/Exts/Stack.hs ===================================== @@ -14,6 +14,9 @@ import GHC.Exts.Stack.Constants import GHC.Exts.Stack.Decode import Prelude +-- | Get the size of the `StackFrame` in words. +-- +-- Includes header and payload. Does not follow pointers. stackFrameSize :: StackFrame -> Int stackFrameSize (UpdateFrame {}) = sizeStgUpdateFrame stackFrameSize (CatchFrame {}) = sizeStgCatchFrame ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -190,8 +190,8 @@ getInfoTableForStack stackSnapshot# = peekItbl $ Ptr (getStackInfoTableAddr# stackSnapshot#) -foreign import prim "getBoxedClosurezh" - getBoxedClosure# :: +foreign import prim "getStackClosurezh" + getStackClosure# :: StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Any #) foreign import prim "getStackFieldszh" @@ -205,8 +205,8 @@ getStackFields stackSnapshot# = IO $ \s -> (# s1, (W32# sSize#, W8# sDirty#, W8# sMarking#) #) -- | `StackFrameLocation` of the top-most stack frame -stackHead :: StackSnapshot -> StackFrameLocation -stackHead (StackSnapshot s#) = (StackSnapshot s#, 0) -- GHC stacks are never empty +stackHead :: StackSnapshot# -> StackFrameLocation +stackHead s# = (StackSnapshot s#, 0) -- GHC stacks are never empty -- | Advance to the next stack frame (if any) -- @@ -230,7 +230,7 @@ advanceStackFrameLocation ((StackSnapshot stackSnapshot#), index) = getClosure :: StackSnapshot# -> WordOffset -> IO Closure getClosure stackSnapshot# index = ( IO $ \s -> - case getBoxedClosure# + case getStackClosure# stackSnapshot# (wordOffsetToWord# index) s of @@ -427,19 +427,25 @@ intToWord# i = int2Word# (toInt# i) wordOffsetToWord# :: WordOffset -> Word# wordOffsetToWord# wo = intToWord# (fromIntegral wo) +-- | Location of a stackframe on the stack +-- +-- It's defined by the `StackSnapshot` (@StgStack@) and the offset to the bottom +-- of the stack. type StackFrameLocation = (StackSnapshot, WordOffset) -- | Decode `StackSnapshot` to a `StgStackClosure` -- -- The return value is the representation of the @StgStack@ itself. +-- +-- See /Note [Decoding the stack]/. decodeStack :: StackSnapshot -> IO StgStackClosure decodeStack (StackSnapshot stack#) = do info <- getInfoTableForStack stack# (stack_size', stack_dirty', stack_marking') <- getStackFields stack# case tipe info of STACK -> do - let sfis = stackFrameLocations (StackSnapshot stack#) - stack' <- mapM unpackStackFrame sfis + let sfls = stackFrameLocations stack# + stack' <- mapM unpackStackFrame sfls pure $ StgStackClosure { ssc_info = info, @@ -450,10 +456,10 @@ decodeStack (StackSnapshot stack#) = do } _ -> error $ "Expected STACK closure, got " ++ show info where - stackFrameLocations :: StackSnapshot -> [StackFrameLocation] - stackFrameLocations s = - stackHead s - : go (advanceStackFrameLocation (stackHead s)) + stackFrameLocations :: StackSnapshot# -> [StackFrameLocation] + stackFrameLocations s# = + stackHead s# + : go (advanceStackFrameLocation (stackHead s#)) where go :: Maybe StackFrameLocation -> [StackFrameLocation] go Nothing = [] ===================================== libraries/ghc-heap/cbits/Stack.c ===================================== @@ -147,4 +147,4 @@ StgWord getRetFunType(StgRetFun *ret_fun) { return fun_info->f.fun_type; } -StgClosure *getBoxedClosure(StgClosure **c) { return *c; } +StgClosure *getStackClosure(StgClosure **c) { return *c; } ===================================== libraries/ghc-heap/cbits/Stack.cmm ===================================== @@ -8,7 +8,9 @@ // developed. #if defined(StgStack_marking) -// advanceStackFrameLocationzh(StgStack* stack, StgWord offsetWords) +// Returns the next stackframe's StgStack* and offset in it. And, an indicator +// if this frame is the last one (`hasNext` bit.) +// (StgStack*, StgWord, StgWord) advanceStackFrameLocationzh(StgStack* stack, StgWord offsetWords) advanceStackFrameLocationzh (P_ stack, W_ offsetWords) { W_ frameSize; (frameSize) = ccall stackFrameSize(stack, offsetWords); @@ -48,7 +50,7 @@ advanceStackFrameLocationzh (P_ stack, W_ offsetWords) { return (newStack, newOffsetWords, hasNext); } -// getSmallBitmapzh(StgStack* stack, StgWord offsetWords) +// (StgWord, StgWord) getSmallBitmapzh(StgStack* stack, StgWord offsetWords) getSmallBitmapzh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); @@ -62,7 +64,7 @@ getSmallBitmapzh(P_ stack, W_ offsetWords) { } -// getRetFunSmallBitmapzh(StgStack* stack, StgWord offsetWords) +// (StgWord, StgWord) getRetFunSmallBitmapzh(StgStack* stack, StgWord offsetWords) getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); @@ -75,7 +77,7 @@ getRetFunSmallBitmapzh(P_ stack, W_ offsetWords) { return (bitmap, size); } -// getLargeBitmapzh(StgStack* stack, StgWord offsetWords) +// (StgWord*, StgWord) getLargeBitmapzh(StgStack* stack, StgWord offsetWords) getLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, words; W_ size; @@ -88,7 +90,7 @@ getLargeBitmapzh(P_ stack, W_ offsetWords) { return (words, size); } -// getBCOLargeBitmapzh(StgStack* stack, StgWord offsetWords) +// (StgWord*, StgWord) getBCOLargeBitmapzh(StgStack* stack, StgWord offsetWords) getBCOLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, words; W_ size; @@ -101,7 +103,7 @@ getBCOLargeBitmapzh(P_ stack, W_ offsetWords) { return (words, size); } -// getRetFunLargeBitmapzh(StgStack* stack, StgWord offsetWords) +// (StgWord*, StgWord) getRetFunLargeBitmapzh(StgStack* stack, StgWord offsetWords) getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) { P_ c, words; W_ size; @@ -114,22 +116,14 @@ getRetFunLargeBitmapzh(P_ stack, W_ offsetWords) { return (words, size); } -// getWordzh(StgStack* stack, StgWord offsetWords) +// (StgWord) getWordzh(StgStack* stack, StgWord offsetWords) getWordzh(P_ stack, W_ offsetWords) { P_ wordAddr; wordAddr = (StgStack_sp(stack) + WDS(offsetWords)); return (W_[wordAddr]); } -getAddrzh(P_ stack, W_ offsetWords){ - P_ addr; - addr = (StgStack_sp(stack) + WDS(offsetWords)); - P_ ptr; - ptr = P_[addr]; - return (ptr); -} - -// getUnderflowFrameNextChunkzh(StgStack* stack, StgWord offsetWords) +// (StgStack*) getUnderflowFrameNextChunkzh(StgStack* stack, StgWord offsetWords) getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords) { P_ closurePtr; closurePtr = (StgStack_sp(stack) + WDS(offsetWords)); @@ -141,7 +135,7 @@ getUnderflowFrameNextChunkzh(P_ stack, W_ offsetWords) { return (next_chunk); } -// getRetFunTypezh(StgStack* stack, StgWord offsetWords) +// (StgWord) getRetFunTypezh(StgStack* stack, StgWord offsetWords) getRetFunTypezh(P_ stack, W_ offsetWords) { P_ c; c = StgStack_sp(stack) + WDS(offsetWords); @@ -152,7 +146,7 @@ getRetFunTypezh(P_ stack, W_ offsetWords) { return (type); } -// getInfoTableAddrzh(StgStack* stack, StgWord offsetWords) +// (StgInfoTable*) getInfoTableAddrzh(StgStack* stack, StgWord offsetWords) getInfoTableAddrzh(P_ stack, W_ offsetWords) { P_ p, info; p = StgStack_sp(stack) + WDS(offsetWords); @@ -162,24 +156,24 @@ getInfoTableAddrzh(P_ stack, W_ offsetWords) { return (info); } -// getStackInfoTableAddrzh(StgStack* stack) +// (StgInfoTable*) getStackInfoTableAddrzh(StgStack* stack) getStackInfoTableAddrzh(P_ stack) { P_ info; info = %GET_STD_INFO(UNTAG(stack)); return (info); } -// getBoxedClosurezh(StgStack* stack, StgWord offsetWords) -getBoxedClosurezh(P_ stack, W_ offsetWords) { +// (StgClosure*) getStackClosurezh(StgStack* stack, StgWord offsetWords) +getStackClosurezh(P_ stack, W_ offsetWords) { P_ ptr; ptr = StgStack_sp(stack) + WDS(offsetWords); - P_ box; - (box) = ccall getBoxedClosure(ptr); - return (box); + P_ closure; + (closure) = ccall getStackClosure(ptr); + return (closure); } -// getStackFieldszh(StgStack* stack) +// (bits32, bits8, bits8) getStackFieldszh(StgStack* stack) getStackFieldszh(P_ stack){ bits32 size; bits8 dirty, marking; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e42e2f82e63ebd350dedfc1815f89e4a009d8506...e071fa31da7c5e9264685bf17ca582bde756d00f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e42e2f82e63ebd350dedfc1815f89e4a009d8506...e071fa31da7c5e9264685bf17ca582bde756d00f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 09:31:22 2023 From: gitlab at gitlab.haskell.org (tocic (@tocic)) Date: Sun, 23 Apr 2023 05:31:22 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fix/base_typos Message-ID: <6444faea43aea_178e748d11ca8c10054cc@gitlab.mail> tocic pushed new branch wip/fix/base_typos at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix/base_typos You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 10:08:48 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 23 Apr 2023 06:08:48 -0400 Subject: [Git][ghc/ghc][wip/decode_cloned_stack] 6 commits: Un-IO getWord Message-ID: <644503b086164_178e748dc4550810090c7@gitlab.mail> Sven Tennie pushed to branch wip/decode_cloned_stack at Glasgow Haskell Compiler / GHC Commits: 75039a7b by Sven Tennie at 2023-04-23T09:34:42+00:00 Un-IO getWord - - - - - df9f0b2e by Sven Tennie at 2023-04-23T09:38:14+00:00 Un-IO getUnderflowFrameNextChunk - - - - - 7c26cb2c by Sven Tennie at 2023-04-23T09:44:38+00:00 Un-IO getRetFunType - - - - - f3230b9d by Sven Tennie at 2023-04-23T09:49:20+00:00 Un-IO LargeBitmapGetter - - - - - c4205b02 by Sven Tennie at 2023-04-23T09:53:15+00:00 Un-IO SmallBitmapGetter - - - - - dc135403 by Sven Tennie at 2023-04-23T10:08:26+00:00 Formatting and one comment - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/Stack/Decode.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Stack/Decode.hs ===================================== @@ -117,47 +117,32 @@ Technical details foreign import prim "getUnderflowFrameNextChunkzh" getUnderflowFrameNextChunk# :: - StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, StackSnapshot# #) + StackSnapshot# -> Word# -> StackSnapshot# -getUnderflowFrameNextChunk :: StackSnapshot# -> WordOffset -> IO StackSnapshot -getUnderflowFrameNextChunk stackSnapshot# index = IO $ \s -> - case getUnderflowFrameNextChunk# stackSnapshot# (wordOffsetToWord# index) s of - (# s1, stack# #) -> (# s1, StackSnapshot stack# #) +getUnderflowFrameNextChunk :: StackSnapshot# -> WordOffset -> StackSnapshot +getUnderflowFrameNextChunk stackSnapshot# index = + StackSnapshot (getUnderflowFrameNextChunk# stackSnapshot# (wordOffsetToWord# index)) foreign import prim "getWordzh" getWord# :: - StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Word# #) + StackSnapshot# -> Word# -> Word# -getWord :: StackSnapshot# -> WordOffset -> IO Word -getWord stackSnapshot# index = IO $ \s -> - case getWord# - stackSnapshot# - (wordOffsetToWord# index) - s of - (# s1, w# #) -> (# s1, W# w# #) - -type WordGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Word# #) +getWord :: StackSnapshot# -> WordOffset -> Word +getWord stackSnapshot# index = + W# (getWord# stackSnapshot# (wordOffsetToWord# index)) -foreign import prim "getRetFunTypezh" getRetFunType# :: WordGetter +foreign import prim "getRetFunTypezh" getRetFunType# :: StackSnapshot# -> Word# -> Word# -getRetFunType :: StackSnapshot# -> WordOffset -> IO RetFunType +getRetFunType :: StackSnapshot# -> WordOffset -> RetFunType getRetFunType stackSnapshot# index = - toEnum . fromInteger . toInteger - <$> IO - ( \s -> - case getRetFunType# - stackSnapshot# - (wordOffsetToWord# index) - s of - (# s1, rft# #) -> (# s1, W# rft# #) - ) + toEnum . fromInteger . toInteger $ + W# (getRetFunType# stackSnapshot# (wordOffsetToWord# index)) -- | Gets contents of a `LargeBitmap` (@StgLargeBitmap@) -- -- The first two arguments identify the location of the frame on the stack. --- Returned is the `Addr#` of the @StgWord[]@ (bitmap) and it's size. The --- `RealWorld` token is used to run this in an `IO` context. -type LargeBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Addr#, Word# #) +-- Returned is the `Addr#` of the @StgWord[]@ (bitmap) and it's size. +type LargeBitmapGetter = StackSnapshot# -> Word# -> (# Addr#, Word# #) foreign import prim "getLargeBitmapzh" getLargeBitmap# :: LargeBitmapGetter @@ -168,9 +153,8 @@ foreign import prim "getRetFunLargeBitmapzh" getRetFunLargeBitmap# :: LargeBitma -- | Gets contents of a small bitmap (fitting in one @StgWord@) -- -- The first two arguments identify the location of the frame on the stack. --- Returned is the bitmap and it's size. The `RealWorld` token is used to run --- this in an `IO` context. -type SmallBitmapGetter = StackSnapshot# -> Word# -> State# RealWorld -> (# State# RealWorld, Word#, Word# #) +-- Returned is the bitmap and it's size. +type SmallBitmapGetter = StackSnapshot# -> Word# -> (# Word#, Word# #) foreign import prim "getSmallBitmapzh" getSmallBitmap# :: SmallBitmapGetter @@ -196,13 +180,13 @@ foreign import prim "getStackClosurezh" foreign import prim "getStackFieldszh" getStackFields# :: - StackSnapshot# -> State# RealWorld -> (# State# RealWorld, Word32#, Word8#, Word8# #) + StackSnapshot# -> (# Word32#, Word8#, Word8# #) -getStackFields :: StackSnapshot# -> IO (Word32, Word8, Word8) -getStackFields stackSnapshot# = IO $ \s -> - case getStackFields# stackSnapshot# s of - (# s1, sSize#, sDirty#, sMarking# #) -> - (# s1, (W32# sSize#, W8# sDirty#, W8# sMarking#) #) +getStackFields :: StackSnapshot# -> (Word32, Word8, Word8) +getStackFields stackSnapshot# = + case getStackFields# stackSnapshot# of + (# sSize#, sDirty#, sMarking# #) -> + (W32# sSize#, W8# sDirty#, W8# sMarking#) -- | `StackFrameLocation` of the top-most stack frame stackHead :: StackSnapshot# -> StackFrameLocation @@ -229,6 +213,9 @@ advanceStackFrameLocation ((StackSnapshot stackSnapshot#), index) = getClosure :: StackSnapshot# -> WordOffset -> IO Closure getClosure stackSnapshot# index = + -- Beware! We have to put ptr into a Box immediately. Otherwise, the garbage + -- collector might move the referenced closure, without updating our reference + -- (pointer) to it. ( IO $ \s -> case getStackClosure# stackSnapshot# @@ -251,9 +238,8 @@ data Pointerness = Pointer | NonPointer decodeLargeBitmap :: LargeBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeLargeBitmap getterFun# stackSnapshot# index relativePayloadOffset = do - largeBitmap <- IO $ \s -> - case getterFun# stackSnapshot# (wordOffsetToWord# index) s of - (# s1, wordsAddr#, size# #) -> (# s1, LargeBitmap (W# size#) (Ptr wordsAddr#) #) + let largeBitmap = case getterFun# stackSnapshot# (wordOffsetToWord# index) of + (# wordsAddr#, size# #) -> LargeBitmap (W# size#) (Ptr wordsAddr#) bitmapWords <- largeBitmapToList largeBitmap decodeBitmaps stackSnapshot# @@ -296,21 +282,18 @@ decodeBitmaps stack# index ps = where toPayload :: Pointerness -> WordOffset -> IO Closure toPayload p i = case p of - NonPointer -> do - w <- getWord stack# i - pure $ UnknownTypeWordSizedPrimitive w + NonPointer -> + pure $ UnknownTypeWordSizedPrimitive (getWord stack# i) Pointer -> getClosure stack# i decodeSmallBitmap :: SmallBitmapGetter -> StackSnapshot# -> WordOffset -> WordOffset -> IO [Closure] decodeSmallBitmap getterFun# stackSnapshot# index relativePayloadOffset = - do - (bitmap, size) <- IO $ \s -> - case getterFun# stackSnapshot# (wordOffsetToWord# index) s of - (# s1, b#, s# #) -> (# s1, (W# b#, W# s#) #) - decodeBitmaps - stackSnapshot# - (index + relativePayloadOffset) - (bitmapWordPointerness size bitmap) + let (bitmap, size) = case getterFun# stackSnapshot# (wordOffsetToWord# index) of + (# b#, s# #) -> (W# b#, W# s#) + in decodeBitmaps + stackSnapshot# + (index + relativePayloadOffset) + (bitmapWordPointerness size bitmap) unpackStackFrame :: StackFrameLocation -> IO StackFrame unpackStackFrame (StackSnapshot stackSnapshot#, index) = do @@ -345,8 +328,8 @@ unpackStackFrame (StackSnapshot stackSnapshot#, index) = do stack_payload = payload' } RET_FUN -> do - retFunType' <- getRetFunType stackSnapshot# index - retFunSize' <- getWord stackSnapshot# (index + offsetStgRetFunFrameSize) + let retFunType' = getRetFunType stackSnapshot# index + retFunSize' = getWord stackSnapshot# (index + offsetStgRetFunFrameSize) retFunFun' <- getClosure stackSnapshot# (index + offsetStgRetFunFrameFun) retFunPayload' <- if retFunType' == ARG_GEN_BIG @@ -368,7 +351,7 @@ unpackStackFrame (StackSnapshot stackSnapshot#, index) = do updatee = updatee' } CATCH_FRAME -> do - exceptions_blocked' <- getWord stackSnapshot# (index + offsetStgCatchFrameExceptionsBlocked) + let exceptions_blocked' = getWord stackSnapshot# (index + offsetStgCatchFrameExceptionsBlocked) handler' <- getClosure stackSnapshot# (index + offsetStgCatchFrameHandler) pure $ CatchFrame @@ -377,7 +360,7 @@ unpackStackFrame (StackSnapshot stackSnapshot#, index) = do handler = handler' } UNDERFLOW_FRAME -> do - nextChunk' <- getUnderflowFrameNextChunk stackSnapshot# index + let nextChunk' = getUnderflowFrameNextChunk stackSnapshot# index stackClosure <- decodeStack nextChunk' pure $ UnderflowFrame @@ -395,7 +378,7 @@ unpackStackFrame (StackSnapshot stackSnapshot#, index) = do result = result' } CATCH_RETRY_FRAME -> do - running_alt_code' <- getWord stackSnapshot# (index + offsetStgCatchRetryFrameRunningAltCode) + let running_alt_code' = getWord stackSnapshot# (index + offsetStgCatchRetryFrameRunningAltCode) first_code' <- getClosure stackSnapshot# (index + offsetStgCatchRetryFrameRunningFirstCode) alt_code' <- getClosure stackSnapshot# (index + offsetStgCatchRetryFrameAltCode) pure $ @@ -441,10 +424,10 @@ type StackFrameLocation = (StackSnapshot, WordOffset) decodeStack :: StackSnapshot -> IO StgStackClosure decodeStack (StackSnapshot stack#) = do info <- getInfoTableForStack stack# - (stack_size', stack_dirty', stack_marking') <- getStackFields stack# case tipe info of STACK -> do - let sfls = stackFrameLocations stack# + let (stack_size', stack_dirty', stack_marking') = getStackFields stack# + sfls = stackFrameLocations stack# stack' <- mapM unpackStackFrame sfls pure $ StgStackClosure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e071fa31da7c5e9264685bf17ca582bde756d00f...dc135403e75c95c697d48afc7b085ae757560ca5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e071fa31da7c5e9264685bf17ca582bde756d00f...dc135403e75c95c697d48afc7b085ae757560ca5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 15:19:31 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 23 Apr 2023 11:19:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Minor doc fixes Message-ID: <64454c834c175_178e7492b85dfc103764d@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - a058e004 by PHO at 2023-04-23T11:19:22-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 9e083c0b by tocic at 2023-04-23T11:19:22-04:00 Fix doc typos in libraries/base - - - - - 16 changed files: - .gitignore - docs/users_guide/exts/control.rst - docs/users_guide/exts/multiway_if.rst - docs/users_guide/javascript.rst - docs/users_guide/phases.rst - docs/users_guide/using-warnings.rst - libraries/base/Control/Concurrent/MVar.hs - libraries/base/Control/Exception/Base.hs - libraries/base/Control/Monad.hs - libraries/base/Data/Complex.hs - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/System/Environment.hs - libraries/base/System/Environment/ExecutablePath.hsc - libraries/base/Text/Read/Lex.hs - libraries/ghc-boot/GHC/BaseDir.hs Changes: ===================================== .gitignore ===================================== @@ -115,6 +115,7 @@ _darcs/ /compiler/ghc.cabal.old /distrib/configure.ac /distrib/ghc.iss +/docs/index.html /docs/man /docs/users_guide/.log /docs/users_guide/users_guide ===================================== docs/users_guide/exts/control.rst ===================================== @@ -98,6 +98,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`DoAndIfThenElse` * :extension:`EmptyDataDecls` * :extension:`FieldSelectors` @@ -120,6 +121,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: * :extension:`CUSKs` * :extension:`DatatypeContexts` + * :extension:`DeepSubsumption` * :extension:`FieldSelectors` * :extension:`ImplicitPrelude` * :extension:`MonomorphismRestriction` ===================================== docs/users_guide/exts/multiway_if.rst ===================================== @@ -51,3 +51,11 @@ except that the semi-colons between guards in a multi-way if are optional. So it is not necessary to line up all the guards at the same column; this is consistent with the way guards work in function definitions and case expressions. + +Note that multi-way if supports guards other than boolean conditions: :: + + if | parseNumbers settings + , Just (exponent, mantissa) <- decomposeNumber str + , let (integralPart, fractionPart) = parse mantissa + , integralPart >= 0 = ... + | otherwise = ... ===================================== docs/users_guide/javascript.rst ===================================== @@ -1,4 +1,4 @@ -.. _ffi-javascript +.. _ffi-javascript: FFI and the JavaScript Backend ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ look like: js_add :: Int -> Int -> Int JSVal -^^^^^ +~~~~~ The JavaScript backend has a concept of an untyped 'plain' JavaScript value, under the guise of the type ``JSVal``. Values having this type @@ -47,7 +47,7 @@ It also contains functions for working with objects: * ``getProp :: JSVal -> String -> JSVal`` - object field access JavaScript FFI Types -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ Some types are able to be used directly in the type signatures of foreign exports, without conversion to a ``JSVal``. We saw in the first example @@ -75,7 +75,7 @@ for the Haskell `Bool` type: type_error :: Bool -> Bool JavaScript Callbacks -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The JavaScript execution model is based around callback functions, and GHC's JavaScript backend implements these as a type in order to support @@ -146,7 +146,7 @@ passed as an ``Int`` to a ``Callback`` that accepts a ``JSVal``: releaseCallback add3 Callbacks as Foreign Exports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JavaScript callbacks allow for a sort of FFI exports via FFI imports. To do this, a global JavaScript variable is set, and that global variable can then ===================================== docs/users_guide/phases.rst ===================================== @@ -247,13 +247,6 @@ the following flags: Pass ⟨option⟩ to the linker when merging object files. In the case of a standard ``ld``-style linker this should generally include the ``-r`` flag. -.. ghc-flag:: -optdll ⟨option⟩ - :shortdesc: pass ⟨option⟩ to the DLL generator - :type: dynamic - :category: phase-options - - Pass ⟨option⟩ to the DLL generator. - .. ghc-flag:: -optwindres ⟨option⟩ :shortdesc: pass ⟨option⟩ to ``windres``. :type: dynamic ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -2358,7 +2358,7 @@ of ``-W(no-)*``. :since: 9.6.1 - As explained in :ref:`undecidable_instances`, when using + As explained in :ref:`undecidable-instances`, when using :extension:`UndecidableInstances` it is possible for GHC to construct non-terminating evidence for certain superclass constraints. ===================================== libraries/base/Control/Concurrent/MVar.hs ===================================== @@ -37,7 +37,7 @@ -- than 'GHC.Conc.STM'. They are appropriate for building synchronization -- primitives and performing simple interthread communication; however -- they are very simple and susceptible to race conditions, deadlocks or --- uncaught exceptions. Do not use them if you need perform larger +-- uncaught exceptions. Do not use them if you need to perform larger -- atomic operations such as reading from multiple variables: use 'GHC.Conc.STM' -- instead. -- ===================================== libraries/base/Control/Exception/Base.hs ===================================== @@ -223,7 +223,7 @@ onException io what = io `catch` \e -> do _ <- what -- handle. Similarly, closing a socket (from \"network\" package) is also -- uninterruptible under similar conditions. An example of an interruptible -- action is 'killThread'. Completion of interruptible release actions can be --- ensured by wrapping them in in 'uninterruptibleMask_', but this risks making +-- ensured by wrapping them in 'uninterruptibleMask_', but this risks making -- the program non-responsive to @Control-C@, or timeouts. Another option is to -- run the release action asynchronously in its own thread: -- ===================================== libraries/base/Control/Monad.hs ===================================== @@ -101,11 +101,11 @@ import GHC.Num ( (-) ) -- -- ==== __Examples__ -- --- Common uses of 'guard' include conditionally signaling an error in +-- Common uses of 'guard' include conditionally signalling an error in -- an error monad and conditionally rejecting the current choice in an -- 'Alternative'-based parser. -- --- As an example of signaling an error in the error monad 'Maybe', +-- As an example of signalling an error in the error monad 'Maybe', -- consider a safe division function @safeDiv x y@ that returns -- 'Nothing' when the denominator @y@ is zero and @'Just' (x \`div\` -- y)@ otherwise. For example: ===================================== libraries/base/Data/Complex.hs ===================================== @@ -104,13 +104,13 @@ cis theta = cos theta :+ sin theta -- | The function 'polar' takes a complex number and -- returns a (magnitude, phase) pair in canonical form: --- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@; +-- the magnitude is non-negative, and the phase in the range @(-'pi', 'pi']@; -- if the magnitude is zero, then so is the phase. {-# SPECIALISE polar :: Complex Double -> (Double,Double) #-} polar :: (RealFloat a) => Complex a -> (a,a) polar z = (magnitude z, phase z) --- | The nonnegative magnitude of a complex number. +-- | The non-negative magnitude of a complex number. {-# SPECIALISE magnitude :: Complex Double -> Double #-} magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k ===================================== libraries/base/Data/List.hs ===================================== @@ -124,7 +124,7 @@ module Data.List , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/Data/OldList.hs ===================================== @@ -124,7 +124,7 @@ module Data.OldList , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/System/Environment.hs ===================================== @@ -19,9 +19,7 @@ module System.Environment ( getArgs, getProgName, -#if !defined(javascript_HOST_ARCH) executablePath, -#endif getExecutablePath, getEnv, lookupEnv, ===================================== libraries/base/System/Environment/ExecutablePath.hsc ===================================== @@ -18,9 +18,7 @@ module System.Environment.ExecutablePath ( getExecutablePath -##if !defined(javascript_HOST_ARCH) , executablePath -##endif ) where ##if defined(javascript_HOST_ARCH) @@ -28,6 +26,9 @@ module System.Environment.ExecutablePath getExecutablePath :: IO FilePath getExecutablePath = return "a.jsexe" +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing + ##else -- The imports are purposely kept completely disjoint to prevent edits @@ -47,6 +48,12 @@ import Data.List (isSuffixOf) import Foreign.C import Foreign.Marshal.Array import System.Posix.Internals +#elif defined(solaris2_HOST_OS) +import Control.Exception (catch, throw) +import Foreign.C +import Foreign.Marshal.Array +import System.IO.Error (isDoesNotExistError) +import System.Posix.Internals #elif defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) import Control.Exception (catch, throw) import Foreign.C @@ -101,7 +108,7 @@ getExecutablePath :: IO FilePath -- -- If the operating system provides a reliable way to determine the current -- executable, return the query action, otherwise return @Nothing at . The action --- is defined on FreeBSD, Linux, MacOS, NetBSD, and Windows. +-- is defined on FreeBSD, Linux, MacOS, NetBSD, Solaris, and Windows. -- -- Even where the query action is defined, there may be situations where no -- result is available, e.g. if the executable file was deleted while the @@ -171,9 +178,9 @@ executablePath = Just (fmap Just getExecutablePath `catch` f) | otherwise = throw e -------------------------------------------------------------------------------- --- Linux +-- Linux / Solaris -#elif defined(linux_HOST_OS) +#elif defined(linux_HOST_OS) || defined(solaris2_HOST_OS) foreign import ccall unsafe "readlink" c_readlink :: CString -> CString -> CSize -> IO CInt @@ -190,6 +197,7 @@ readSymbolicLink file = c_readlink s buf 4096 peekFilePathLen (buf,fromIntegral len) +# if defined(linux_HOST_OS) getExecutablePath = readSymbolicLink $ "/proc/self/exe" executablePath = Just (check <$> getExecutablePath) where @@ -200,6 +208,18 @@ executablePath = Just (check <$> getExecutablePath) where check s | "(deleted)" `isSuffixOf` s = Nothing | otherwise = Just s +# elif defined(solaris2_HOST_OS) +getExecutablePath = readSymbolicLink "/proc/self/path/a.out" + +executablePath = Just ((Just <$> getExecutablePath) `catch` f) + where + -- readlink(2) fails with ENOENT when the executable has been deleted, + -- even though the symlink itself still exists according to readdir(3). + f e | isDoesNotExistError e = pure Nothing + | otherwise = throw e + +#endif + -------------------------------------------------------------------------------- -- FreeBSD / NetBSD ===================================== libraries/base/Text/Read/Lex.hs ===================================== @@ -112,7 +112,7 @@ numberToFixed _ _ = Nothing -- space problems in #5688 -- Ways this is conservative: -- * the floatRange is in base 2, but we pretend it is in base 10 --- * we pad the floateRange a bit, just in case it is very small +-- * we pad the floatRange a bit, just in case it is very small -- and we would otherwise hit an edge case -- * We only worry about numbers that have an exponent. If they don't -- have an exponent then the Rational won't be much larger than the ===================================== libraries/ghc-boot/GHC/BaseDir.hs ===================================== @@ -12,7 +12,11 @@ -- installation location at build time. ghc-pkg also can expand those variables -- and so needs the top dir location to do that too. -module GHC.BaseDir where +module GHC.BaseDir + ( expandTopDir + , expandPathVar + , getBaseDir + ) where import Prelude -- See Note [Why do we import Prelude here?] @@ -20,11 +24,9 @@ import Data.List (stripPrefix) import Data.Maybe (listToMaybe) import System.FilePath --- Windows -#if defined(mingw32_HOST_OS) -import System.Environment (getExecutablePath) --- POSIX -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#if MIN_VERSION_base(4,17,0) +import System.Environment (executablePath) +#else import System.Environment (getExecutablePath) #endif @@ -43,17 +45,27 @@ expandPathVar var value str expandPathVar var value (x:xs) = x : expandPathVar var value xs expandPathVar _ _ [] = [] +#if !MIN_VERSION_base(4,17,0) +-- Polyfill for base-4.17 executablePath +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Just (Just <$> getExecutablePath) +#elif !MIN_VERSION_base(4,18,0) && defined(js_HOST_ARCH) +-- executablePath is missing from base < 4.18.0 on js_HOST_ARCH +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing +#endif + -- | Calculate the location of the base dir getBaseDir :: IO (Maybe String) #if defined(mingw32_HOST_OS) -getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath where -- locate the "base dir" when given the path -- to the real ghc executable (as opposed to symlink) -- that is running this function. rootDir :: FilePath -> FilePath rootDir = takeDirectory . takeDirectory . normalise -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#else -- on unix, this is a bit more confusing. -- The layout right now is something like -- @@ -65,14 +77,15 @@ getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath -- As such, we first need to find the absolute location to the -- binary. -- --- getExecutablePath will return (3). One takeDirectory will +-- executablePath will return (3). One takeDirectory will -- give use /lib/ghc-X.Y.Z/bin, and another will give us (4). -- -- This of course only works due to the current layout. If -- the layout is changed, such that we have ghc-X.Y.Z/{bin,lib} -- this would need to be changed accordingly. -- -getBaseDir = Just . (\p -> p "lib") . takeDirectory . takeDirectory <$> getExecutablePath -#else -getBaseDir = return Nothing +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath + where + rootDir :: FilePath -> FilePath + rootDir = takeDirectory . takeDirectory #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2de6d8747f7804b2bb5e421d858d8bd432f55cbe...9e083c0b704dc3c5574fcb5fce534fbdd43f3729 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2de6d8747f7804b2bb5e421d858d8bd432f55cbe...9e083c0b704dc3c5574fcb5fce534fbdd43f3729 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 17:31:54 2023 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Sun, 23 Apr 2023 13:31:54 -0400 Subject: [Git][ghc/ghc][wip/int-index/visibility-check] 50 commits: Add release note for GHC.Unicode refactor in base-4.18. Message-ID: <64456b8a536e7_178e7494dc4dc81046112@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/visibility-check at Glasgow Haskell Compiler / GHC Commits: 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - e606979a by Vladislav Zavialov at 2023-04-23T19:31:21+02:00 Ignore forall visibility in eqType (#22762) Prior to this change, the equality relation on types took ForAllTyFlag into account, making a distinction between: 1. forall a. blah 2. forall a -> blah Not anymore. This distinction is important in surface Haskell, but it has no meaning in Core where type abstraction and type application are always explicit. At the same time, if we are not careful to track this flag, Core Lint will fail, as reported in #22762: *** Core Lint errors : in result of TcGblEnv axioms *** From-kind of Cast differs from kind of enclosed type From-kind: forall (b :: Bool) -> * Kind of enclosed type: forall {b :: Bool}. * The solution is to compare types for equality modulo visibility (ForAllTyFlag). Updated functions: nonDetCmpType (worker for eqType) eqDeBruijnType tc_eq_type (worker for tcEqType) can_eq_nc In order to retain the distinction between visible and invisible forall in user-written code, we introduce a new ad-hoc check: checkEqForallVis. - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitmodules - cabal.project-reinstall - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Map/Type.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Compare.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e52ccbd3cc5879350548e455f5e910ffda2332ee...e606979aca878513a54ce3b0e26467e3c3496dd6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e52ccbd3cc5879350548e455f5e910ffda2332ee...e606979aca878513a54ce3b0e26467e3c3496dd6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 17:39:48 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 23 Apr 2023 13:39:48 -0400 Subject: [Git][ghc/ghc][master] Implement executablePath for Solaris and make getBaseDir less platform-dependent Message-ID: <64456d643f62c_178e74951039e410503fe@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 3 changed files: - libraries/base/System/Environment.hs - libraries/base/System/Environment/ExecutablePath.hsc - libraries/ghc-boot/GHC/BaseDir.hs Changes: ===================================== libraries/base/System/Environment.hs ===================================== @@ -19,9 +19,7 @@ module System.Environment ( getArgs, getProgName, -#if !defined(javascript_HOST_ARCH) executablePath, -#endif getExecutablePath, getEnv, lookupEnv, ===================================== libraries/base/System/Environment/ExecutablePath.hsc ===================================== @@ -18,9 +18,7 @@ module System.Environment.ExecutablePath ( getExecutablePath -##if !defined(javascript_HOST_ARCH) , executablePath -##endif ) where ##if defined(javascript_HOST_ARCH) @@ -28,6 +26,9 @@ module System.Environment.ExecutablePath getExecutablePath :: IO FilePath getExecutablePath = return "a.jsexe" +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing + ##else -- The imports are purposely kept completely disjoint to prevent edits @@ -47,6 +48,12 @@ import Data.List (isSuffixOf) import Foreign.C import Foreign.Marshal.Array import System.Posix.Internals +#elif defined(solaris2_HOST_OS) +import Control.Exception (catch, throw) +import Foreign.C +import Foreign.Marshal.Array +import System.IO.Error (isDoesNotExistError) +import System.Posix.Internals #elif defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) import Control.Exception (catch, throw) import Foreign.C @@ -101,7 +108,7 @@ getExecutablePath :: IO FilePath -- -- If the operating system provides a reliable way to determine the current -- executable, return the query action, otherwise return @Nothing at . The action --- is defined on FreeBSD, Linux, MacOS, NetBSD, and Windows. +-- is defined on FreeBSD, Linux, MacOS, NetBSD, Solaris, and Windows. -- -- Even where the query action is defined, there may be situations where no -- result is available, e.g. if the executable file was deleted while the @@ -171,9 +178,9 @@ executablePath = Just (fmap Just getExecutablePath `catch` f) | otherwise = throw e -------------------------------------------------------------------------------- --- Linux +-- Linux / Solaris -#elif defined(linux_HOST_OS) +#elif defined(linux_HOST_OS) || defined(solaris2_HOST_OS) foreign import ccall unsafe "readlink" c_readlink :: CString -> CString -> CSize -> IO CInt @@ -190,6 +197,7 @@ readSymbolicLink file = c_readlink s buf 4096 peekFilePathLen (buf,fromIntegral len) +# if defined(linux_HOST_OS) getExecutablePath = readSymbolicLink $ "/proc/self/exe" executablePath = Just (check <$> getExecutablePath) where @@ -200,6 +208,18 @@ executablePath = Just (check <$> getExecutablePath) where check s | "(deleted)" `isSuffixOf` s = Nothing | otherwise = Just s +# elif defined(solaris2_HOST_OS) +getExecutablePath = readSymbolicLink "/proc/self/path/a.out" + +executablePath = Just ((Just <$> getExecutablePath) `catch` f) + where + -- readlink(2) fails with ENOENT when the executable has been deleted, + -- even though the symlink itself still exists according to readdir(3). + f e | isDoesNotExistError e = pure Nothing + | otherwise = throw e + +#endif + -------------------------------------------------------------------------------- -- FreeBSD / NetBSD ===================================== libraries/ghc-boot/GHC/BaseDir.hs ===================================== @@ -12,7 +12,11 @@ -- installation location at build time. ghc-pkg also can expand those variables -- and so needs the top dir location to do that too. -module GHC.BaseDir where +module GHC.BaseDir + ( expandTopDir + , expandPathVar + , getBaseDir + ) where import Prelude -- See Note [Why do we import Prelude here?] @@ -20,11 +24,9 @@ import Data.List (stripPrefix) import Data.Maybe (listToMaybe) import System.FilePath --- Windows -#if defined(mingw32_HOST_OS) -import System.Environment (getExecutablePath) --- POSIX -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#if MIN_VERSION_base(4,17,0) +import System.Environment (executablePath) +#else import System.Environment (getExecutablePath) #endif @@ -43,17 +45,27 @@ expandPathVar var value str expandPathVar var value (x:xs) = x : expandPathVar var value xs expandPathVar _ _ [] = [] +#if !MIN_VERSION_base(4,17,0) +-- Polyfill for base-4.17 executablePath +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Just (Just <$> getExecutablePath) +#elif !MIN_VERSION_base(4,18,0) && defined(js_HOST_ARCH) +-- executablePath is missing from base < 4.18.0 on js_HOST_ARCH +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing +#endif + -- | Calculate the location of the base dir getBaseDir :: IO (Maybe String) #if defined(mingw32_HOST_OS) -getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath where -- locate the "base dir" when given the path -- to the real ghc executable (as opposed to symlink) -- that is running this function. rootDir :: FilePath -> FilePath rootDir = takeDirectory . takeDirectory . normalise -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#else -- on unix, this is a bit more confusing. -- The layout right now is something like -- @@ -65,14 +77,15 @@ getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath -- As such, we first need to find the absolute location to the -- binary. -- --- getExecutablePath will return (3). One takeDirectory will +-- executablePath will return (3). One takeDirectory will -- give use /lib/ghc-X.Y.Z/bin, and another will give us (4). -- -- This of course only works due to the current layout. If -- the layout is changed, such that we have ghc-X.Y.Z/{bin,lib} -- this would need to be changed accordingly. -- -getBaseDir = Just . (\p -> p "lib") . takeDirectory . takeDirectory <$> getExecutablePath -#else -getBaseDir = return Nothing +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath + where + rootDir :: FilePath -> FilePath + rootDir = takeDirectory . takeDirectory #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/499a1c202522d849d91300c92be5d5623a46d264 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/499a1c202522d849d91300c92be5d5623a46d264 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 17:40:25 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 23 Apr 2023 13:40:25 -0400 Subject: [Git][ghc/ghc][master] Fix doc typos in libraries/base Message-ID: <64456d89967e3_178e74951039d010538e9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 7 changed files: - libraries/base/Control/Concurrent/MVar.hs - libraries/base/Control/Exception/Base.hs - libraries/base/Control/Monad.hs - libraries/base/Data/Complex.hs - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/Text/Read/Lex.hs Changes: ===================================== libraries/base/Control/Concurrent/MVar.hs ===================================== @@ -37,7 +37,7 @@ -- than 'GHC.Conc.STM'. They are appropriate for building synchronization -- primitives and performing simple interthread communication; however -- they are very simple and susceptible to race conditions, deadlocks or --- uncaught exceptions. Do not use them if you need perform larger +-- uncaught exceptions. Do not use them if you need to perform larger -- atomic operations such as reading from multiple variables: use 'GHC.Conc.STM' -- instead. -- ===================================== libraries/base/Control/Exception/Base.hs ===================================== @@ -223,7 +223,7 @@ onException io what = io `catch` \e -> do _ <- what -- handle. Similarly, closing a socket (from \"network\" package) is also -- uninterruptible under similar conditions. An example of an interruptible -- action is 'killThread'. Completion of interruptible release actions can be --- ensured by wrapping them in in 'uninterruptibleMask_', but this risks making +-- ensured by wrapping them in 'uninterruptibleMask_', but this risks making -- the program non-responsive to @Control-C@, or timeouts. Another option is to -- run the release action asynchronously in its own thread: -- ===================================== libraries/base/Control/Monad.hs ===================================== @@ -101,11 +101,11 @@ import GHC.Num ( (-) ) -- -- ==== __Examples__ -- --- Common uses of 'guard' include conditionally signaling an error in +-- Common uses of 'guard' include conditionally signalling an error in -- an error monad and conditionally rejecting the current choice in an -- 'Alternative'-based parser. -- --- As an example of signaling an error in the error monad 'Maybe', +-- As an example of signalling an error in the error monad 'Maybe', -- consider a safe division function @safeDiv x y@ that returns -- 'Nothing' when the denominator @y@ is zero and @'Just' (x \`div\` -- y)@ otherwise. For example: ===================================== libraries/base/Data/Complex.hs ===================================== @@ -104,13 +104,13 @@ cis theta = cos theta :+ sin theta -- | The function 'polar' takes a complex number and -- returns a (magnitude, phase) pair in canonical form: --- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@; +-- the magnitude is non-negative, and the phase in the range @(-'pi', 'pi']@; -- if the magnitude is zero, then so is the phase. {-# SPECIALISE polar :: Complex Double -> (Double,Double) #-} polar :: (RealFloat a) => Complex a -> (a,a) polar z = (magnitude z, phase z) --- | The nonnegative magnitude of a complex number. +-- | The non-negative magnitude of a complex number. {-# SPECIALISE magnitude :: Complex Double -> Double #-} magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k ===================================== libraries/base/Data/List.hs ===================================== @@ -124,7 +124,7 @@ module Data.List , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/Data/OldList.hs ===================================== @@ -124,7 +124,7 @@ module Data.OldList , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/Text/Read/Lex.hs ===================================== @@ -112,7 +112,7 @@ numberToFixed _ _ = Nothing -- space problems in #5688 -- Ways this is conservative: -- * the floatRange is in base 2, but we pretend it is in base 10 --- * we pad the floateRange a bit, just in case it is very small +-- * we pad the floatRange a bit, just in case it is very small -- and we would otherwise hit an edge case -- * We only worry about numbers that have an exponent. If they don't -- have an exponent then the Rational won't be much larger than the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97a6f7bc5e2408d99c3ecdef85b7cc66ff994de3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97a6f7bc5e2408d99c3ecdef85b7cc66ff994de3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 17:41:33 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 23 Apr 2023 13:41:33 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Begin to implement c calling convention Message-ID: <64456dcd46c14_178e7495370ac410540f6@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: fef76fa5 by Sven Tennie at 2023-04-23T17:40:39+00:00 Begin to implement c calling convention - - - - - 5 changed files: - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs - compiler/GHC/CmmToAsm/RISCV64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -4,7 +4,7 @@ module GHC.CmmToAsm.RISCV64.CodeGen where import GHC.CmmToAsm.Types import GHC.CmmToAsm.Monad import GHC.CmmToAsm.RISCV64.Instr -import Prelude +import Prelude hiding ((<>)) import GHC.Cmm import GHC.Cmm.Utils import Control.Monad @@ -22,6 +22,7 @@ import GHC.CmmToAsm.RISCV64.Regs import GHC.Platform.Regs import GHC.Utils.Panic import GHC.Cmm.BlockId +import GHC.Utils.Trace -- | Don't try to compile all GHC Cmm files in the beginning. -- Ignore them. There's a flag to decide we really want to emit something. @@ -94,6 +95,8 @@ stmtToInstrs :: CmmNode e x -> NatM InstrBlock stmtToInstrs stmt = do platform <- getPlatform case stmt of + CmmUnsafeForeignCall target result_regs args + -> genCCall target result_regs args CmmComment s -> return (unitOL (COMMENT (ftext s))) -- TODO: Maybe, it would be nice to see the tick comment in assembly? CmmTick {} -> return nilOL @@ -129,6 +132,21 @@ getRegisterReg platform (CmmGlobal reg@(GlobalRegUse mid _)) Just reg -> RegReal reg Nothing -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal reg) +-- ----------------------------------------------------------------------------- +-- General things for putting together code sequences + +-- | The dual to getAnyReg: compute an expression into a register, but +-- we don't mind which one it is. +getSomeReg :: CmmExpr -> NatM (Reg, Format, InstrBlock) +getSomeReg expr = do + r <- getRegister expr + case r of + Any rep code -> do + tmp <- getNewRegNat rep + return (tmp, rep, code tmp) + Fixed rep reg code -> + return (reg, rep, code) + getRegister :: CmmExpr -> NatM Register getRegister e = do config <- getConfig @@ -140,13 +158,20 @@ getRegister' config plat expr = case expr of CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _)) -> pprPanic "getRegisterReg-memory" (ppr $ PicBaseReg) + CmmReg reg + -> return (Fixed (cmmTypeFormat (cmmRegType reg)) + (getRegisterReg plat reg) + nilOL) CmmLit lit -> case lit of - CmmInt i W64 -> do - return (Any (intFormat W64) (\dst -> unitOL $ annExpr expr (LI dst i))) + CmmInt i W64 -> + return (Any II64 (\dst -> unitOL $ annExpr expr (LI dst i))) CmmInt i w -> error ("TODO: getRegister' CmmInt " ++ show i ++ show w ++ " " ++show expr) + CmmLabel lbl -> + return (Any II64 (\dst -> unitOL $ annExpr expr (LA dst lbl))) e -> error ("TODO: getRegister' other " ++ show e) - e -> error ("TODO: getRegister'" ++ show e) + CmmRegOff reg off -> error $ "TODO: getRegister' : " ++ show reg ++ " , " ++ show off + e -> error ("TODO: getRegister' " ++ show e ++ " -- " ++ showPprUnsafe (pdoc plat e)) -- ----------------------------------------------------------------------------- -- Jumps @@ -201,3 +226,88 @@ annExpr e instr {- debugIsOn -} = ANN (text . show $ e) instr generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) generateJumpTableForInstr _ = Nothing +genCCall + :: ForeignTarget -- function to call + -> [CmmFormal] -- where to put the result + -> [CmmActual] -- arguments (of mixed type) + -> NatM InstrBlock +-- TODO: Specialize where we can. +-- Generic impl +genCCall target dest_regs arg_regs = do + -- we want to pass arg_regs into allArgRegs + -- pprTraceM "genCCall target" (ppr target) + -- pprTraceM "genCCall formal" (ppr dest_regs) + -- pprTraceM "genCCall actual" (ppr arg_regs) + + platform <- getPlatform + case target of + -- The target :: ForeignTarget call can either + -- be a foreign procedure with an address expr + -- and a calling convention. + ForeignTarget expr _cconv -> do + (call_target, call_target_code) <- case expr of + -- if this is a label, let's just directly to it. This will produce the + -- correct CALL relocation for BL... + (CmmLit (CmmLabel lbl)) -> pure (TLabel lbl, nilOL) + -- ... if it's not a label--well--let's compute the expression into a + -- register and jump to that. See Note [PLT vs GOT relocations] + e -> do + (reg, _format, reg_code) <- getSomeReg expr + pure (TReg reg, reg_code) + -- compute the code and register logic for all arg_regs. + -- this will give us the format information to match on. + arg_regs' <- mapM getSomeReg arg_regs + + -- Now this is stupid. Our Cmm expressions doesn't carry the proper sizes + -- so while in Cmm we might get W64 incorrectly for an int, that is W32 in + -- STG; this thenn breaks packing of stack arguments, if we need to pack + -- for the pcs, e.g. darwinpcs. Option one would be to fix the Int type + -- in Cmm proper. Option two, which we choose here is to use extended Hint + -- information to contain the size information and use that when packing + -- arguments, spilled onto the stack. + let (_res_hints, arg_hints) = foreignTargetHints target + arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints + + (stackSpace, passRegs, passArgumentsCode) <- passArguments allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL + + (returnRegs, readResultsCode) <- readResults allGpArgRegs allFpArgRegs dest_regs [] nilOL + + let moveStackDown 0 = toOL [ PUSH_STACK_FRAME + , DELTA (-16) ] + moveStackDown i = error $ "TODO: moveStackDown " ++ show i +-- moveStackDown i | odd i = moveStackDown (i + 1) +-- moveStackDown i = toOL [ PUSH_STACK_FRAME +-- , SUB (OpReg W64 (regSingle 31)) (OpReg W64 (regSingle 31)) (OpImm (ImmInt (8 * i))) +-- , DELTA (-8 * i - 16) ] + moveStackUp 0 = toOL [ POP_STACK_FRAME + , DELTA 0 ] + moveStackUp i = error $ "TODO: moveStackUp " ++ show i +-- moveStackUp i | odd i = moveStackUp (i + 1) +-- moveStackUp i = toOL [ ADD (OpReg W64 (regSingle 31)) (OpReg W64 (regSingle 31)) (OpImm (ImmInt (8 * i))) +-- , POP_STACK_FRAME +-- , DELTA 0 ] + + let code = call_target_code -- compute the label (possibly into a register) + `appOL` moveStackDown (stackSpace `div` 8) + `appOL` passArgumentsCode -- put the arguments into x0, ... + `appOL` (unitOL $ J call_target) -- jump + `appOL` readResultsCode -- parse the results into registers + `appOL` moveStackUp (stackSpace `div` 8) + return code + e -> error $ "TODO genCCall" ++ showSDocUnsafe (pdoc platform e) + where + passArguments :: [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock) + passArguments _ _ [] stackSpace accumRegs accumCode = return (stackSpace, accumRegs, accumCode) + passArguments (gpReg:gpRegs) fpRegs ((r, format, hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do + let w = formatToWidth format + mov = MV gpReg r + accumCode' = accumCode `appOL` + code_r `snocOL` + ann (text "Pass gp argument: " <> ppr r) mov + passArguments gpRegs fpRegs args stackSpace (gpReg:accumRegs) accumCode' + passArguments _ _ _ _ _ _ = error $ "TODO: passArguments" + + + readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg]-> InstrBlock -> NatM ([Reg], InstrBlock) + readResults _ _ [] accumRegs accumCode = return (accumRegs, accumCode) + readResults _ _ _ _ _ = error $ "TODO: readResults" ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -1,19 +1,20 @@ {-# LANGUAGE EmptyCase #-} + module GHC.CmmToAsm.RISCV64.Instr where import GHC.Cmm import GHC.Cmm.BlockId +import GHC.Cmm.CLabel import GHC.Cmm.Dataflow.Label import GHC.CmmToAsm.Config -import GHC.CmmToAsm.Instr hiding (patchRegsOfInstr, takeDeltaInstr, regUsageOfInstr, isMetaInstr, jumpDestsOfInstr) +import GHC.CmmToAsm.Instr hiding (isMetaInstr, jumpDestsOfInstr, patchRegsOfInstr, regUsageOfInstr, takeDeltaInstr) import GHC.CmmToAsm.Types import GHC.Platform import GHC.Platform.Reg +import GHC.Platform.Regs (freeReg) import GHC.Types.Unique.Supply import GHC.Utils.Outputable import Prelude -import GHC.Platform.Regs (freeReg) -import GHC.Cmm.CLabel data Instr = -- comment pseudo-op @@ -21,10 +22,11 @@ data Instr | MULTILINE_COMMENT SDoc | -- Annotated instruction. Should print # ANN SDoc Instr - -- specify current stack offset for + | -- specify current stack offset for -- benefit of subsequent passes - | DELTA Int - + DELTA Int + | PUSH_STACK_FRAME + | POP_STACK_FRAME | -- some static data spat out during code -- generation. Will be extracted before -- pretty-printing. @@ -36,12 +38,17 @@ data Instr NEWBLOCK BlockId | -- load immediate pseudo-instruction LI Reg Integer + | -- load address (label) + LA Reg CLabel | -- jump pseudo-instruction J Target + | -- copy register + MV Reg Reg data Target - = TBlock BlockId - | TLabel CLabel + = TBlock BlockId + | TReg Reg + | TLabel CLabel allocMoreStack :: Int -> @@ -60,10 +67,12 @@ spillSlotSize = 8 -- | The number of spill slots available without allocating more. maxSpillSlots :: NCGConfig -> Int -maxSpillSlots config --- = 0 -- set to zero, to see when allocMoreStack has to fire. - = ((ncgSpillPreallocSize config - stackFrameHeaderSize) - `div` spillSlotSize) - 1 +maxSpillSlots config = + -- = 0 -- set to zero, to see when allocMoreStack has to fire. + ( (ncgSpillPreallocSize config - stackFrameHeaderSize) + `div` spillSlotSize + ) + - 1 makeFarBranches :: LabelMap RawCmmStatics -> @@ -81,27 +90,33 @@ regUsageOfInstr :: Instr -> RegUsage regUsageOfInstr platform instr = case instr of - ANN _ i -> regUsageOfInstr platform i - COMMENT{} -> usage ([], []) - MULTILINE_COMMENT{} -> usage ([], []) - LDATA{} -> usage ([], []) - DELTA{} -> usage ([], []) - NEWBLOCK{} -> usage ([], []) - LI reg _ -> usage ([], [reg]) - -- Looks like J doesn't change registers (beside PC) - -- This might be wrong. - J{} -> usage ([], []) + ANN _ i -> regUsageOfInstr platform i + COMMENT {} -> none + MULTILINE_COMMENT {} -> none + LDATA {} -> none + DELTA {} -> none + NEWBLOCK {} -> none + PUSH_STACK_FRAME -> none + POP_STACK_FRAME -> none + LI dst _ -> usage ([], [dst]) + LA dst _ -> usage ([], [dst]) + MV dst src -> usage ([src], [dst]) + -- Looks like J doesn't change registers (beside PC) + -- This might be wrong. + J {} -> none where - -- filtering the usage is necessary, otherwise the register - -- allocator will try to allocate pre-defined fixed stg - -- registers as well, as they show up. - usage (src, dst) = RU (filter (interesting platform) src) - (filter (interesting platform) dst) - - interesting :: Platform -> Reg -> Bool - interesting _ (RegVirtual _) = True - interesting platform (RegReal (RealRegSingle i)) = freeReg platform i + none = usage ([], []) + -- filtering the usage is necessary, otherwise the register + -- allocator will try to allocate pre-defined fixed stg + -- registers as well, as they show up. + usage (src, dst) = + RU + (filter (interesting platform) src) + (filter (interesting platform) dst) + interesting :: Platform -> Reg -> Bool + interesting _ (RegVirtual _) = True + interesting platform (RegReal (RealRegSingle i)) = freeReg platform i -- | Apply a given mapping to all the register references in this -- instruction. @@ -110,22 +125,25 @@ patchRegsOfInstr :: (Reg -> Reg) -> Instr patchRegsOfInstr instr env = case instr of - ANN _ i -> patchRegsOfInstr i env - COMMENT{} -> instr - MULTILINE_COMMENT{} -> instr - LDATA{} -> instr - DELTA{} -> instr - NEWBLOCK{} -> instr - LI reg i -> LI (env reg) i - -- Looks like J doesn't change registers (beside PC) - -- This might be wrong. - J{} -> instr - + ANN _ i -> patchRegsOfInstr i env + COMMENT {} -> instr + MULTILINE_COMMENT {} -> instr + LDATA {} -> instr + DELTA {} -> instr + NEWBLOCK {} -> instr + PUSH_STACK_FRAME {} -> instr + POP_STACK_FRAME {} -> instr + LI reg i -> LI (env reg) i + LA reg i -> LA (env reg) i + -- Looks like J doesn't change registers (beside PC) + -- This might be wrong. + J {} -> instr + MV dst src -> MV (env dst) (env src) -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the -- register allocator needs to worry about. -isJumpishInstr :: Instr -> Bool +isJumpishInstr :: Instr -> Bool isJumpishInstr COMMENT {} = False isJumpishInstr MULTILINE_COMMENT {} = False isJumpishInstr ANN {} = False @@ -135,7 +153,6 @@ isJumpishInstr NEWBLOCK {} = False isJumpishInstr LI {} = False isJumpishInstr J {} = True - -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the -- register allocator needs to worry about. @@ -183,8 +200,7 @@ mkLoadInstr _ _ _ _ = error "TODO: mkLoadInstr" takeDeltaInstr :: Instr -> Maybe Int takeDeltaInstr (ANN _ i) = takeDeltaInstr i takeDeltaInstr (DELTA i) = Just i -takeDeltaInstr _ = Nothing - +takeDeltaInstr _ = Nothing -- | Check whether this instruction is some meta thing inserted into -- the instruction stream for other purposes. @@ -194,16 +210,20 @@ takeDeltaInstr _ = Nothing -- -- eg, comments, delta, ldata, etc. isMetaInstr :: Instr -> Bool -isMetaInstr instr - = case instr of - ANN _ i -> isMetaInstr i - COMMENT{} -> True - MULTILINE_COMMENT{} -> True - LDATA{} -> True - NEWBLOCK{} -> True - LI{} -> False - J{} -> False - +isMetaInstr instr = + case instr of + ANN _ i -> isMetaInstr i + COMMENT {} -> True + MULTILINE_COMMENT {} -> True + LDATA {} -> True + NEWBLOCK {} -> True + DELTA {} -> True + PUSH_STACK_FRAME -> True + POP_STACK_FRAME -> True + LI {} -> False + LA {} -> False + J {} -> False + MV {} -> False -- | Copy the value in a register to another one. -- Must work for all register classes. @@ -225,8 +245,12 @@ takeRegRegMoveInstr ANN {} = Nothing takeRegRegMoveInstr DELTA {} = Nothing takeRegRegMoveInstr LDATA {} = Nothing takeRegRegMoveInstr NEWBLOCK {} = Nothing +takeRegRegMoveInstr PUSH_STACK_FRAME {} = Nothing +takeRegRegMoveInstr POP_STACK_FRAME {} = Nothing takeRegRegMoveInstr LI {} = Nothing +takeRegRegMoveInstr LA {} = Nothing takeRegRegMoveInstr J {} = Nothing +takeRegRegMoveInstr (MV dst src) = Just (src, dst) -- | Make an unconditional jump instruction. -- For architectures with branch delay slots, its ok to put ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -21,8 +21,8 @@ import GHC.Utils.Panic import GHC.Types.Unique pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc -pprNatCmmDecl config (CmmData _ _) = error "TODO: pprNatCmmDecl " - +pprNatCmmDecl config (CmmData section dats) = + pprSectionAlign config section $$ pprDatas config dats pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = let platform = ncgPlatform config in pprProcAlignment config @@ -116,6 +116,18 @@ pprBasicBlock config info_env (BasicBlock blockid instrs) = Nothing -> c Just (CmmStaticsRaw info_lbl info) -> error "pprBasicBlock" +pprDatas :: IsDoc doc => NCGConfig -> RawCmmStatics -> doc +-- TODO: Adhere to Note [emit-time elimination of static indirections] +-- See AArch64/Ppr.hs +pprDatas config (CmmStaticsRaw lbl dats) + = vcat (pprLabel platform lbl : map (pprData config) dats) + where + platform = ncgPlatform config + +pprData :: IsDoc doc => NCGConfig -> CmmStatic -> doc +pprData _config (CmmString str) = line (pprString str) +pprData _ _ = error $ "TODO: pprData" + pprInstr :: IsDoc doc => Platform -> Instr -> doc pprInstr platform instr = case instr of -- Meta Instructions --------------------------------------------------------- ===================================== compiler/GHC/CmmToAsm/RISCV64/Regs.hs ===================================== @@ -10,6 +10,12 @@ import GHC.Platform.Regs allMachRegNos :: [RegNo] allMachRegNos = [1..31] ++ [32..63] +-- argRegs is the set of regs which are read for an n-argument call to C. +allGpArgRegs :: [Reg] +allGpArgRegs = map regSingle [10..17] -- a0..a7 +allFpArgRegs :: [Reg] +allFpArgRegs = map regSingle [42..49] -- fa0..fa7 + -- allocatableRegs is allMachRegNos with the fixed-use regs removed. -- i.e., these are the regs for which we are prepared to allow the -- register allocator to attempt to map VRegs to. ===================================== compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs ===================================== @@ -64,6 +64,6 @@ initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs pla releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs releaseReg (RealRegSingle r) (FreeRegs g f) | r > 31 && testBit f (r - 32) = pprPanic "Linear.RISCV64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32)) - | r < 32 && testBit g r = pprPanic "Linear.RISCV64.releaseReg" (text "can't release non-allocated reg x" <> int r) + | r < 32 && testBit g r = pprPanic "Linear.RISCV64.releaseReg" (text "can't release non-allocated reg x" <> int r <+> text (showBits g)) | r > 31 = FreeRegs g (setBit f (r - 32)) | otherwise = FreeRegs (setBit g r) f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fef76fa57edb5f6e6929e457a1834c092ffd8004 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fef76fa57edb5f6e6929e457a1834c092ffd8004 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 18:04:03 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Sun, 23 Apr 2023 14:04:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/forall-vis-coercions Message-ID: <64457313aa6f3_178e7495e356d0105969e@gitlab.mail> Matthew Craven pushed new branch wip/forall-vis-coercions at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/forall-vis-coercions You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 23 18:21:26 2023 From: gitlab at gitlab.haskell.org (Matthew Craven (@clyring)) Date: Sun, 23 Apr 2023 14:21:26 -0400 Subject: [Git][ghc/ghc][wip/forall-vis-coercions] revert temporary renamings of the forallco constructors Message-ID: <64457726c5493_178e749624c958106308a@gitlab.mail> Matthew Craven pushed to branch wip/forall-vis-coercions at Glasgow Haskell Compiler / GHC Commits: d7f95d4a by Matthew Craven at 2023-04-23T14:20:33-04:00 revert temporary renamings of the forallco constructors - - - - - 17 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -169,6 +169,7 @@ import Control.Monad (foldM, zipWithM) import Data.Function ( on ) import Data.Char( isDigit ) import qualified Data.Monoid as Monoid +import Control.DeepSeq {- %************************************************************************ @@ -556,18 +557,18 @@ splitFunCo_maybe (FunCo { fco_arg = arg, fco_res = res }) = Just (arg, res) splitFunCo_maybe _ = Nothing splitForAllCo_maybe :: Coercion -> Maybe (TyCoVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion) -splitForAllCo_maybe (ForAllCoX tv vL vR k_co co) = Just (tv, vL, vR, k_co, co) +splitForAllCo_maybe (ForAllCo tv vL vR k_co co) = Just (tv, vL, vR, k_co, co) splitForAllCo_maybe _ = Nothing -- | Like 'splitForAllCo_maybe', but only returns Just for tyvar binder splitForAllCo_ty_maybe :: Coercion -> Maybe (TyVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion) -splitForAllCo_ty_maybe (ForAllCoX tv vL vR k_co co) +splitForAllCo_ty_maybe (ForAllCo tv vL vR k_co co) | isTyVar tv = Just (tv, vL, vR, k_co, co) splitForAllCo_ty_maybe _ = Nothing -- | Like 'splitForAllCo_maybe', but only returns Just for covar binder splitForAllCo_co_maybe :: Coercion -> Maybe (CoVar, ForAllTyFlag, ForAllTyFlag, Coercion, Coercion) -splitForAllCo_co_maybe (ForAllCoX cv vL vR k_co co) +splitForAllCo_co_maybe (ForAllCo cv vL vR k_co co) | isCoVar cv = Just (cv, vL, vR, k_co, co) splitForAllCo_co_maybe _ = Nothing @@ -966,7 +967,7 @@ mkForAllCo v visL visR kind_co co , visL `eqForAllVis` visR = mkReflCo r (mkTyCoForAllTy v visL ty) | otherwise - = ForAllCoX v visL visR kind_co co + = ForAllCo v visL visR kind_co co -- | Like 'mkForAllCo', but the inner coercion shouldn't be an obvious -- reflexive coercion. For example, it is guaranteed in 'mkForAllCos'. @@ -981,7 +982,7 @@ mkForAllCo_NoRefl v visL visR kind_co co = mkFunCoNoFTF (coercionRole co) (multToCo ManyTy) kind_co co -- Functions from coercions are always unrestricted | otherwise - = ForAllCoX v visL visR kind_co co + = ForAllCo v visL visR kind_co co -- | Make nested ForAllCos, with 'Specified' visibility mkForAllCos :: [(TyCoVar, CoercionN)] -> Coercion -> Coercion @@ -1165,7 +1166,7 @@ mkSelCo_maybe cs co | Just (ty, r) <- isReflCo_maybe co = Just (mkReflCo r (getNthFromType cs ty)) - go SelForAll (ForAllCoX _ _ _ kind_co _) + go SelForAll (ForAllCo _ _ _ kind_co _) = Just kind_co -- If co :: (forall a1:k1. t1) ~ (forall a2:k2. t2) -- then (nth SelForAll co :: k1 ~N k2) @@ -1233,7 +1234,7 @@ mkLRCo lr co -- | Instantiates a 'Coercion'. mkInstCo :: Coercion -> CoercionN -> Coercion -mkInstCo (ForAllCoX tcv _visL _visR _kind_co body_co) co +mkInstCo (ForAllCo tcv _visL _visR _kind_co body_co) co | Just (arg, _) <- isReflCo_maybe co -- works for both tyvar and covar = substCoUnchecked (zipTCvSubst [tcv] [arg]) body_co @@ -1385,9 +1386,9 @@ setNominalRole_maybe r co = TransCo <$> setNominalRole_maybe_helper co1 <*> setNominalRole_maybe_helper co2 setNominalRole_maybe_helper (AppCo co1 co2) = AppCo <$> setNominalRole_maybe_helper co1 <*> pure co2 - setNominalRole_maybe_helper (ForAllCoX tv visL visR kind_co co) + setNominalRole_maybe_helper (ForAllCo tv visL visR kind_co co) | visL `eqForAllVis` visR - = ForAllCoX tv visL visR kind_co <$> setNominalRole_maybe_helper co + = ForAllCo tv visL visR kind_co <$> setNominalRole_maybe_helper co setNominalRole_maybe_helper (SelCo n co) -- NB, this case recurses via setNominalRole_maybe, not -- setNominalRole_maybe_helper! @@ -1498,11 +1499,11 @@ promoteCoercion co = case co of | otherwise -> mkKindCo co - ForAllCoX tv _ _ _ g + ForAllCo tv _ _ _ g | isTyVar tv -> promoteCoercion g - ForAllCoX {} + ForAllCo {} -- Is it possible to make a tricky coercion with type -- "forall {covar}. ty ~R# forall covar -> ty"? Probably not; -- forall-covar-types are still very internal-ish and limited. @@ -2328,7 +2329,7 @@ seqCo (Refl ty) = seqType ty seqCo (GRefl r ty mco) = r `seq` seqType ty `seq` seqMCo mco seqCo (TyConAppCo r tc cos) = r `seq` tc `seq` seqCos cos seqCo (AppCo co1 co2) = seqCo co1 `seq` seqCo co2 -seqCo (ForAllCoX tv visL visR k co) = seqType (varType tv) `seq` +seqCo (ForAllCo tv visL visR k co) = seqType (varType tv) `seq` rnf visL `seq` rnf visR `seq` seqCo k `seq` seqCo co seqCo (FunCo r af1 af2 w co1 co2) = r `seq` af1 `seq` af2 `seq` @@ -2395,7 +2396,7 @@ coercionLKind co go (GRefl _ ty _) = ty go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos) go (AppCo co1 co2) = mkAppTy (go co1) (go co2) - go (ForAllCoX tv1 visL _ _ co1) = mkTyCoForAllTy tv1 visL (go co1) + go (ForAllCo tv1 visL _ _ co1) = mkTyCoForAllTy tv1 visL (go co1) go (FunCo { fco_afl = af, fco_mult = mult, fco_arg = arg, fco_res = res}) {- See Note [FunCo] -} = FunTy { ft_af = af, ft_mult = go mult , ft_arg = go arg, ft_res = go res } @@ -2474,7 +2475,7 @@ coercionRKind co go (AxiomRuleCo ax cos) = pSnd $ expectJust "coercionKind" $ coaxrProves ax $ map coercionKind cos - go co@(ForAllCoX tv1 _visL visR k_co co1) -- works for both tyvar and covar + go co@(ForAllCo tv1 _visL visR k_co co1) -- works for both tyvar and covar | isGReflCo k_co = mkTyCoForAllTy tv1 visR (go co1) -- kind_co always has kind @Type@, thus @isGReflCo@ | otherwise = go_forall empty_subst co @@ -2498,7 +2499,7 @@ coercionRKind co go_app (InstCo co arg) args = go_app co (go arg:args) go_app co args = piResultTys (go co) args - go_forall subst (ForAllCoX tv1 _visL visR k_co co) + go_forall subst (ForAllCo tv1 _visL visR k_co co) -- See Note [Nested ForAllCos] | isTyVar tv1 = mkForAllTy (Bndr tv2 visR) (go_forall subst' co) @@ -2510,7 +2511,7 @@ coercionRKind co | otherwise = extendTvSubst (extendSubstInScope subst tv2) tv1 $ TyVarTy tv2 `mkCastTy` mkSymCo k_co - go_forall subst (ForAllCoX cv1 _visL visR k_co co) + go_forall subst (ForAllCo cv1 _visL visR k_co co) | isCoVar cv1 = mkTyCoForAllTy cv2 visR (go_forall subst' co) where @@ -2564,7 +2565,7 @@ coercionRole = go go (GRefl r _ _) = r go (TyConAppCo r _ _) = r go (AppCo co1 _) = go co1 - go (ForAllCoX _tcv _visL _visR _kco co) = go co + go (ForAllCo _tcv _visL _visR _kco co) = go co go (FunCo { fco_role = r }) = r go (CoVarCo cv) = coVarRole cv go (HoleCo h) = coVarRole (coHoleCoVar h) ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -291,7 +291,7 @@ opt_co4 env sym rep r (AppCo co1 co2) = mkAppCo (opt_co4_wrap env sym rep r co1) (opt_co4_wrap env sym False Nominal co2) -opt_co4 env sym rep r (ForAllCoX tv visL visR k_co co) +opt_co4 env sym rep r (ForAllCo tv visL visR k_co co) = case optForAllCoBndr env sym tv k_co of (env', tv', k_co') -> mkForAllCo tv' visL visR k_co' $ opt_co4_wrap env' sym rep r co @@ -377,7 +377,7 @@ opt_co4 env sym rep r (SelCo (SelTyCon n r1) (TyConAppCo _ _ cos)) opt_co4 env sym rep r (SelCo (SelFun fs) (FunCo _r2 _afl _afr w co1 co2)) = opt_co4_wrap env sym rep r (getNthFun fs w co1 co2) -opt_co4 env sym rep _ (SelCo SelForAll (ForAllCoX _ _ _ eta _)) +opt_co4 env sym rep _ (SelCo SelForAll (ForAllCo _ _ _ eta _)) -- works for both tyvar and covar = opt_co4_wrap env sym rep Nominal eta @@ -385,7 +385,7 @@ opt_co4 env sym rep r (SelCo n co) | Just nth_co <- case (co', n) of (TyConAppCo _ _ cos, SelTyCon n _) -> Just (cos `getNth` n) (FunCo _ _ _ w co1 co2, SelFun fs) -> Just (getNthFun fs w co1 co2) - (ForAllCoX _ _ _ eta _, SelForAll) -> Just eta + (ForAllCo _ _ _ eta _, SelForAll) -> Just eta _ -> Nothing = if rep && (r == Nominal) -- keep propagating the SubCo ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -386,7 +386,7 @@ orphNamesOfCo (Refl ty) = orphNamesOfType ty orphNamesOfCo (GRefl _ ty mco) = orphNamesOfType ty `unionNameSet` orphNamesOfMCo mco orphNamesOfCo (TyConAppCo _ tc cos) = unitNameSet (getName tc) `unionNameSet` orphNamesOfCos cos orphNamesOfCo (AppCo co1 co2) = orphNamesOfCo co1 `unionNameSet` orphNamesOfCo co2 -orphNamesOfCo (ForAllCoX _tcv _vL _vR kind_co co) = orphNamesOfCo kind_co +orphNamesOfCo (ForAllCo _tcv _vL _vR kind_co co) = orphNamesOfCo kind_co `unionNameSet` orphNamesOfCo co orphNamesOfCo (FunCo { fco_mult = co_mult, fco_arg = co1, fco_res = co2 }) = orphNamesOfCo co_mult ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2222,7 +2222,7 @@ lintCoercion co@(AppCo co1 co2) ; return (AppCo co1' co2') } ---------- -lintCoercion co@(ForAllCoX tcv visL visR kind_co body_co) +lintCoercion co@(ForAllCo tcv visL visR kind_co body_co) | not (isTyCoVar tcv) = failWithL (text "Non tyco binder in ForAllCo:" <+> ppr co) | otherwise @@ -2253,7 +2253,7 @@ lintCoercion co@(ForAllCoX tcv visL visR kind_co body_co) lintL (visL `eqForAllVis` visR) $ text "Nominal ForAllCo has mismatched visibilities: " <+> ppr co - ; return (ForAllCoX tcv' visL visR kind_co' body_co') } } + ; return (ForAllCo tcv' visL visR kind_co' body_co') } } lintCoercion co@(FunCo { fco_role = r, fco_afl = afl, fco_afr = afr , fco_mult = cow, fco_arg = co1, fco_res = co2 }) ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -631,7 +631,7 @@ tyCoFVsOfCo (GRefl _ ty mco) fv_cand in_scope acc tyCoFVsOfCo (TyConAppCo _ _ cos) fv_cand in_scope acc = tyCoFVsOfCos cos fv_cand in_scope acc tyCoFVsOfCo (AppCo co arg) fv_cand in_scope acc = (tyCoFVsOfCo co `unionFV` tyCoFVsOfCo arg) fv_cand in_scope acc -tyCoFVsOfCo (ForAllCoX tv _visL _visR kind_co co) fv_cand in_scope acc +tyCoFVsOfCo (ForAllCo tv _visL _visR kind_co co) fv_cand in_scope acc = (tyCoFVsVarBndr tv (tyCoFVsOfCo co) `unionFV` tyCoFVsOfCo kind_co) fv_cand in_scope acc tyCoFVsOfCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) fv_cand in_scope acc = (tyCoFVsOfCo co1 `unionFV` tyCoFVsOfCo co2 `unionFV` tyCoFVsOfCo w) fv_cand in_scope acc @@ -686,7 +686,7 @@ almost_devoid_co_var_of_co (TyConAppCo _ _ cos) cv almost_devoid_co_var_of_co (AppCo co arg) cv = almost_devoid_co_var_of_co co cv && almost_devoid_co_var_of_co arg cv -almost_devoid_co_var_of_co (ForAllCoX v _visL _visR kind_co co) cv +almost_devoid_co_var_of_co (ForAllCo v _visL _visR kind_co co) cv = almost_devoid_co_var_of_co kind_co cv && (v == cv || almost_devoid_co_var_of_co co cv) almost_devoid_co_var_of_co (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 }) cv @@ -1109,7 +1109,7 @@ tyConsOfType ty go_co (GRefl _ ty mco) = go ty `unionUniqSets` go_mco mco go_co (TyConAppCo _ tc args) = go_tc tc `unionUniqSets` go_cos args go_co (AppCo co arg) = go_co co `unionUniqSets` go_co arg - go_co (ForAllCoX _ _ _ kind_co co) = go_co kind_co `unionUniqSets` go_co co + go_co (ForAllCo _ _ _ kind_co co) = go_co kind_co `unionUniqSets` go_co co go_co (FunCo { fco_mult = m, fco_arg = a, fco_res = r }) = go_co m `unionUniqSets` go_co a `unionUniqSets` go_co r go_co (AxiomInstCo ax _ args) = go_ax ax `unionUniqSets` go_cos args @@ -1293,14 +1293,14 @@ occCheckExpand vs_to_avoid ty go_co cxt (AppCo co arg) = do { co' <- go_co cxt co ; arg' <- go_co cxt arg ; return (AppCo co' arg') } - go_co cxt@(as, env) (ForAllCoX tv visL visR kind_co body_co) + go_co cxt@(as, env) (ForAllCo tv visL visR kind_co body_co) = do { kind_co' <- go_co cxt kind_co ; let tv' = setVarType tv $ coercionLKind kind_co' env' = extendVarEnv env tv tv' as' = as `delVarSet` tv ; body' <- go_co (as', env') body_co - ; return (ForAllCoX tv' visL visR kind_co' body') } + ; return (ForAllCo tv' visL visR kind_co' body') } go_co cxt co@(FunCo { fco_mult = w, fco_arg = co1 ,fco_res = co2 }) = do { co1' <- go_co cxt co1 ; co2' <- go_co cxt co2 ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -850,7 +850,7 @@ data Coercion -- AppCo :: e -> N -> e -- See Note [Forall coercions] - | ForAllCoX + | ForAllCo TyCoVar !ForAllTyFlag -- visibility of coercionLKind !ForAllTyFlag -- visibility of coercionRKind @@ -1757,7 +1757,7 @@ foldTyCo (TyCoFolder { tcf_view = view go_co env (FunCo { fco_mult = cw, fco_arg = c1, fco_res = c2 }) = go_co env cw `mappend` go_co env c1 `mappend` go_co env c2 - go_co env (ForAllCoX tv _vis1 _vis2 kind_co co) + go_co env (ForAllCo tv _vis1 _vis2 kind_co co) = go_co env kind_co `mappend` go_ty env (varType tv) `mappend` go_co env' co where @@ -1812,7 +1812,7 @@ coercionSize (GRefl _ ty MRefl) = typeSize ty coercionSize (GRefl _ ty (MCo co)) = 1 + typeSize ty + coercionSize co coercionSize (TyConAppCo _ _ args) = 1 + sum (map coercionSize args) coercionSize (AppCo co arg) = coercionSize co + coercionSize arg -coercionSize (ForAllCoX _ _ _ h co) = 1 + coercionSize co + coercionSize h +coercionSize (ForAllCo _ _ _ h co) = 1 + coercionSize co + coercionSize h coercionSize (FunCo _ _ _ w c1 c2) = 1 + coercionSize c1 + coercionSize c2 + coercionSize w coercionSize (CoVarCo _) = 1 ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -889,7 +889,7 @@ subst_co subst co go (TyConAppCo r tc args)= let args' = map go args in args' `seqList` mkTyConAppCo r tc args' go (AppCo co arg) = (mkAppCo $! go co) $! go arg - go (ForAllCoX tv visL visR kind_co co) + go (ForAllCo tv visL visR kind_co co) = case substForAllCoBndrUnchecked subst tv kind_co of (subst', tv', kind_co') -> ((mkForAllCo $! tv') visL visR $! kind_co') $! subst_co subst' co ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -228,8 +228,8 @@ tidyCo env@(_, subst) co go (GRefl r ty mco) = (GRefl r $! tidyType env ty) $! go_mco mco go (TyConAppCo r tc cos) = TyConAppCo r tc $! strictMap go cos go (AppCo co1 co2) = (AppCo $! go co1) $! go co2 - go (ForAllCoX tv visL visR h co) - = ((((ForAllCoX $! tvp) $! visL) $! visR) $! (go h)) $! (tidyCo envp co) + go (ForAllCo tv visL visR h co) + = ((((ForAllCo $! tvp) $! visL) $! visR) $! (go h)) $! (tidyCo envp co) where (envp, tvp) = tidyVarBndr env tv -- the case above duplicates a bit of work in tidying h and the kind -- of tv. But the alternative is to use coercionKind, which seems worse. ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -547,7 +547,7 @@ expandTypeSynonyms ty = mkTyConAppCo r tc (map (go_co subst) args) go_co subst (AppCo co arg) = mkAppCo (go_co subst co) (go_co subst arg) - go_co subst (ForAllCoX tv visL visR kind_co co) + go_co subst (ForAllCo tv visL visR kind_co co) = let (subst', tv', kind_co') = go_cobndr subst tv kind_co in mkForAllCo tv' visL visR kind_co' (go_co subst' co) go_co subst (FunCo r afl afr w co1 co2) @@ -988,7 +988,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar | otherwise = mkTyConAppCo r tc <$> go_cos env cos - go_co env (ForAllCoX tv visL visR kind_co co) + go_co env (ForAllCo tv visL visR kind_co co) = do { kind_co' <- go_co env kind_co ; (env', tv') <- tycobinder env tv visL ; co' <- go_co env' co ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -1673,7 +1673,7 @@ ty_co_match menv subst (FunTy { ft_mult = w, ft_arg = ty1, ft_res = ty2 }) -- not doing so caused #21205. ty_co_match menv subst (ForAllTy (Bndr tv1 vis1t) ty1) - (ForAllCoX tv2 vis1c vis2c kind_co2 co2) + (ForAllCo tv2 vis1c vis2c kind_co2 co2) lkco rkco | isTyVar tv1 && isTyVar tv2 , vis1t == vis1c && vis1c == vis2c -- Is this necessary? @@ -1777,7 +1777,7 @@ pushRefl co = Just (TyConApp tc tys, r) -> Just (TyConAppCo r tc (zipWith mkReflCo (tyConRoleListX r tc) tys)) Just (ForAllTy (Bndr tv vis) ty, r) - -> Just (ForAllCoX tv vis vis (mkNomReflCo (varType tv)) (mkReflCo r ty)) + -> Just (ForAllCo tv vis vis (mkNomReflCo (varType tv)) (mkReflCo r ty)) -- NB: NoRefl variant. Otherwise, we get a loop! _ -> Nothing ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -311,8 +311,8 @@ toIfaceCoercionX fr co go (FunCo { fco_role = r, fco_mult = w, fco_arg = co1, fco_res = co2 }) = IfaceFunCo r (go w) (go co1) (go co2) - go (ForAllCoX tv visL visR k co) - = IfaceForAllCoY(toIfaceBndr tv) + go (ForAllCo tv visL visR k co) + = IfaceForAllCo (toIfaceBndr tv) visL visR (toIfaceCoercionX fr' k) ===================================== compiler/GHC/Iface/Rename.hs ===================================== @@ -668,8 +668,8 @@ rnIfaceCo (IfaceTyConAppCo role tc cos) = IfaceTyConAppCo role <$> rnIfaceTyCon tc <*> mapM rnIfaceCo cos rnIfaceCo (IfaceAppCo co1 co2) = IfaceAppCo <$> rnIfaceCo co1 <*> rnIfaceCo co2 -rnIfaceCo (IfaceForAllCoY bndr visL visR co1 co2) - = (\bndr' co1' co2' -> IfaceForAllCoY bndr' visL visR co1' co2') +rnIfaceCo (IfaceForAllCo bndr visL visR co1 co2) + = (\bndr' co1' co2' -> IfaceForAllCo bndr' visL visR co1' co2') <$> rnIfaceBndr bndr <*> rnIfaceCo co1 <*> rnIfaceCo co2 rnIfaceCo (IfaceFreeCoVar c) = pure (IfaceFreeCoVar c) rnIfaceCo (IfaceCoVarCo lcl) = IfaceCoVarCo <$> pure lcl ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1717,7 +1717,7 @@ freeNamesIfCoercion (IfaceTyConAppCo _ tc cos) = freeNamesIfTc tc &&& fnList freeNamesIfCoercion cos freeNamesIfCoercion (IfaceAppCo c1 c2) = freeNamesIfCoercion c1 &&& freeNamesIfCoercion c2 -freeNamesIfCoercion (IfaceForAllCoY _tcv _visL _visR kind_co co) +freeNamesIfCoercion (IfaceForAllCo _tcv _visL _visR kind_co co) = freeNamesIfCoercion kind_co &&& freeNamesIfCoercion co freeNamesIfCoercion (IfaceFreeCoVar _) = emptyNameSet freeNamesIfCoercion (IfaceCoVarCo _) = emptyNameSet ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -380,7 +380,7 @@ data IfaceCoercion | IfaceFunCo Role IfaceCoercion IfaceCoercion IfaceCoercion | IfaceTyConAppCo Role IfaceTyCon [IfaceCoercion] | IfaceAppCo IfaceCoercion IfaceCoercion - | IfaceForAllCoY IfaceBndr !ForAllTyFlag !ForAllTyFlag IfaceCoercion IfaceCoercion + | IfaceForAllCo IfaceBndr !ForAllTyFlag !ForAllTyFlag IfaceCoercion IfaceCoercion | IfaceCoVarCo IfLclName | IfaceAxiomInstCo IfExtName BranchIndex [IfaceCoercion] | IfaceAxiomRuleCo IfLclName [IfaceCoercion] @@ -604,7 +604,7 @@ substIfaceType env ty go_co (IfaceFunCo r w c1 c2) = IfaceFunCo r (go_co w) (go_co c1) (go_co c2) go_co (IfaceTyConAppCo r tc cos) = IfaceTyConAppCo r tc (go_cos cos) go_co (IfaceAppCo c1 c2) = IfaceAppCo (go_co c1) (go_co c2) - go_co (IfaceForAllCoY {}) = pprPanic "substIfaceCoercion" (ppr ty) + go_co (IfaceForAllCo {}) = pprPanic "substIfaceCoercion" (ppr ty) go_co (IfaceFreeCoVar cv) = IfaceFreeCoVar cv go_co (IfaceCoVarCo cv) = IfaceCoVarCo cv go_co (IfaceHoleCo cv) = IfaceHoleCo cv @@ -1791,16 +1791,16 @@ ppr_co _ (IfaceTyConAppCo r tc cos) ppr_co ctxt_prec (IfaceAppCo co1 co2) = maybeParen ctxt_prec appPrec $ ppr_co funPrec co1 <+> pprParendIfaceCoercion co2 -ppr_co ctxt_prec co@(IfaceForAllCoY {}) +ppr_co ctxt_prec co@(IfaceForAllCo {}) = maybeParen ctxt_prec funPrec $ -- FIXME: collect and pretty-print visibility info? pprIfaceForAllCoPart tvs (pprIfaceCoercion inner_co) where (tvs, inner_co) = split_co co - split_co (IfaceForAllCoY (IfaceTvBndr (name, _)) _visL _visR kind_co co') + split_co (IfaceForAllCo (IfaceTvBndr (name, _)) _visL _visR kind_co co') = let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'') - split_co (IfaceForAllCoY (IfaceIdBndr (_, name, _)) _visL _visR kind_co co') + split_co (IfaceForAllCo (IfaceIdBndr (_, name, _)) _visL _visR kind_co co') = let (tvs, co'') = split_co co' in ((name,kind_co):tvs,co'') split_co co' = ([], co') @@ -2107,7 +2107,7 @@ instance Binary IfaceCoercion where putByte bh 5 put_ bh a put_ bh b - put_ bh (IfaceForAllCoY a visL visR b c) = do + put_ bh (IfaceForAllCo a visL visR b c) = do putByte bh 6 put_ bh a put_ bh visL @@ -2189,7 +2189,7 @@ instance Binary IfaceCoercion where visR <- get bh b <- get bh c <- get bh - return $ IfaceForAllCoY a visL visR b c + return $ IfaceForAllCo a visL visR b c 7 -> do a <- get bh return $ IfaceCoVarCo a 8 -> do a <- get bh @@ -2287,7 +2287,7 @@ instance NFData IfaceCoercion where IfaceFunCo f1 f2 f3 f4 -> f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 IfaceTyConAppCo f1 f2 f3 -> f1 `seq` rnf f2 `seq` rnf f3 IfaceAppCo f1 f2 -> rnf f1 `seq` rnf f2 - IfaceForAllCoY f1 f2 f3 f4 f5 -> rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 + IfaceForAllCo f1 f2 f3 f4 f5 -> rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 IfaceCoVarCo f1 -> rnf f1 IfaceAxiomInstCo f1 f2 f3 -> rnf f1 `seq` rnf f2 `seq` rnf f3 IfaceAxiomRuleCo f1 f2 -> rnf f1 `seq` rnf f2 ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1491,9 +1491,9 @@ tcIfaceCo = go go (IfaceFunCo r w c1 c2) = mkFunCoNoFTF r <$> go w <*> go c1 <*> go c2 go (IfaceTyConAppCo r tc cs) = TyConAppCo r <$> tcIfaceTyCon tc <*> mapM go cs go (IfaceAppCo c1 c2) = AppCo <$> go c1 <*> go c2 - go (IfaceForAllCoY tv visL visR k c) = do { k' <- go k + go (IfaceForAllCo tv visL visR k c) = do { k' <- go k ; bindIfaceBndr tv $ \ tv' -> - ForAllCoX tv' visL visR k' <$> go c } + ForAllCo tv' visL visR k' <$> go c } go (IfaceCoVarCo n) = CoVarCo <$> go_var n go (IfaceAxiomInstCo n i cs) = AxiomInstCo <$> tcIfaceCoAxiom n <*> pure i <*> mapM go cs go (IfaceUnivCo p r t1 t2) = UnivCo <$> tcIfaceUnivCoProv p <*> pure r ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -137,7 +137,7 @@ synonymTyConsOfType ty go_co (GRefl _ ty mco) = go ty `plusNameEnv` go_mco mco go_co (TyConAppCo _ tc cs) = go_tc tc `plusNameEnv` go_co_s cs go_co (AppCo co co') = go_co co `plusNameEnv` go_co co' - go_co (ForAllCoX _ _ _ co co') = go_co co `plusNameEnv` go_co co' + go_co (ForAllCo _ _ _ co co') = go_co co `plusNameEnv` go_co co' go_co (FunCo { fco_mult = m, fco_arg = a, fco_res = r }) = go_co m `plusNameEnv` go_co a `plusNameEnv` go_co r go_co (CoVarCo _) = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1568,7 +1568,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_co dv (CoVarCo cv) = go_cv dv cv - go_co dv (ForAllCoX tcv _visL _visR kind_co co) + go_co dv (ForAllCo tcv _visL _visR kind_co co) = do { dv1 <- go_co dv kind_co ; collect_cand_qtvs_co orig_ty cur_lvl (bound `extendVarSet` tcv) dv1 co } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7f95d4a8492e9aaf5a5c6af317ffe4e393413d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7f95d4a8492e9aaf5a5c6af317ffe4e393413d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 00:48:34 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Sun, 23 Apr 2023 20:48:34 -0400 Subject: [Git][ghc/ghc][wip/expand-do] run the pattern match check in generated lambda exprs to avoid getting... Message-ID: <6445d1e283e98_178e749c7990cc108246f@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 9226b223 by Apoorv Ingle at 2023-04-23T19:48:21-05:00 run the pattern match check in generated lambda exprs to avoid getting suprious pattern match failures. c.f. pmcheck/should_compile/DoubleMatch.hs - - - - - 8 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc.hs - compiler/GHC/HsToCore/Pmc/Utils.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Match.hs - + testsuite/tests/pmcheck/should_compile/DoubleMatch.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -150,6 +150,7 @@ dsHsBind dflags (VarBind { var_id = var force_var = if xopt LangExt.Strict dflags then [id] else [] + -- ; tracePm "dsHsBind" (vcat [text "VarBind:", ppr force_var, ppr core_bind]) ; return (force_var, [core_bind]) } dsHsBind dflags b@(FunBind { fun_id = L loc fun @@ -179,10 +180,11 @@ dsHsBind dflags b@(FunBind { fun_id = L loc fun = [id] | otherwise = [] - ; --pprTrace "dsHsBind" (vcat [ ppr fun <+> ppr (idInlinePragma fun) - -- , ppr (mg_alts matches) - -- , ppr args, ppr core_binds, ppr body']) $ - return (force_var, [core_binds]) } } + -- ; tracePm "dsHsBind" (vcat [ text "FunBind:", + -- , ppr fun <+> ppr (idInlinePragma fun) + -- , ppr (mg_alts matches) + -- , ppr args, ppr core_binds, ppr body']) + ; return (force_var, [core_binds]) } } dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss , pat_ext = (ty, (rhs_tick, var_ticks)) @@ -197,6 +199,9 @@ dsHsBind dflags (PatBind { pat_lhs = pat, pat_rhs = grhss ; let force_var' = if isBangedLPat pat' then [force_var] else [] + -- ; tracePm "dsHsBind" (vcat [text "PatBind" + -- , ppr force_var' + -- , ppr sel_binds]) ; return (force_var', sel_binds) } dsHsBind ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -783,6 +783,9 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches -- Pattern match check warnings for /this match-group/. -- @rhss_nablas@ is a flat list of covered Nablas for each RHS. -- Each Match will split off one Nablas for its RHSs from this. + -- ; tracePm "matchWrapper" (vcat [ppr ctxt + -- , text "matchPmChecked" + -- , ppr $ isMatchContextPmChecked dflags origin ctxt]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt then addHsScrutTmCs (concat scrs) new_vars $ -- See Note [Long-distance information] ===================================== compiler/GHC/HsToCore/Pmc.hs ===================================== @@ -159,7 +159,7 @@ pmcMatches ctxt vars matches = {-# SCC "pmcMatches" #-} do tracePm "pmcMatches {" $ hang (vcat [ppr ctxt, ppr vars, text "Matches:"]) 2 - (vcat (map ppr matches) $$ ppr missing) + (vcat (map ppr matches) $$ (text "missing:" <+> ppr missing)) case NE.nonEmpty matches of Nothing -> do -- This must be an -XEmptyCase. See Note [Checking EmptyCase] ===================================== compiler/GHC/HsToCore/Pmc/Utils.hs ===================================== @@ -108,6 +108,9 @@ arrowMatchContextExhaustiveWarningFlag = \ case -- 'HsMatchContext' (does not matter whether it is the redundancy check or the -- exhaustiveness check). isMatchContextPmChecked :: DynFlags -> Origin -> HsMatchContext id -> Bool +isMatchContextPmChecked _ origin LambdaExpr + | isGenerated origin + = True isMatchContextPmChecked dflags origin kind | isGenerated origin = False @@ -119,7 +122,7 @@ isMatchContextPmChecked dflags origin kind needToRunPmCheck :: DynFlags -> Origin -> Bool needToRunPmCheck dflags origin | isGenerated origin - = False + = True | otherwise = notNull (filter (`wopt` dflags) allPmCheckWarnings) ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -326,6 +326,7 @@ tcApp rn_expr exp_res_ty = do { traceTc "tcApp {" $ vcat [ text "rn_fun:" <+> ppr rn_fun , text "rn_args:" <+> ppr rn_args ] + ; (tc_fun, fun_sigma) <- tcInferAppHead fun rn_args -- Instantiate ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -326,7 +326,9 @@ tcDoStmts doExpr@(DoExpr _) (L l stmts) res_ty ; let expand_do_expr = mkExpandedExpr (HsDo noExtField doExpr (L l stmts)) (unLoc expand_expr) -- Do expansion on the fly - ; traceTc "tcDoStmts do" (text "tcExpr:" <+> ppr expand_do_expr) + ; traceTc "tcDoStmts do" (vcat [ text "original:" <+> ppr expand_do_expr + , text "expnd:" <+> ppr expand_expr + ]) ; tcExpr expand_do_expr res_ty } ===================================== testsuite/tests/pmcheck/should_compile/DoubleMatch.hs ===================================== @@ -0,0 +1,18 @@ +{-# LANGUAGE CApiFFI, CPP, DeriveDataTypeable, NondecreasingIndentation #-} +{-# OPTIONS_GHC -Wincomplete-patterns #-} +{-# OPTIONS_GHC -fno-cse #-} +module DoubleMatch where + +data Handler = Default + | Handler1 + +doingThing :: Handler -> IO Int +doingThing handler = do + v <- case handler of + Default -> return 0 + _other_Handler -> do + asdf <- return 1 + let action = case handler of + Handler1 -> 1 + return action + return v ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -159,3 +159,4 @@ test('EmptyCase010', [], compile, [overlapping_incomplete]) test('T19271', [], compile, [overlapping_incomplete]) test('T21761', [], compile, [overlapping_incomplete]) test('T22964', [], compile, [overlapping_incomplete]) +test('DoubleMatch', normal, compile, [overlapping_incomplete]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9226b223426fdd3e8f461dc37ee61d9cef69de9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9226b223426fdd3e8f461dc37ee61d9cef69de9d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 07:46:07 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 24 Apr 2023 03:46:07 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23025 Message-ID: <644633bfb6b0_178e74a2e1003011006a9@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T23025 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23025 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 09:43:56 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 24 Apr 2023 05:43:56 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 3 commits: Fix acquire fences on indirections Message-ID: <64464f5ceb4d3_178e74a4df38c0110998b@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 9d911f17 by Ubuntu at 2023-04-24T09:35:15+00:00 Fix acquire fences on indirections - - - - - 39446503 by Ubuntu at 2023-04-24T09:36:09+00:00 STM - - - - - 3caadbd5 by Ubuntu at 2023-04-24T09:36:29+00:00 comment fixes - - - - - 3 changed files: - rts/STM.c - rts/StgMiscClosures.cmm - rts/include/stg/SMP.h Changes: ===================================== rts/STM.c ===================================== @@ -294,7 +294,7 @@ static StgClosure *lock_tvar(Capability *cap, StgInfoTable *info; do { result = ACQUIRE_LOAD(&s->current_value); - info = GET_INFO_RELAXED(UNTAG_CLOSURE(result)); + info = GET_INFO(UNTAG_CLOSURE(result)); } while (info == &stg_TREC_HEADER_info); } while (cas((void *) &s->current_value, (StgWord)result, (StgWord)trec) != (StgWord)result); ===================================== rts/StgMiscClosures.cmm ===================================== @@ -521,6 +521,7 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") (P_ node) { TICK_ENT_DYN_IND(); /* tick */ + ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info); node = %acquire StgInd_indirectee(node); node = UNTAG(node); TICK_ENT_VIA_NODE(); @@ -530,6 +531,7 @@ INFO_TABLE(stg_IND,1,0,IND,"IND","IND") /* explicit stack */ { TICK_ENT_DYN_IND(); /* tick */ + ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); P_ p; p = %acquire StgInd_indirectee(R1); R1 = UNTAG(p); @@ -542,6 +544,7 @@ INFO_TABLE(stg_IND_STATIC,1,0,IND_STATIC,"IND_STATIC","IND_STATIC") /* explicit stack */ { TICK_ENT_STATIC_IND(); /* tick */ + ACQUIRE_FENCE_ON(R1 + OFFSET_StgHeader_info); P_ p; p = %acquire StgInd_indirectee(R1); R1 = UNTAG(p); @@ -569,7 +572,7 @@ INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE") retry: // Synchronizes with the SET_INFO_RELEASE in // updateWithIndirection - ACQUIRE_FENCE_ON(StgHeader_info(node)); + ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info); // Synchronizes with the release-store in // updateWithIndirection. @@ -678,7 +681,7 @@ loop: // defined in CMM. goto loop; } - ACQUIRE_FENCE_ON(StgHeader_info(node)); + ACQUIRE_FENCE_ON(node + OFFSET_StgHeader_info); jump %ENTRY_CODE(info) (node); #else ccall barf("WHITEHOLE object (%p) entered!", R1) never returns; ===================================== rts/include/stg/SMP.h ===================================== @@ -277,7 +277,7 @@ EXTERN_INLINE void load_load_barrier(void); * U1. use a release-store to place the new indirectee into the thunk's * indirectee field * - * U2. use a relaxed-store to set the info table to stg_BLACKHOLE (which + * U2. use a release-store to set the info table to stg_BLACKHOLE (which * represents an indirection) * * Blackholing a thunk (either eagerly, by GHC.StgToCmm.Bind.emitBlackHoleCode, @@ -299,7 +299,7 @@ EXTERN_INLINE void load_load_barrier(void); * * E4. enter the indirectee (or block if the indirectee is a TSO) * - * The acquire-fence in step (E2) is somewhat surprising but is necessary as + * The release/acquire pair (U2)/(E2) is somewhat surprising but is necessary as * the C11 memory model does not guarantee that the store (U1) is visible to * (E3) despite (U1) preceding (U2) in program-order (due to the relaxed * ordering of (E3)). This is demonstrated by the following CppMem model: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e1bd66c4aa70f2a0130820cbac48a017f76eacf9...3caadbd50211ef5fddbcefcba17b4c5baaa1793e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e1bd66c4aa70f2a0130820cbac48a017f76eacf9...3caadbd50211ef5fddbcefcba17b4c5baaa1793e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 10:09:23 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Mon, 24 Apr 2023 06:09:23 -0400 Subject: [Git][ghc/ghc][wip/T23025] WIP: fix another bug Message-ID: <64465553c955e_178e74a565898411123ee@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23025 at Glasgow Haskell Compiler / GHC Commits: 3e1f1f48 by Krzysztof Gogolewski at 2023-04-24T12:09:03+02:00 WIP: fix another bug - - - - - 2 changed files: - compiler/GHC/Core/Lint.hs - testsuite/tests/linear/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -1491,6 +1491,7 @@ lintCaseExpr scrut var alt_ty alts = -- See GHC.Core Note [Case expression invariants] item (7) ; lintBinder CaseBind var $ \_ -> + addAliasUE var scrut_ue $ do { -- Check the alternatives ; let extra_ue = scaleUE scrut_mult scrut_ue ; alt_ues <- mapM (lintCoreAlt var scrut_ty scrut_mult alt_ty extra_ue) alts ===================================== testsuite/tests/linear/should_compile/all.T ===================================== @@ -40,4 +40,4 @@ test('T18731', normal, compile, ['']) test('T19400', unless(compiler_debugged(), skip), compile, ['']) test('T20023', normal, compile, ['']) test('T22546', normal, compile, ['']) -test('T23025', normal, compile, ['']) +test('T23025', normal, compile, ['-dlinear-core-lint']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e1f1f48465052d8b9eccc36d917305338030531 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3e1f1f48465052d8b9eccc36d917305338030531 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 13:19:11 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 09:19:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Implement executablePath for Solaris and make getBaseDir less platform-dependent Message-ID: <644681cf86885_178e74a8c36e5c115095@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 99c28e8f by Ben Gamari at 2023-04-24T09:18:58-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - cb55beb5 by Cheng Shao at 2023-04-24T09:19:00-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2d937299 by Cheng Shao at 2023-04-24T09:19:01-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 19 changed files: - compiler/GHC/Utils/Panic.hs - configure.ac - hadrian/src/Rules/Generate.hs - libraries/base/Control/Concurrent/MVar.hs - libraries/base/Control/Exception/Base.hs - libraries/base/Control/Monad.hs - libraries/base/Data/Complex.hs - libraries/base/Data/List.hs - libraries/base/Data/OldList.hs - libraries/base/System/Environment.hs - libraries/base/System/Environment/ExecutablePath.hsc - libraries/base/Text/Read/Lex.hs - libraries/ghc-boot/GHC/BaseDir.hs - libraries/ghc-prim/cbits/atomic.c - rts/include/stg/Prim.h - rts/rts.cabal.in - testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm - testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 - testsuite/tests/codeGen/should_run/T20137/T20137C.c Changes: ===================================== compiler/GHC/Utils/Panic.hs ===================================== @@ -7,6 +7,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables, LambdaCase #-} +#include + -- | Defines basic functions for printing error messages. -- -- It's hard to put these functions anywhere else without causing @@ -236,6 +238,11 @@ signalHandlersRefCount = unsafePerformIO $ newMVar (0,Nothing) -- | Temporarily install standard signal handlers for catching ^C, which just -- throw an exception in the current thread. withSignalHandlers :: ExceptionMonad m => m a -> m a +#if !defined(HAVE_SIGNAL_H) +-- No signal functionality exist on the host platform (e.g. on +-- wasm32-wasi), so don't attempt to set up signal handlers +withSignalHandlers = id +#else withSignalHandlers act = do main_thread <- liftIO myThreadId wtid <- liftIO (mkWeakThreadId main_thread) @@ -295,6 +302,7 @@ withSignalHandlers act = do mayInstallHandlers act `MC.finally` mayUninstallHandlers +#endif callStackDoc :: HasCallStack => SDoc callStackDoc = prettyCallStackDoc callStack ===================================== configure.ac ===================================== @@ -904,11 +904,6 @@ FP_CHECK_SIZEOF_AND_ALIGNMENT(uint64_t) dnl for use in settings file TargetWordSize=$ac_cv_sizeof_void_p -if test "x$TargetWordSize" = x8; then - AC_SUBST([Cabal64bit],[True]) -else - AC_SUBST([Cabal64bit],[False]) -fi AC_SUBST(TargetWordSize) AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -295,11 +295,6 @@ rtsCabalFlags = mconcat , flag "CabalUseSystemLibFFI" UseSystemFfi , flag "CabalLibffiAdjustors" UseLibffiForAdjustors , flag "CabalLeadingUnderscore" LeadingUnderscore - , interpolateVar "Cabal64bit" $ do - let settingWord :: Setting -> Action Word - settingWord s = read <$> setting s - ws <- settingWord TargetWordSize - return $ toCabalBool (ws == 8) ] where flag = interpolateCabalFlag ===================================== libraries/base/Control/Concurrent/MVar.hs ===================================== @@ -37,7 +37,7 @@ -- than 'GHC.Conc.STM'. They are appropriate for building synchronization -- primitives and performing simple interthread communication; however -- they are very simple and susceptible to race conditions, deadlocks or --- uncaught exceptions. Do not use them if you need perform larger +-- uncaught exceptions. Do not use them if you need to perform larger -- atomic operations such as reading from multiple variables: use 'GHC.Conc.STM' -- instead. -- ===================================== libraries/base/Control/Exception/Base.hs ===================================== @@ -223,7 +223,7 @@ onException io what = io `catch` \e -> do _ <- what -- handle. Similarly, closing a socket (from \"network\" package) is also -- uninterruptible under similar conditions. An example of an interruptible -- action is 'killThread'. Completion of interruptible release actions can be --- ensured by wrapping them in in 'uninterruptibleMask_', but this risks making +-- ensured by wrapping them in 'uninterruptibleMask_', but this risks making -- the program non-responsive to @Control-C@, or timeouts. Another option is to -- run the release action asynchronously in its own thread: -- ===================================== libraries/base/Control/Monad.hs ===================================== @@ -101,11 +101,11 @@ import GHC.Num ( (-) ) -- -- ==== __Examples__ -- --- Common uses of 'guard' include conditionally signaling an error in +-- Common uses of 'guard' include conditionally signalling an error in -- an error monad and conditionally rejecting the current choice in an -- 'Alternative'-based parser. -- --- As an example of signaling an error in the error monad 'Maybe', +-- As an example of signalling an error in the error monad 'Maybe', -- consider a safe division function @safeDiv x y@ that returns -- 'Nothing' when the denominator @y@ is zero and @'Just' (x \`div\` -- y)@ otherwise. For example: ===================================== libraries/base/Data/Complex.hs ===================================== @@ -104,13 +104,13 @@ cis theta = cos theta :+ sin theta -- | The function 'polar' takes a complex number and -- returns a (magnitude, phase) pair in canonical form: --- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@; +-- the magnitude is non-negative, and the phase in the range @(-'pi', 'pi']@; -- if the magnitude is zero, then so is the phase. {-# SPECIALISE polar :: Complex Double -> (Double,Double) #-} polar :: (RealFloat a) => Complex a -> (a,a) polar z = (magnitude z, phase z) --- | The nonnegative magnitude of a complex number. +-- | The non-negative magnitude of a complex number. {-# SPECIALISE magnitude :: Complex Double -> Double #-} magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k ===================================== libraries/base/Data/List.hs ===================================== @@ -124,7 +124,7 @@ module Data.List , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/Data/OldList.hs ===================================== @@ -124,7 +124,7 @@ module Data.OldList , partition -- * Indexing lists - -- | These functions treat a list @xs@ as a indexed collection, + -- | These functions treat a list @xs@ as an indexed collection, -- with indices ranging from 0 to @'length' xs - 1 at . , (!?) ===================================== libraries/base/System/Environment.hs ===================================== @@ -19,9 +19,7 @@ module System.Environment ( getArgs, getProgName, -#if !defined(javascript_HOST_ARCH) executablePath, -#endif getExecutablePath, getEnv, lookupEnv, ===================================== libraries/base/System/Environment/ExecutablePath.hsc ===================================== @@ -18,9 +18,7 @@ module System.Environment.ExecutablePath ( getExecutablePath -##if !defined(javascript_HOST_ARCH) , executablePath -##endif ) where ##if defined(javascript_HOST_ARCH) @@ -28,6 +26,9 @@ module System.Environment.ExecutablePath getExecutablePath :: IO FilePath getExecutablePath = return "a.jsexe" +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing + ##else -- The imports are purposely kept completely disjoint to prevent edits @@ -47,6 +48,12 @@ import Data.List (isSuffixOf) import Foreign.C import Foreign.Marshal.Array import System.Posix.Internals +#elif defined(solaris2_HOST_OS) +import Control.Exception (catch, throw) +import Foreign.C +import Foreign.Marshal.Array +import System.IO.Error (isDoesNotExistError) +import System.Posix.Internals #elif defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) import Control.Exception (catch, throw) import Foreign.C @@ -101,7 +108,7 @@ getExecutablePath :: IO FilePath -- -- If the operating system provides a reliable way to determine the current -- executable, return the query action, otherwise return @Nothing at . The action --- is defined on FreeBSD, Linux, MacOS, NetBSD, and Windows. +-- is defined on FreeBSD, Linux, MacOS, NetBSD, Solaris, and Windows. -- -- Even where the query action is defined, there may be situations where no -- result is available, e.g. if the executable file was deleted while the @@ -171,9 +178,9 @@ executablePath = Just (fmap Just getExecutablePath `catch` f) | otherwise = throw e -------------------------------------------------------------------------------- --- Linux +-- Linux / Solaris -#elif defined(linux_HOST_OS) +#elif defined(linux_HOST_OS) || defined(solaris2_HOST_OS) foreign import ccall unsafe "readlink" c_readlink :: CString -> CString -> CSize -> IO CInt @@ -190,6 +197,7 @@ readSymbolicLink file = c_readlink s buf 4096 peekFilePathLen (buf,fromIntegral len) +# if defined(linux_HOST_OS) getExecutablePath = readSymbolicLink $ "/proc/self/exe" executablePath = Just (check <$> getExecutablePath) where @@ -200,6 +208,18 @@ executablePath = Just (check <$> getExecutablePath) where check s | "(deleted)" `isSuffixOf` s = Nothing | otherwise = Just s +# elif defined(solaris2_HOST_OS) +getExecutablePath = readSymbolicLink "/proc/self/path/a.out" + +executablePath = Just ((Just <$> getExecutablePath) `catch` f) + where + -- readlink(2) fails with ENOENT when the executable has been deleted, + -- even though the symlink itself still exists according to readdir(3). + f e | isDoesNotExistError e = pure Nothing + | otherwise = throw e + +#endif + -------------------------------------------------------------------------------- -- FreeBSD / NetBSD ===================================== libraries/base/Text/Read/Lex.hs ===================================== @@ -112,7 +112,7 @@ numberToFixed _ _ = Nothing -- space problems in #5688 -- Ways this is conservative: -- * the floatRange is in base 2, but we pretend it is in base 10 --- * we pad the floateRange a bit, just in case it is very small +-- * we pad the floatRange a bit, just in case it is very small -- and we would otherwise hit an edge case -- * We only worry about numbers that have an exponent. If they don't -- have an exponent then the Rational won't be much larger than the ===================================== libraries/ghc-boot/GHC/BaseDir.hs ===================================== @@ -12,7 +12,11 @@ -- installation location at build time. ghc-pkg also can expand those variables -- and so needs the top dir location to do that too. -module GHC.BaseDir where +module GHC.BaseDir + ( expandTopDir + , expandPathVar + , getBaseDir + ) where import Prelude -- See Note [Why do we import Prelude here?] @@ -20,11 +24,9 @@ import Data.List (stripPrefix) import Data.Maybe (listToMaybe) import System.FilePath --- Windows -#if defined(mingw32_HOST_OS) -import System.Environment (getExecutablePath) --- POSIX -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#if MIN_VERSION_base(4,17,0) +import System.Environment (executablePath) +#else import System.Environment (getExecutablePath) #endif @@ -43,17 +45,27 @@ expandPathVar var value str expandPathVar var value (x:xs) = x : expandPathVar var value xs expandPathVar _ _ [] = [] +#if !MIN_VERSION_base(4,17,0) +-- Polyfill for base-4.17 executablePath +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Just (Just <$> getExecutablePath) +#elif !MIN_VERSION_base(4,18,0) && defined(js_HOST_ARCH) +-- executablePath is missing from base < 4.18.0 on js_HOST_ARCH +executablePath :: Maybe (IO (Maybe FilePath)) +executablePath = Nothing +#endif + -- | Calculate the location of the base dir getBaseDir :: IO (Maybe String) #if defined(mingw32_HOST_OS) -getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath where -- locate the "base dir" when given the path -- to the real ghc executable (as opposed to symlink) -- that is running this function. rootDir :: FilePath -> FilePath rootDir = takeDirectory . takeDirectory . normalise -#elif defined(darwin_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS) +#else -- on unix, this is a bit more confusing. -- The layout right now is something like -- @@ -65,14 +77,15 @@ getBaseDir = Just . (\p -> p "lib") . rootDir <$> getExecutablePath -- As such, we first need to find the absolute location to the -- binary. -- --- getExecutablePath will return (3). One takeDirectory will +-- executablePath will return (3). One takeDirectory will -- give use /lib/ghc-X.Y.Z/bin, and another will give us (4). -- -- This of course only works due to the current layout. If -- the layout is changed, such that we have ghc-X.Y.Z/{bin,lib} -- this would need to be changed accordingly. -- -getBaseDir = Just . (\p -> p "lib") . takeDirectory . takeDirectory <$> getExecutablePath -#else -getBaseDir = return Nothing +getBaseDir = maybe (pure Nothing) (((( "lib") . rootDir) <$>) <$>) executablePath + where + rootDir :: FilePath -> FilePath + rootDir = takeDirectory . takeDirectory #endif ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -33,14 +33,12 @@ hs_atomic_add32(StgWord x, StgWord val) return __sync_fetch_and_add((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_add64(StgWord x, StgWord64 val); StgWord64 hs_atomic_add64(StgWord x, StgWord64 val) { return __sync_fetch_and_add((volatile StgWord64 *) x, val); } -#endif // FetchSubByteArrayOp_Int @@ -65,14 +63,12 @@ hs_atomic_sub32(StgWord x, StgWord val) return __sync_fetch_and_sub((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val); StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val) { return __sync_fetch_and_sub((volatile StgWord64 *) x, val); } -#endif // FetchAndByteArrayOp_Int @@ -97,14 +93,12 @@ hs_atomic_and32(StgWord x, StgWord val) return __sync_fetch_and_and((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_and64(StgWord x, StgWord64 val); StgWord64 hs_atomic_and64(StgWord x, StgWord64 val) { return __sync_fetch_and_and((volatile StgWord64 *) x, val); } -#endif // FetchNandByteArrayOp_Int @@ -206,7 +200,6 @@ hs_atomic_nand32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val); StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val) @@ -217,7 +210,6 @@ hs_atomic_nand64(StgWord x, StgWord64 val) CAS_NAND((volatile StgWord64 *) x, val); #endif } -#endif #pragma GCC diagnostic pop @@ -244,14 +236,12 @@ hs_atomic_or32(StgWord x, StgWord val) return __sync_fetch_and_or((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_or64(StgWord x, StgWord64 val); StgWord64 hs_atomic_or64(StgWord x, StgWord64 val) { return __sync_fetch_and_or((volatile StgWord64 *) x, val); } -#endif // FetchXorByteArrayOp_Int @@ -276,14 +266,12 @@ hs_atomic_xor32(StgWord x, StgWord val) return __sync_fetch_and_xor((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val); StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val) { return __sync_fetch_and_xor((volatile StgWord64 *) x, val); } -#endif // CasByteArrayOp_Int @@ -338,15 +326,13 @@ hs_xchg32(StgWord x, StgWord val) return (StgWord) __atomic_exchange_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST); } -#if WORD_SIZE_IN_BITS == 64 //GCC provides this even on 32bit, but StgWord is still 32 bits. -extern StgWord hs_xchg64(StgWord x, StgWord val); -StgWord -hs_xchg64(StgWord x, StgWord val) +extern StgWord64 hs_xchg64(StgWord x, StgWord64 val); +StgWord64 +hs_xchg64(StgWord x, StgWord64 val) { - return (StgWord) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); + return (StgWord64) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); } -#endif // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -391,7 +377,6 @@ hs_atomicread32(StgWord x) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomicread64(StgWord x); StgWord64 hs_atomicread64(StgWord x) @@ -402,7 +387,6 @@ hs_atomicread64(StgWord x) return __sync_add_and_fetch((StgWord64 *) x, 0); #endif } -#endif // AtomicWriteByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -441,7 +425,6 @@ hs_atomicwrite32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern void hs_atomicwrite64(StgWord x, StgWord64 val); void hs_atomicwrite64(StgWord x, StgWord64 val) @@ -452,6 +435,5 @@ hs_atomicwrite64(StgWord x, StgWord64 val) while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val)); #endif } -#endif #endif ===================================== rts/include/stg/Prim.h ===================================== @@ -53,7 +53,7 @@ void hs_atomicwrite64(StgWord x, StgWord64 val); StgWord hs_xchg8(StgWord x, StgWord val); StgWord hs_xchg16(StgWord x, StgWord val); StgWord hs_xchg32(StgWord x, StgWord val); -StgWord hs_xchg64(StgWord x, StgWord val); +StgWord64 hs_xchg64(StgWord x, StgWord64 val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== rts/rts.cabal.in ===================================== @@ -45,8 +45,6 @@ flag libdw default: @CabalHaveLibdw@ flag libnuma default: @CabalHaveLibNuma@ -flag 64bit - default: @Cabal64bit@ flag leading-underscore default: @CabalLeadingUnderscore@ flag smp @@ -289,27 +287,6 @@ library stg/Types.h -- See Note [Undefined symbols in the RTS] - if flag(64bit) - if flag(leading-underscore) - ld-options: - "-Wl,-u,_hs_atomic_add64" - "-Wl,-u,_hs_atomic_sub64" - "-Wl,-u,_hs_atomic_and64" - "-Wl,-u,_hs_atomic_nand64" - "-Wl,-u,_hs_atomic_or64" - "-Wl,-u,_hs_atomic_xor64" - "-Wl,-u,_hs_atomicread64" - "-Wl,-u,_hs_atomicwrite64" - else - ld-options: - "-Wl,-u,hs_atomic_add64" - "-Wl,-u,hs_atomic_sub64" - "-Wl,-u,hs_atomic_and64" - "-Wl,-u,hs_atomic_nand64" - "-Wl,-u,hs_atomic_or64" - "-Wl,-u,hs_atomic_xor64" - "-Wl,-u,hs_atomicread64" - "-Wl,-u,hs_atomicwrite64" if flag(leading-underscore) ld-options: "-Wl,-u,_base_GHCziTopHandler_runIO_closure" @@ -357,21 +334,27 @@ library "-Wl,-u,_hs_atomic_add8" "-Wl,-u,_hs_atomic_add16" "-Wl,-u,_hs_atomic_add32" + "-Wl,-u,_hs_atomic_add64" "-Wl,-u,_hs_atomic_sub8" "-Wl,-u,_hs_atomic_sub16" "-Wl,-u,_hs_atomic_sub32" + "-Wl,-u,_hs_atomic_sub64" "-Wl,-u,_hs_atomic_and8" "-Wl,-u,_hs_atomic_and16" "-Wl,-u,_hs_atomic_and32" + "-Wl,-u,_hs_atomic_and64" "-Wl,-u,_hs_atomic_nand8" "-Wl,-u,_hs_atomic_nand16" "-Wl,-u,_hs_atomic_nand32" + "-Wl,-u,_hs_atomic_nand64" "-Wl,-u,_hs_atomic_or8" "-Wl,-u,_hs_atomic_or16" "-Wl,-u,_hs_atomic_or32" + "-Wl,-u,_hs_atomic_or64" "-Wl,-u,_hs_atomic_xor8" "-Wl,-u,_hs_atomic_xor16" "-Wl,-u,_hs_atomic_xor32" + "-Wl,-u,_hs_atomic_xor64" "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" @@ -383,9 +366,11 @@ library "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" + "-Wl,-u,_hs_atomicread64" "-Wl,-u,_hs_atomicwrite8" "-Wl,-u,_hs_atomicwrite16" "-Wl,-u,_hs_atomicwrite32" + "-Wl,-u,_hs_atomicwrite64" "-Wl,-u,_base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) @@ -440,21 +425,27 @@ library "-Wl,-u,hs_atomic_add8" "-Wl,-u,hs_atomic_add16" "-Wl,-u,hs_atomic_add32" + "-Wl,-u,hs_atomic_add64" "-Wl,-u,hs_atomic_sub8" "-Wl,-u,hs_atomic_sub16" "-Wl,-u,hs_atomic_sub32" + "-Wl,-u,hs_atomic_sub64" "-Wl,-u,hs_atomic_and8" "-Wl,-u,hs_atomic_and16" "-Wl,-u,hs_atomic_and32" + "-Wl,-u,hs_atomic_and64" "-Wl,-u,hs_atomic_nand8" "-Wl,-u,hs_atomic_nand16" "-Wl,-u,hs_atomic_nand32" + "-Wl,-u,hs_atomic_nand64" "-Wl,-u,hs_atomic_or8" "-Wl,-u,hs_atomic_or16" "-Wl,-u,hs_atomic_or32" + "-Wl,-u,hs_atomic_or64" "-Wl,-u,hs_atomic_xor8" "-Wl,-u,hs_atomic_xor16" "-Wl,-u,hs_atomic_xor32" + "-Wl,-u,hs_atomic_xor64" "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" @@ -466,9 +457,11 @@ library "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" + "-Wl,-u,hs_atomicread64" "-Wl,-u,hs_atomicwrite8" "-Wl,-u,hs_atomicwrite16" "-Wl,-u,hs_atomicwrite32" + "-Wl,-u,hs_atomicwrite64" "-Wl,-u,base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) ===================================== testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm ===================================== @@ -7,17 +7,17 @@ cmm_foo64 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits64 x; + I64 x; - prim %store_seqcst64(q, 42); - (x) = prim %fetch_add64(q, 5); - (x) = prim %fetch_sub64(q, 10); - (x) = prim %fetch_and64(q, 120); - (x) = prim %fetch_or64(q, 2); - (x) = prim %fetch_xor64(q, 33); - (x) = prim %fetch_nand64(q, 127); + prim %store_seqcst64(q, 42 :: I64); + (x) = prim %fetch_add64(q, 5 :: I64); + (x) = prim %fetch_sub64(q, 10 :: I64); + (x) = prim %fetch_and64(q, 120 :: I64); + (x) = prim %fetch_or64(q, 2 :: I64); + (x) = prim %fetch_xor64(q, 33 :: I64); + (x) = prim %fetch_nand64(q, 127 :: I64); (x) = prim %load_seqcst64(q); return (x); } @@ -26,9 +26,9 @@ cmm_foo32 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits32 x; + I32 x; prim %store_seqcst32(q, 42); (x) = prim %fetch_add32(q, 5); @@ -45,9 +45,9 @@ cmm_foo16 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits16 x; + I16 x; prim %store_seqcst16(q, 42); (x) = prim %fetch_add16(q, 5); @@ -64,9 +64,9 @@ cmm_foo8 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits8 x; + I8 x; prim %store_seqcst8(q, 42); (x) = prim %fetch_add8(q, 5); ===================================== testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 ===================================== @@ -5,9 +5,9 @@ 5 6 77777777 -ffffffff88888888 -ffffffff99999999 -ffffffffaaaaaaaa -ffffffffbbbbbbbb +88888888 +99999999 +aaaaaaaa +bbbbbbbb cccccccc -ffffffffdddddddd +dddddddd ===================================== testsuite/tests/codeGen/should_run/T20137/T20137C.c ===================================== @@ -16,19 +16,19 @@ runInteractiveProcess (char *const * args, { // N.B. We don't use %p here since the rendering of this varies across // libc implementations - printf("%" PRIx64 "\n", (uint64_t) args); - printf("%" PRIx64 "\n", (uint64_t) workingDirectory); - printf("%" PRIx64 "\n", (uint64_t) environment); + printf("%" PRIxPTR "\n", (uintptr_t) args); + printf("%" PRIxPTR "\n", (uintptr_t) workingDirectory); + printf("%" PRIxPTR "\n", (uintptr_t) environment); printf("%x\n", fdStdIn); printf("%x\n", fdStdOut); printf("%x\n", fdStdErr); - printf("%" PRIx64 "\n", (uint64_t) pfdStdInput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdOutput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdError); - printf("%" PRIx64 "\n", (uint64_t) childGroup); - printf("%" PRIx64 "\n", (uint64_t) childUser); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdInput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdOutput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdError); + printf("%" PRIxPTR "\n", (uintptr_t) childGroup); + printf("%" PRIxPTR "\n", (uintptr_t) childUser); printf("%x\n", flags); - printf("%" PRIx64 "\n", (uint64_t) failed_doing); + printf("%" PRIxPTR "\n", (uintptr_t) failed_doing); return 0; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e083c0b704dc3c5574fcb5fce534fbdd43f3729...2d93729979787f001b74e79f489a910915bc2195 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e083c0b704dc3c5574fcb5fce534fbdd43f3729...2d93729979787f001b74e79f489a910915bc2195 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 13:26:23 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 24 Apr 2023 09:26:23 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <6446837fe8a44_178e74a8ecbc581161087@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: 55d1d73d by Josh Meredith at 2023-04-24T13:25:52+00:00 Use unboxed codebuffers in base - - - - - 8 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/CodePage/API.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/CodePage/API.hs ===================================== @@ -1,6 +1,7 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude, NondecreasingIndentation, - RecordWildCards, ScopedTypeVariables #-} + RecordWildCards, ScopedTypeVariables, + UnboxedTuples #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} module GHC.IO.Encoding.CodePage.API ( @@ -157,11 +158,15 @@ newCP rec fn cp = do utf16_native_encode' :: EncodeBuffer utf16_native_decode' :: DecodeBuffer #if defined(WORDS_BIGENDIAN) -utf16_native_encode' = utf16be_encode -utf16_native_decode' = utf16be_decode +utf16_native_encode' i o = IO $ \st -> case utf16be_encode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) +utf16_native_decode' i o = IO $ \st -> case utf16be_decode i o st of + (# st', i', o' #) -> (# st', (i', o') #) #else -utf16_native_encode' = utf16le_encode -utf16_native_decode' = utf16le_decode +utf16_native_encode' i o = IO $ \st -> case utf16le_encode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) +utf16_native_decode' i o = IO $ \st -> case utf16le_decode i o st of + (# st', i', o' #) -> (# st', (i', o') #) #endif saner :: CodeBuffer from to ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let !(# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55d1d73d46c162c26bc6f04d7807fe9888cc0efe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55d1d73d46c162c26bc6f04d7807fe9888cc0efe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 14:44:12 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 24 Apr 2023 10:44:12 -0400 Subject: [Git][ghc/ghc][wip/tsan/fixes] 71 commits: Convert interface file loading errors into proper diagnostics Message-ID: <644695bcb3db0_178e74aa65dc68117699a@gitlab.mail> Ben Gamari pushed to branch wip/tsan/fixes at Glasgow Haskell Compiler / GHC Commits: 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - fa2c82e4 by Ben Gamari at 2023-04-24T06:00:39-04:00 compiler: Style fixes - - - - - add3ee5d by Ben Gamari at 2023-04-24T06:00:39-04:00 rts: Fix data race in threadPaused This only affects an assertion in the debug RTS, but it's a data race nevertheless. - - - - - c9642199 by Ben Gamari at 2023-04-24T06:00:39-04:00 rts: Silence spurious data races in ticky counters Previously we would use non-atomic accesses when bumping ticky counters, which would result in spurious data race reports from ThreadSanitizer when the threaded RTS was in use. - - - - - d29a3679 by Ben Gamari at 2023-04-24T06:00:40-04:00 Improve TSAN documentation - - - - - 5165a358 by Ben Gamari at 2023-04-24T06:00:40-04:00 compiler/cmm: Ensure that dump output has proc name Previously dump output from the early Cmm passes would not be labelled with a proc label. - - - - - 47d0ad2e by Ben Gamari at 2023-04-24T06:00:40-04:00 cmm: Introduce MO_RelaxedRead In hand-written Cmm it can sometimes be necessary to atomically load from memory deep within an expression (e.g. see the `CHECK_GC` macro). This MachOp provides a convenient way to do so without breaking the expression into multiple statements. - - - - - 4eb1aeb0 by Ben Gamari at 2023-04-24T06:00:40-04:00 rts: Fix various data races - - - - - e1986113 by Ben Gamari at 2023-04-24T06:00:40-04:00 base: use atomic write when updating timer manager - - - - - e5a4c2e4 by Ben Gamari at 2023-04-24T06:00:40-04:00 Use relaxed atomics to manipulate TSO status fields - - - - - d0f300cf by Ben Gamari at 2023-04-24T06:00:40-04:00 rts: Drop unnecessary atomic - - - - - 5946bdf1 by Ben Gamari at 2023-04-24T06:03:12-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers - - - - - 3c1e4a69 by Ben Gamari at 2023-04-24T06:03:49-04:00 rts: Fix synchronization on thread blocking state - - - - - c3b59aec by Ben Gamari at 2023-04-24T06:03:49-04:00 rts: Relaxed load MutVar info table - - - - - 48512cb5 by Ben Gamari at 2023-04-24T06:03:49-04:00 More principled treatment of acquire fences - - - - - 7b06478a by Ben Gamari at 2023-04-24T06:03:49-04:00 IND - - - - - a9abd9e6 by Ben Gamari at 2023-04-24T06:03:49-04:00 Wordsmith Note - - - - - 6bfb2ac0 by Ben Gamari at 2023-04-24T06:03:49-04:00 Use relaxed accesses in ticky bumping - - - - - cd8e6a32 by Ben Gamari at 2023-04-24T06:03:49-04:00 Fix thunk update ordering Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185. - - - - - c4a93bd7 by Ben Gamari at 2023-04-24T06:03:49-04:00 Things - - - - - e968aa19 by Ben Gamari at 2023-04-24T06:03:49-04:00 rts/IPE: Fix unused mutex warning - - - - - edb1a8f1 by Ben Gamari at 2023-04-24T06:03:49-04:00 rts: Relax info pointer stores - - - - - da2ef6fc by Ben Gamari at 2023-04-24T06:03:49-04:00 TSAN: Rework handling of spilling - - - - - aada555b by Ben Gamari at 2023-04-24T06:03:49-04:00 hadrian: More debug information - - - - - 3f8b3216 by Ben Gamari at 2023-04-24T06:03:49-04:00 hadrian: More selective TSAN instrumentation - - - - - 5090582c by Ben Gamari at 2023-04-24T06:03:49-04:00 rts: Drop benign race - - - - - 53451434 by Ubuntu at 2023-04-24T06:03:49-04:00 rts: C++ fixes - - - - - 4fa414c0 by Ben Gamari at 2023-04-24T06:04:16-04:00 codeGen: Ensure that TSAN is aware of writeArray# write barriers - - - - - 82fcb0d3 by Ben Gamari at 2023-04-24T06:04:18-04:00 More principled treatment of acquire fences - - - - - 69fcb273 by Ubuntu at 2023-04-24T06:04:18-04:00 Work around #22451 - - - - - ffce10ef by Ubuntu at 2023-04-24T06:04:18-04:00 llvm: Sequential consistency - - - - - 6f92a601 by Ubuntu at 2023-04-24T06:04:18-04:00 rts: sequential consistency - - - - - 96adc99c by Ubuntu at 2023-04-24T06:04:18-04:00 ghc-prim: Use C11 atomics - - - - - 59793d31 by Ubuntu at 2023-04-24T06:04:18-04:00 Fix thunk update further - - - - - b20f33cf by Ubuntu at 2023-04-24T06:04:18-04:00 Add acquire fence in WHITEHOLE - - - - - 76973b5c by Ubuntu at 2023-04-24T06:04:18-04:00 whitespace - - - - - b381a3b1 by Ubuntu at 2023-04-24T06:04:18-04:00 Note - - - - - 1a98c968 by Ben Gamari at 2023-04-24T06:04:18-04:00 STM: relaxed - - - - - 1079e23f by Ubuntu at 2023-04-24T06:04:18-04:00 Run script - - - - - 4bced947 by Ubuntu at 2023-04-24T06:04:18-04:00 Refine run script - - - - - 022d958b by Ubuntu at 2023-04-24T06:04:18-04:00 run - - - - - a419561b by Ubuntu at 2023-04-24T06:04:18-04:00 Disable selector optimisation - - - - - 213fe43e by Ben Gamari at 2023-04-24T06:04:18-04:00 CheckGC - - - - - 8d07f07c by Ubuntu at 2023-04-24T06:04:18-04:00 check-gc: fix large objects - - - - - c1102ada by Ubuntu at 2023-04-24T06:04:18-04:00 check-gc on GC - - - - - e0ec4666 by Ben Gamari at 2023-04-24T06:04:18-04:00 ACQUIRE_FENCE - - - - - d215f65d by Ben Gamari at 2023-04-24T06:04:18-04:00 Add Note - - - - - eb524511 by Ben Gamari at 2023-04-24T06:04:18-04:00 STM: Acquire instead of seq-cst - - - - - dda36120 by Ben Gamari at 2023-04-24T06:04:18-04:00 Comment - - - - - bd27d186 by Ubuntu at 2023-04-24T06:04:18-04:00 Fix acquire fences on indirections - - - - - 7fb7f719 by Ubuntu at 2023-04-24T06:04:18-04:00 STM - - - - - b702af6e by Ubuntu at 2023-04-24T06:04:18-04:00 comment fixes - - - - - 756d7141 by Ben Gamari at 2023-04-24T08:45:48-04:00 hadrian: Fix - - - - - 166b7062 by Ben Gamari at 2023-04-24T10:33:39-04:00 rts: BLACKHOLE fix - - - - - 8094c785 by Ben Gamari at 2023-04-24T10:34:07-04:00 rts: TSO owner - - - - - db98923f by Ben Gamari at 2023-04-24T10:34:31-04:00 updateThunk - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitmodules - cabal.project-reinstall - compiler/GHC/Cmm/Expr.hs - compiler/GHC/Cmm/Info.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - + compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Errors.hs - + compiler/GHC/Iface/Errors/Ppr.hs - + compiler/GHC/Iface/Errors/Types.hs - compiler/GHC/Iface/Load.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3caadbd50211ef5fddbcefcba17b4c5baaa1793e...db98923f70606b156f3cf82147ff6ca4172aed14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3caadbd50211ef5fddbcefcba17b4c5baaa1793e...db98923f70606b156f3cf82147ff6ca4172aed14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 15:03:09 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 24 Apr 2023 11:03:09 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <64469a2d7def7_178e74aabc6e7011792fb@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 5c30b235 by Sebastian Graf at 2023-04-24T16:59:55+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 9 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/stranal/should_compile/T18894.stderr - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5c30b235f23a23d06374c5b7d647ad8979edc3ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5c30b235f23a23d06374c5b7d647ad8979edc3ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 15:56:03 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 24 Apr 2023 11:56:03 -0400 Subject: [Git][ghc/ghc][wip/unboxed-codebuffer] Use unboxed codebuffers in base Message-ID: <6446a6938577b_178e74aba037e01185922@gitlab.mail> Josh Meredith pushed to branch wip/unboxed-codebuffer at Glasgow Haskell Compiler / GHC Commits: eb1588f6 by Josh Meredith at 2023-04-24T15:55:40+00:00 Use unboxed codebuffers in base - - - - - 8 changed files: - libraries/base/GHC/IO/Encoding.hs - libraries/base/GHC/IO/Encoding/CodePage/API.hs - libraries/base/GHC/IO/Encoding/Failure.hs - libraries/base/GHC/IO/Encoding/Iconv.hs - libraries/base/GHC/IO/Encoding/Latin1.hs - libraries/base/GHC/IO/Encoding/UTF16.hs - libraries/base/GHC/IO/Encoding/UTF32.hs - libraries/base/GHC/IO/Encoding/UTF8.hs Changes: ===================================== libraries/base/GHC/IO/Encoding.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} ----------------------------------------------------------------------------- @@ -336,11 +337,13 @@ mkTextEncoding' cfm enc = latin1_encode :: CharBuffer -> Buffer Word8 -> IO (CharBuffer, Buffer Word8) -latin1_encode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_encode input output -- unchecked, used for char8 +latin1_encode input output = IO $ \st -> case Latin1.latin1_encode input output st of + (# st', _why, input', output' #) -> (# st', (input', output') #) -- unchecked, used for char8 --latin1_encode = unsafePerformIO $ do mkTextEncoder Iconv.latin1 >>= return.encode latin1_decode :: Buffer Word8 -> CharBuffer -> IO (Buffer Word8, CharBuffer) -latin1_decode input output = fmap (\(_why,input',output') -> (input',output')) $ Latin1.latin1_decode input output +latin1_decode input output = IO $ \st -> case Latin1.latin1_decode input output st of + (# st', _why, input', output' #) -> (# st', (input',output') #) --latin1_decode = unsafePerformIO $ do mkTextDecoder Iconv.latin1 >>= return.encode unknownEncodingErr :: String -> IO a ===================================== libraries/base/GHC/IO/Encoding/CodePage/API.hs ===================================== @@ -1,6 +1,7 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude, NondecreasingIndentation, - RecordWildCards, ScopedTypeVariables #-} + RecordWildCards, ScopedTypeVariables, + UnboxedTuples #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} module GHC.IO.Encoding.CodePage.API ( @@ -157,11 +158,15 @@ newCP rec fn cp = do utf16_native_encode' :: EncodeBuffer utf16_native_decode' :: DecodeBuffer #if defined(WORDS_BIGENDIAN) -utf16_native_encode' = utf16be_encode -utf16_native_decode' = utf16be_decode +utf16_native_encode' i o = IO $ \st -> case utf16be_encode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) +utf16_native_decode' i o = IO $ \st -> case utf16be_decode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) #else -utf16_native_encode' = utf16le_encode -utf16_native_decode' = utf16le_decode +utf16_native_encode' i o = IO $ \st -> case utf16le_encode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) +utf16_native_decode' i o = IO $ \st -> case utf16le_decode i o st of + (# st', c, i', o' #) -> (# st', (c, i', o') #) #endif saner :: CodeBuffer from to ===================================== libraries/base/GHC/IO/Encoding/Failure.hs ===================================== @@ -1,5 +1,8 @@ {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- | @@ -18,7 +21,8 @@ module GHC.IO.Encoding.Failure ( CodingFailureMode(..), codingFailureModeSuffix, isSurrogate, - recoverDecode, recoverEncode + recoverDecode, recoverEncode, + recoverDecode#, recoverEncode#, ) where import GHC.IO @@ -142,6 +146,12 @@ unescapeRoundtripCharacterSurrogate c | otherwise = Nothing where x = ord c +recoverDecode# :: CodingFailureMode -> Buffer Word8 -> Buffer Char + -> State# RealWorld -> (# State# RealWorld, Buffer Word8, Buffer Char #) +recoverDecode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverDecode cfm input output) st + in (# st', bIn, bOut #) + recoverDecode :: CodingFailureMode -> Buffer Word8 -> Buffer Char -> IO (Buffer Word8, Buffer Char) recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } @@ -160,6 +170,12 @@ recoverDecode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ow' <- writeCharBuf oraw ow (escapeToRoundtripCharacterSurrogate b) return (input { bufL=ir+1 }, output { bufR=ow' }) +recoverEncode# :: CodingFailureMode -> Buffer Char -> Buffer Word8 + -> State# RealWorld -> (# State# RealWorld, Buffer Char, Buffer Word8 #) +recoverEncode# cfm input output st = + let !(# st', (bIn, bOut) #) = unIO (recoverEncode cfm input output) st + in (# st', bIn, bOut #) + recoverEncode :: CodingFailureMode -> Buffer Char -> Buffer Word8 -> IO (Buffer Char, Buffer Word8) recoverEncode cfm input at Buffer{ bufRaw=iraw, bufL=ir, bufR=_ } ===================================== libraries/base/GHC/IO/Encoding/Iconv.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE CPP , NoImplicitPrelude , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_HADDOCK not-home #-} @@ -133,19 +135,24 @@ newIConv from to rec fn = withCAString to $ \ to_str -> do iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt - return BufferCodec{ - encode = fn iconvt, - recover = rec, - close = iclose, + fn_iconvt ibuf obuf st = case unIO (fn iconvt ibuf obuf) st of + (# st', (prog, ibuf', obuf') #) -> (# st', prog, ibuf', obuf' #) + return BufferCodec# { + encode# = fn_iconvt, + recover# = rec#, + close# = iclose, -- iconv doesn't supply a way to save/restore the state - getState = return (), - setState = const $ return () + getState# = return (), + setState# = const $ return () } + where + rec# ibuf obuf st = case unIO (rec ibuf obuf) st of + (# st', (ibuf', obuf') #) -> (# st', ibuf', obuf' #) -iconvDecode :: IConv -> DecodeBuffer +iconvDecode :: IConv -> Buffer Word8 -> Buffer Char -> IO (CodingProgress, Buffer Word8, Buffer Char) iconvDecode iconv_t ibuf obuf = iconvRecode iconv_t ibuf 0 obuf char_shift -iconvEncode :: IConv -> EncodeBuffer +iconvEncode :: IConv -> Buffer Char -> Buffer Word8 -> IO (CodingProgress, Buffer Char, Buffer Word8) iconvEncode iconv_t ibuf obuf = iconvRecode iconv_t ibuf char_shift obuf 0 iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int ===================================== libraries/base/GHC/IO/Encoding/Latin1.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE NoImplicitPrelude , BangPatterns , NondecreasingIndentation + , UnboxedTuples + , MagicHash #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +58,22 @@ mkLatin1 cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_DF :: CodingFailureMode -> IO (TextDecoder ()) latin1_DF cfm = - return (BufferCodec { - encode = latin1_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_EF cfm = - return (BufferCodec { - encode = latin1_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) latin1_checked :: TextEncoding @@ -85,12 +87,12 @@ mkLatin1_checked cfm = TextEncoding { textEncodingName = "ISO-8859-1", latin1_checked_EF :: CodingFailureMode -> IO (TextEncoder ()) latin1_checked_EF cfm = - return (BufferCodec { - encode = latin1_checked_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = latin1_checked_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -- ----------------------------------------------------------------------------- @@ -108,22 +110,22 @@ mkAscii cfm = TextEncoding { textEncodingName = "ASCII", ascii_DF :: CodingFailureMode -> IO (TextDecoder ()) ascii_DF cfm = - return (BufferCodec { - encode = ascii_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) ascii_EF :: CodingFailureMode -> IO (TextEncoder ()) ascii_EF cfm = - return (BufferCodec { - encode = ascii_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = ascii_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -134,97 +136,115 @@ ascii_EF cfm = -- TODO: Eliminate code duplication between the checked and unchecked -- versions of the decoder or encoder (but don't change the Core!) -latin1_decode :: DecodeBuffer +latin1_decode :: DecodeBuffer# latin1_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -ascii_decode :: DecodeBuffer +ascii_decode :: DecodeBuffer# ascii_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - if c0 > 0x7f then invalid else do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 + if c0 > 0x7f then invalid st1 else do + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -latin1_encode :: EncodeBuffer +latin1_encode :: EncodeBuffer# latin1_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 in - loop ir0 ow0 + loop ir0 ow0 st -latin1_checked_encode :: EncodeBuffer +latin1_checked_encode :: EncodeBuffer# latin1_checked_encode input output = single_byte_checked_encode 0xff input output -ascii_encode :: EncodeBuffer +ascii_encode :: EncodeBuffer# ascii_encode input output = single_byte_checked_encode 0x7f input output -single_byte_checked_encode :: Int -> EncodeBuffer +single_byte_checked_encode :: Int -> EncodeBuffer# single_byte_checked_encode max_legal_char input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if ord c > max_legal_char then invalid else do - writeWord8Buf oraw ow (fromIntegral (ord c)) - loop ir' (ow+1) + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if ord c > max_legal_char then invalid st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (ord c))) st1 + loop ir' (ow+1) st2 where - invalid = done InvalidSequence ir ow + invalid :: EncodingBuffer# + invalid st' = done InvalidSequence ir ow st' in - loop ir0 ow0 + loop ir0 ow0 st {-# INLINE single_byte_checked_encode #-} ===================================== libraries/base/GHC/IO/Encoding/UTF16.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,64 +62,66 @@ mkUTF16 cfm = TextEncoding { textEncodingName = "UTF-16", mkTextDecoder = utf16_DF cfm, mkTextEncoder = utf16_EF cfm } -utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf16_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf16_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf16_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf16_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf16_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf16_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf16_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf16_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf16_encode :: IORef Bool -> EncodeBuffer +utf16_encode :: IORef Bool -> EncodeBuffer# utf16_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf16_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf16_native_encode input output st1 else if os - ow < 2 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom1 - writeWord8Buf oraw (ow+1) bom2 - utf16_native_encode input output{ bufR = ow+2 } + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom2) st3 + utf16_native_encode input output{ bufR = ow+2 } st4 -utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer +utf16_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf16_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 case () of - _ | c0 == bomB && c1 == bomL -> do - writeIORef seen_bom (Just utf16be_decode) - utf16be_decode input{ bufL= ir+2 } output - | c0 == bomL && c1 == bomB -> do - writeIORef seen_bom (Just utf16le_decode) - utf16le_decode input{ bufL= ir+2 } output - | otherwise -> do - writeIORef seen_bom (Just utf16_native_decode) - utf16_native_decode input output + _ | c0 == bomB && c1 == bomL -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16be_decode)) st3 + in utf16be_decode input{ bufL= ir+2 } output st4 + | c0 == bomL && c1 == bomB -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16le_decode)) st3 + in utf16le_decode input{ bufL= ir+2 } output st4 + | otherwise -> + let !(# st4, () #) = unIO (writeIORef seen_bom (Just utf16_native_decode)) st3 + in utf16_native_decode input output st4 bomB, bomL, bom1, bom2 :: Word8 @@ -126,10 +129,10 @@ bomB = 0xfe bomL = 0xff -- choose UTF-16BE by default for UTF-16 output -utf16_native_decode :: DecodeBuffer +utf16_native_decode :: DecodeBuffer# utf16_native_decode = utf16be_decode -utf16_native_encode :: EncodeBuffer +utf16_native_encode :: EncodeBuffer# utf16_native_encode = utf16be_encode bom1 = bomB @@ -149,22 +152,22 @@ mkUTF16be cfm = TextEncoding { textEncodingName = "UTF-16BE", utf16be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16be_DF cfm = - return (BufferCodec { - encode = utf16be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16be_EF cfm = - return (BufferCodec { - encode = utf16be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le :: TextEncoding @@ -178,114 +181,127 @@ mkUTF16le cfm = TextEncoding { textEncodingName = "UTF16-LE", utf16le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf16le_DF cfm = - return (BufferCodec { - encode = utf16le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf16le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf16le_EF cfm = - return (BufferCodec { - encode = utf16le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf16le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf16be_decode :: DecodeBuffer +utf16be_decode :: DecodeBuffer# utf16be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 let x1 = fromIntegral c0 `shiftL` 8 + fromIntegral c1 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c2 `shiftL` 8 + fromIntegral c3 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input { bufL = 0, bufR = 0 } else input { bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_decode :: DecodeBuffer +utf16le_decode :: DecodeBuffer# utf16le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow - | ir + 1 == iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | ir + 1 == iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - let x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + x1 = fromIntegral c1 `shiftL` 8 + fromIntegral c0 if validate1 x1 - then do ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral x1)) - loop (ir+2) ow' - else if iw - ir < 4 then done InputUnderflow ir ow else do - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - let x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 - if not (validate2 x1 x2) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 x1 x2) - loop (ir+4) ow' + then let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral x1))) st2 + in loop (ir+2) ow' st3 + else if iw - ir < 4 then done InputUnderflow ir ow st2 else do + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + x2 = fromIntegral c3 `shiftL` 8 + fromIntegral c2 + if not (validate2 x1 x2) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr2 x1 x2)) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf16be_encode :: EncodeBuffer +utf16be_encode :: EncodeBuffer# utf16be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8)) - writeWord8Buf oraw (ow+1) (fromIntegral x) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral (x `shiftR` 8))) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral x)) st2 + loop ir' (ow+2) st3 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -294,35 +310,39 @@ utf16be_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf16le_encode :: EncodeBuffer +utf16le_encode :: EncodeBuffer# utf16le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 2 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 2 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of - x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow else do - writeWord8Buf oraw ow (fromIntegral x) - writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8)) - loop ir' (ow+2) + x | x < 0x10000 -> if isSurrogate c then done InvalidSequence ir ow st1 else do + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) (fromIntegral (x `shiftR` 8))) st2 + loop ir' (ow+2) st3 | otherwise -> - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let n1 = x - 0x10000 c1 = fromIntegral (n1 `shiftR` 18 + 0xD8) @@ -331,13 +351,13 @@ utf16le_encode c3 = fromIntegral (n2 `shiftR` 8 + 0xDC) c4 = fromIntegral n2 -- - writeWord8Buf oraw ow c2 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c4 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c2) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c4) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) ===================================== libraries/base/GHC/IO/Encoding/UTF32.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -61,68 +62,70 @@ mkUTF32 cfm = TextEncoding { textEncodingName = "UTF-32", mkTextDecoder = utf32_DF cfm, mkTextEncoder = utf32_EF cfm } -utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer)) +utf32_DF :: CodingFailureMode -> IO (TextDecoder (Maybe DecodeBuffer#)) utf32_DF cfm = do seen_bom <- newIORef Nothing - return (BufferCodec { - encode = utf32_decode seen_bom, - recover = recoverDecode cfm, - close = return (), - getState = readIORef seen_bom, - setState = writeIORef seen_bom + return (BufferCodec# { + encode# = utf32_decode seen_bom, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef seen_bom, + setState# = writeIORef seen_bom }) utf32_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf32_EF cfm = do done_bom <- newIORef False - return (BufferCodec { - encode = utf32_encode done_bom, - recover = recoverEncode cfm, - close = return (), - getState = readIORef done_bom, - setState = writeIORef done_bom + return (BufferCodec# { + encode# = utf32_encode done_bom, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef done_bom, + setState# = writeIORef done_bom }) -utf32_encode :: IORef Bool -> EncodeBuffer +utf32_encode :: IORef Bool -> EncodeBuffer# utf32_encode done_bom input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef done_bom - if b then utf32_native_encode input output + let !(# st1, b #) = unIO (readIORef done_bom) st0 + if b then utf32_native_encode input output st1 else if os - ow < 4 - then return (OutputUnderflow, input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef done_bom True - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - writeWord8Buf oraw (ow+3) bom3 - utf32_native_encode input output{ bufR = ow+4 } - -utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer + let !(# st2, () #) = unIO (writeIORef done_bom True) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + !(# st6, () #) = unIO (writeWord8Buf oraw (ow+3) bom3) st5 + utf32_native_encode input output{ bufR = ow+4 } st6 + +utf32_decode :: IORef (Maybe DecodeBuffer#) -> DecodeBuffer# utf32_decode seen_bom input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - mb <- readIORef seen_bom + let !(# st1, mb #) = unIO (readIORef seen_bom) st0 case mb of - Just decode -> decode input output + Just decode -> decode input output st1 Nothing -> - if iw - ir < 4 then return (InputUnderflow, input,output) else do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + if iw - ir < 4 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir ) st1 + !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 + !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 + !(# st5, c3 #) = unIO (readWord8Buf iraw (ir+3)) st4 case () of - _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do - writeIORef seen_bom (Just utf32be_decode) - utf32be_decode input{ bufL= ir+4 } output - _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do - writeIORef seen_bom (Just utf32le_decode) - utf32le_decode input{ bufL= ir+4 } output - | otherwise -> do - writeIORef seen_bom (Just utf32_native_decode) - utf32_native_decode input output + _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32be_decode)) st5 + in utf32be_decode input{ bufL= ir+4 } output st6 + _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32le_decode)) st5 + in utf32le_decode input{ bufL= ir+4 } output st6 + | otherwise -> + let !(# st6, () #) = unIO (writeIORef seen_bom (Just utf32_native_decode)) st5 + in utf32_native_decode input output st6 bom0, bom1, bom2, bom3 :: Word8 @@ -132,10 +135,10 @@ bom2 = 0xfe bom3 = 0xff -- choose UTF-32BE by default for UTF-32 output -utf32_native_decode :: DecodeBuffer +utf32_native_decode :: DecodeBuffer# utf32_native_decode = utf32be_decode -utf32_native_encode :: EncodeBuffer +utf32_native_encode :: EncodeBuffer# utf32_native_encode = utf32be_encode -- ----------------------------------------------------------------------------- @@ -152,22 +155,22 @@ mkUTF32be cfm = TextEncoding { textEncodingName = "UTF-32BE", utf32be_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32be_DF cfm = - return (BufferCodec { - encode = utf32be_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32be_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32be_EF cfm = - return (BufferCodec { - encode = utf32be_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32be_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) @@ -182,128 +185,145 @@ mkUTF32le cfm = TextEncoding { textEncodingName = "UTF-32LE", utf32le_DF :: CodingFailureMode -> IO (TextDecoder ()) utf32le_DF cfm = - return (BufferCodec { - encode = utf32le_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf32le_EF :: CodingFailureMode -> IO (TextEncoder ()) utf32le_EF cfm = - return (BufferCodec { - encode = utf32le_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf32le_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) -utf32be_decode :: DecodeBuffer +utf32be_decode :: DecodeBuffer# utf32be_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c0 c1 c2 c3 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_decode :: DecodeBuffer +utf32le_decode :: DecodeBuffer# utf32le_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | iw - ir < 4 = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | iw - ir < 4 = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir ) st0 + !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 let x1 = chr4 c3 c2 c1 c0 - if not (validate x1) then invalid else do - ow' <- writeCharBuf oraw ow x1 - loop (ir+4) ow' + if not (validate x1) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow x1) st4 + loop (ir+4) ow' st5 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf32be_encode :: EncodeBuffer +utf32be_encode :: EncodeBuffer# utf32be_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c0 - writeWord8Buf oraw (ow+1) c1 - writeWord8Buf oraw (ow+2) c2 - writeWord8Buf oraw (ow+3) c3 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c0) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c1) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c2) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c3) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -utf32le_encode :: EncodeBuffer +utf32le_encode :: EncodeBuffer# utf32le_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ir >= iw = done InputUnderflow ir ow - | os - ow < 4 = done OutputUnderflow ir ow + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL=0, bufR=0 } else input{ bufL=ir } + !ro = output{ bufR=ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ir >= iw = done InputUnderflow ir ow st0 + | os - ow < 4 = done OutputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir - if isSurrogate c then done InvalidSequence ir ow else do + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 + if isSurrogate c then done InvalidSequence ir ow st1 else do let (c0,c1,c2,c3) = ord4 c - writeWord8Buf oraw ow c3 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c1 - writeWord8Buf oraw (ow+3) c0 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c3) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c0) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = ===================================== libraries/base/GHC/IO/Encoding/UTF8.hs ===================================== @@ -3,6 +3,7 @@ , BangPatterns , NondecreasingIndentation , MagicHash + , UnboxedTuples #-} {-# OPTIONS_GHC -funbox-strict-fields #-} @@ -56,22 +57,22 @@ mkUTF8 cfm = TextEncoding { textEncodingName = "UTF-8", utf8_DF :: CodingFailureMode -> IO (TextDecoder ()) utf8_DF cfm = - return (BufferCodec { - encode = utf8_decode, - recover = recoverDecode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_decode, + recover# = recoverDecode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_EF :: CodingFailureMode -> IO (TextEncoder ()) utf8_EF cfm = - return (BufferCodec { - encode = utf8_encode, - recover = recoverEncode cfm, - close = return (), - getState = return (), - setState = const $ return () + return (BufferCodec# { + encode# = utf8_encode, + recover# = recoverEncode# cfm, + close# = return (), + getState# = return (), + setState# = const $ return () }) utf8_bom :: TextEncoding @@ -85,177 +86,188 @@ mkUTF8_bom cfm = TextEncoding { textEncodingName = "UTF-8BOM", utf8_bom_DF :: CodingFailureMode -> IO (TextDecoder Bool) utf8_bom_DF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_decode ref, - recover = recoverDecode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_decode ref, + recover# = recoverDecode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) utf8_bom_EF :: CodingFailureMode -> IO (TextEncoder Bool) utf8_bom_EF cfm = do ref <- newIORef True - return (BufferCodec { - encode = utf8_bom_encode ref, - recover = recoverEncode cfm, - close = return (), - getState = readIORef ref, - setState = writeIORef ref + return (BufferCodec# { + encode# = utf8_bom_encode ref, + recover# = recoverEncode# cfm, + close# = return (), + getState# = readIORef ref, + setState# = writeIORef ref }) -utf8_bom_decode :: IORef Bool -> DecodeBuffer +utf8_bom_decode :: IORef Bool -> DecodeBuffer# utf8_bom_decode ref input at Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } output + st0 = do - first <- readIORef ref + let !(# st1, first #) = unIO (readIORef ref) st0 if not first - then utf8_decode input output + then utf8_decode input output st1 else do - let no_bom = do writeIORef ref False; utf8_decode input output - if iw - ir < 1 then return (InputUnderflow,input,output) else do - c0 <- readWord8Buf iraw ir + let no_bom = let !(# st', () #) = unIO (writeIORef ref False) st1 in utf8_decode input output st' + if iw - ir < 1 then (# st1,InputUnderflow,input,output #) else do + let !(# st2, c0 #) = unIO (readWord8Buf iraw ir) st1 if (c0 /= bom0) then no_bom else do - if iw - ir < 2 then return (InputUnderflow,input,output) else do - c1 <- readWord8Buf iraw (ir+1) + if iw - ir < 2 then (# st2,InputUnderflow,input,output #) else do + let !(# st3, c1 #) = unIO (readWord8Buf iraw (ir+1)) st2 if (c1 /= bom1) then no_bom else do - if iw - ir < 3 then return (InputUnderflow,input,output) else do - c2 <- readWord8Buf iraw (ir+2) + if iw - ir < 3 then (# st3,InputUnderflow,input,output #) else do + let !(# st4, c2 #) = unIO (readWord8Buf iraw (ir+2)) st3 if (c2 /= bom2) then no_bom else do -- found a BOM, ignore it and carry on - writeIORef ref False - utf8_decode input{ bufL = ir + 3 } output + let !(# st5, () #) = unIO (writeIORef ref False) st4 + utf8_decode input{ bufL = ir + 3 } output st5 -utf8_bom_encode :: IORef Bool -> EncodeBuffer +utf8_bom_encode :: IORef Bool -> EncodeBuffer# utf8_bom_encode ref input output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } + st0 = do - b <- readIORef ref - if not b then utf8_encode input output + let !(# st1, b #) = unIO (readIORef ref) st0 + if not b then utf8_encode input output st1 else if os - ow < 3 - then return (OutputUnderflow,input,output) + then (# st1,OutputUnderflow,input,output #) else do - writeIORef ref False - writeWord8Buf oraw ow bom0 - writeWord8Buf oraw (ow+1) bom1 - writeWord8Buf oraw (ow+2) bom2 - utf8_encode input output{ bufR = ow+3 } + let !(# st2, () #) = unIO (writeIORef ref False) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw ow bom0) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+1) bom1) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+2) bom2) st4 + utf8_encode input output{ bufR = ow+3 } st5 bom0, bom1, bom2 :: Word8 bom0 = 0xef bom1 = 0xbb bom2 = 0xbf -utf8_decode :: DecodeBuffer +utf8_decode :: DecodeBuffer# utf8_decode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + loop :: Int -> Int -> DecodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - c0 <- readWord8Buf iraw ir + let !(# st1, c0 #) = unIO (readWord8Buf iraw ir) st0 case c0 of _ | c0 <= 0x7f -> do - ow' <- writeCharBuf oraw ow (unsafeChr (fromIntegral c0)) - loop (ir+1) ow' - | c0 >= 0xc0 && c0 <= 0xc1 -> invalid -- Overlong forms + let !(# st2, ow' #) = unIO (writeCharBuf oraw ow (unsafeChr (fromIntegral c0))) st1 + loop (ir+1) ow' st2 + | c0 >= 0xc0 && c0 <= 0xc1 -> invalid st1 -- Overlong forms | c0 >= 0xc2 && c0 <= 0xdf -> - if iw - ir < 2 then done InputUnderflow ir ow else do - c1 <- readWord8Buf iraw (ir+1) - if (c1 < 0x80 || c1 >= 0xc0) then invalid else do - ow' <- writeCharBuf oraw ow (chr2 c0 c1) - loop (ir+2) ow' + if iw - ir < 2 then done InputUnderflow ir ow st1 else do + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + if (c1 < 0x80 || c1 >= 0xc0) then invalid st2 else do + let !(# st3, ow' #) = unIO (writeCharBuf oraw ow (chr2 c0 c1)) st2 + loop (ir+2) ow' st3 | c0 >= 0xe0 && c0 <= 0xef -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate3 c0 c1 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - if not (validate3 c0 c1 c2) then invalid else do - ow' <- writeCharBuf oraw ow (chr3 c0 c1 c2) - loop (ir+3) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + let !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + if not (validate3 c0 c1 c2) then invalid st3 else do + let !(# st4, ow' #) = unIO (writeCharBuf oraw ow (chr3 c0 c1 c2)) st3 + loop (ir+3) ow' st4 | c0 >= 0xf0 -> case iw - ir of - 1 -> done InputUnderflow ir ow + 1 -> done InputUnderflow ir ow st1 2 -> do -- check for an error even when we don't have -- the full sequence yet (#3341) - c1 <- readWord8Buf iraw (ir+1) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 if not (validate4 c0 c1 0x80 0x80) - then invalid else done InputUnderflow ir ow + then invalid st2 else done InputUnderflow ir ow st2 3 -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 if not (validate4 c0 c1 c2 0x80) - then invalid else done InputUnderflow ir ow + then invalid st3 else done InputUnderflow ir ow st3 _ -> do - c1 <- readWord8Buf iraw (ir+1) - c2 <- readWord8Buf iraw (ir+2) - c3 <- readWord8Buf iraw (ir+3) - if not (validate4 c0 c1 c2 c3) then invalid else do - ow' <- writeCharBuf oraw ow (chr4 c0 c1 c2 c3) - loop (ir+4) ow' + let !(# st2, c1 #) = unIO (readWord8Buf iraw (ir+1)) st1 + !(# st3, c2 #) = unIO (readWord8Buf iraw (ir+2)) st2 + !(# st4, c3 #) = unIO (readWord8Buf iraw (ir+3)) st3 + if not (validate4 c0 c1 c2 c3) then invalid st4 else do + let !(# st5, ow' #) = unIO (writeCharBuf oraw ow (chr4 c0 c1 c2 c3)) st4 + loop (ir+4) ow' st5 | otherwise -> - invalid + invalid st1 where - invalid = done InvalidSequence ir ow + invalid :: DecodingBuffer# + invalid st' = done InvalidSequence ir ow st' -- lambda-lifted, to avoid thunks being built in the inner-loop: - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> DecodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0} else input{ bufL = ir } + !ro = output { bufR = ow } + in (# st', why, ri, ro #) in - loop ir0 ow0 + loop ir0 ow0 st -utf8_encode :: EncodeBuffer +utf8_encode :: EncodeBuffer# utf8_encode input at Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } output at Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } + st = let - done why !ir !ow = return (why, - if ir == iw then input{ bufL=0, bufR=0 } - else input{ bufL=ir }, - output{ bufR=ow }) - loop !ir !ow - | ow >= os = done OutputUnderflow ir ow - | ir >= iw = done InputUnderflow ir ow + {-# NOINLINE done #-} + done :: CodingProgress -> Int -> Int -> EncodingBuffer# + done why !ir !ow st' = + let !ri = if ir == iw then input{ bufL = 0, bufR = 0 } else input{ bufL = ir } + !ro = output{ bufR = ow } + in (# st', why, ri, ro #) + loop :: Int -> Int -> EncodingBuffer# + loop !ir !ow st0 + | ow >= os = done OutputUnderflow ir ow st0 + | ir >= iw = done InputUnderflow ir ow st0 | otherwise = do - (c,ir') <- readCharBuf iraw ir + let !(# st1, (c,ir') #) = unIO (readCharBuf iraw ir) st0 case ord c of x | x <= 0x7F -> do - writeWord8Buf oraw ow (fromIntegral x) - loop ir' (ow+1) + let !(# st2, () #) = unIO (writeWord8Buf oraw ow (fromIntegral x)) st1 + loop ir' (ow+1) st2 | x <= 0x07FF -> - if os - ow < 2 then done OutputUnderflow ir ow else do + if os - ow < 2 then done OutputUnderflow ir ow st1 else do let (c1,c2) = ord2 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - loop ir' (ow+2) - | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow else do - if os - ow < 3 then done OutputUnderflow ir ow else do + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + loop ir' (ow+2) st3 + | x <= 0xFFFF -> if isSurrogate c then done InvalidSequence ir ow st1 else do + if os - ow < 3 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3) = ord3 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - loop ir' (ow+3) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + loop ir' (ow+3) st4 | otherwise -> do - if os - ow < 4 then done OutputUnderflow ir ow else do + if os - ow < 4 then done OutputUnderflow ir ow st1 else do let (c1,c2,c3,c4) = ord4 c - writeWord8Buf oraw ow c1 - writeWord8Buf oraw (ow+1) c2 - writeWord8Buf oraw (ow+2) c3 - writeWord8Buf oraw (ow+3) c4 - loop ir' (ow+4) + !(# st2, () #) = unIO (writeWord8Buf oraw ow c1) st1 + !(# st3, () #) = unIO (writeWord8Buf oraw (ow+1) c2) st2 + !(# st4, () #) = unIO (writeWord8Buf oraw (ow+2) c3) st3 + !(# st5, () #) = unIO (writeWord8Buf oraw (ow+3) c4) st4 + loop ir' (ow+4) st5 in - loop ir0 ow0 + loop ir0 ow0 st -- ----------------------------------------------------------------------------- -- UTF-8 primitives, lifted from Data.Text.Fusion.Utf8 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb1588f66317282deeaf3d3910c17b25b8ff6b0b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb1588f66317282deeaf3d3910c17b25b8ff6b0b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 16:19:27 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 12:19:27 -0400 Subject: [Git][ghc/ghc][master] testsuite/T20137: Avoid impl.-defined behavior Message-ID: <6446ac0fd3fa5_178e74ac2ae19c119658b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 2 changed files: - testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 - testsuite/tests/codeGen/should_run/T20137/T20137C.c Changes: ===================================== testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 ===================================== @@ -5,9 +5,9 @@ 5 6 77777777 -ffffffff88888888 -ffffffff99999999 -ffffffffaaaaaaaa -ffffffffbbbbbbbb +88888888 +99999999 +aaaaaaaa +bbbbbbbb cccccccc -ffffffffdddddddd +dddddddd ===================================== testsuite/tests/codeGen/should_run/T20137/T20137C.c ===================================== @@ -16,19 +16,19 @@ runInteractiveProcess (char *const * args, { // N.B. We don't use %p here since the rendering of this varies across // libc implementations - printf("%" PRIx64 "\n", (uint64_t) args); - printf("%" PRIx64 "\n", (uint64_t) workingDirectory); - printf("%" PRIx64 "\n", (uint64_t) environment); + printf("%" PRIxPTR "\n", (uintptr_t) args); + printf("%" PRIxPTR "\n", (uintptr_t) workingDirectory); + printf("%" PRIxPTR "\n", (uintptr_t) environment); printf("%x\n", fdStdIn); printf("%x\n", fdStdOut); printf("%x\n", fdStdErr); - printf("%" PRIx64 "\n", (uint64_t) pfdStdInput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdOutput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdError); - printf("%" PRIx64 "\n", (uint64_t) childGroup); - printf("%" PRIx64 "\n", (uint64_t) childUser); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdInput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdOutput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdError); + printf("%" PRIxPTR "\n", (uintptr_t) childGroup); + printf("%" PRIxPTR "\n", (uintptr_t) childUser); printf("%x\n", flags); - printf("%" PRIx64 "\n", (uint64_t) failed_doing); + printf("%" PRIxPTR "\n", (uintptr_t) failed_doing); return 0; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/787c6e8c5b96c95ead6cc7c213d12c5983975084 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/787c6e8c5b96c95ead6cc7c213d12c5983975084 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 16:20:00 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 12:20:00 -0400 Subject: [Git][ghc/ghc][master] rts: always build 64-bit atomic ops Message-ID: <6446ac30eaa50_178e74ac14e43c119985@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 6 changed files: - configure.ac - hadrian/src/Rules/Generate.hs - libraries/ghc-prim/cbits/atomic.c - rts/include/stg/Prim.h - rts/rts.cabal.in - testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm Changes: ===================================== configure.ac ===================================== @@ -904,11 +904,6 @@ FP_CHECK_SIZEOF_AND_ALIGNMENT(uint64_t) dnl for use in settings file TargetWordSize=$ac_cv_sizeof_void_p -if test "x$TargetWordSize" = x8; then - AC_SUBST([Cabal64bit],[True]) -else - AC_SUBST([Cabal64bit],[False]) -fi AC_SUBST(TargetWordSize) AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -295,11 +295,6 @@ rtsCabalFlags = mconcat , flag "CabalUseSystemLibFFI" UseSystemFfi , flag "CabalLibffiAdjustors" UseLibffiForAdjustors , flag "CabalLeadingUnderscore" LeadingUnderscore - , interpolateVar "Cabal64bit" $ do - let settingWord :: Setting -> Action Word - settingWord s = read <$> setting s - ws <- settingWord TargetWordSize - return $ toCabalBool (ws == 8) ] where flag = interpolateCabalFlag ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -33,14 +33,12 @@ hs_atomic_add32(StgWord x, StgWord val) return __sync_fetch_and_add((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_add64(StgWord x, StgWord64 val); StgWord64 hs_atomic_add64(StgWord x, StgWord64 val) { return __sync_fetch_and_add((volatile StgWord64 *) x, val); } -#endif // FetchSubByteArrayOp_Int @@ -65,14 +63,12 @@ hs_atomic_sub32(StgWord x, StgWord val) return __sync_fetch_and_sub((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val); StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val) { return __sync_fetch_and_sub((volatile StgWord64 *) x, val); } -#endif // FetchAndByteArrayOp_Int @@ -97,14 +93,12 @@ hs_atomic_and32(StgWord x, StgWord val) return __sync_fetch_and_and((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_and64(StgWord x, StgWord64 val); StgWord64 hs_atomic_and64(StgWord x, StgWord64 val) { return __sync_fetch_and_and((volatile StgWord64 *) x, val); } -#endif // FetchNandByteArrayOp_Int @@ -206,7 +200,6 @@ hs_atomic_nand32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val); StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val) @@ -217,7 +210,6 @@ hs_atomic_nand64(StgWord x, StgWord64 val) CAS_NAND((volatile StgWord64 *) x, val); #endif } -#endif #pragma GCC diagnostic pop @@ -244,14 +236,12 @@ hs_atomic_or32(StgWord x, StgWord val) return __sync_fetch_and_or((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_or64(StgWord x, StgWord64 val); StgWord64 hs_atomic_or64(StgWord x, StgWord64 val) { return __sync_fetch_and_or((volatile StgWord64 *) x, val); } -#endif // FetchXorByteArrayOp_Int @@ -276,14 +266,12 @@ hs_atomic_xor32(StgWord x, StgWord val) return __sync_fetch_and_xor((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val); StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val) { return __sync_fetch_and_xor((volatile StgWord64 *) x, val); } -#endif // CasByteArrayOp_Int @@ -338,15 +326,13 @@ hs_xchg32(StgWord x, StgWord val) return (StgWord) __atomic_exchange_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST); } -#if WORD_SIZE_IN_BITS == 64 //GCC provides this even on 32bit, but StgWord is still 32 bits. -extern StgWord hs_xchg64(StgWord x, StgWord val); -StgWord -hs_xchg64(StgWord x, StgWord val) +extern StgWord64 hs_xchg64(StgWord x, StgWord64 val); +StgWord64 +hs_xchg64(StgWord x, StgWord64 val) { - return (StgWord) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); + return (StgWord64) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); } -#endif // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -391,7 +377,6 @@ hs_atomicread32(StgWord x) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomicread64(StgWord x); StgWord64 hs_atomicread64(StgWord x) @@ -402,7 +387,6 @@ hs_atomicread64(StgWord x) return __sync_add_and_fetch((StgWord64 *) x, 0); #endif } -#endif // AtomicWriteByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -441,7 +425,6 @@ hs_atomicwrite32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern void hs_atomicwrite64(StgWord x, StgWord64 val); void hs_atomicwrite64(StgWord x, StgWord64 val) @@ -452,6 +435,5 @@ hs_atomicwrite64(StgWord x, StgWord64 val) while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val)); #endif } -#endif #endif ===================================== rts/include/stg/Prim.h ===================================== @@ -53,7 +53,7 @@ void hs_atomicwrite64(StgWord x, StgWord64 val); StgWord hs_xchg8(StgWord x, StgWord val); StgWord hs_xchg16(StgWord x, StgWord val); StgWord hs_xchg32(StgWord x, StgWord val); -StgWord hs_xchg64(StgWord x, StgWord val); +StgWord64 hs_xchg64(StgWord x, StgWord64 val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== rts/rts.cabal.in ===================================== @@ -45,8 +45,6 @@ flag libdw default: @CabalHaveLibdw@ flag libnuma default: @CabalHaveLibNuma@ -flag 64bit - default: @Cabal64bit@ flag leading-underscore default: @CabalLeadingUnderscore@ flag smp @@ -289,27 +287,6 @@ library stg/Types.h -- See Note [Undefined symbols in the RTS] - if flag(64bit) - if flag(leading-underscore) - ld-options: - "-Wl,-u,_hs_atomic_add64" - "-Wl,-u,_hs_atomic_sub64" - "-Wl,-u,_hs_atomic_and64" - "-Wl,-u,_hs_atomic_nand64" - "-Wl,-u,_hs_atomic_or64" - "-Wl,-u,_hs_atomic_xor64" - "-Wl,-u,_hs_atomicread64" - "-Wl,-u,_hs_atomicwrite64" - else - ld-options: - "-Wl,-u,hs_atomic_add64" - "-Wl,-u,hs_atomic_sub64" - "-Wl,-u,hs_atomic_and64" - "-Wl,-u,hs_atomic_nand64" - "-Wl,-u,hs_atomic_or64" - "-Wl,-u,hs_atomic_xor64" - "-Wl,-u,hs_atomicread64" - "-Wl,-u,hs_atomicwrite64" if flag(leading-underscore) ld-options: "-Wl,-u,_base_GHCziTopHandler_runIO_closure" @@ -357,21 +334,27 @@ library "-Wl,-u,_hs_atomic_add8" "-Wl,-u,_hs_atomic_add16" "-Wl,-u,_hs_atomic_add32" + "-Wl,-u,_hs_atomic_add64" "-Wl,-u,_hs_atomic_sub8" "-Wl,-u,_hs_atomic_sub16" "-Wl,-u,_hs_atomic_sub32" + "-Wl,-u,_hs_atomic_sub64" "-Wl,-u,_hs_atomic_and8" "-Wl,-u,_hs_atomic_and16" "-Wl,-u,_hs_atomic_and32" + "-Wl,-u,_hs_atomic_and64" "-Wl,-u,_hs_atomic_nand8" "-Wl,-u,_hs_atomic_nand16" "-Wl,-u,_hs_atomic_nand32" + "-Wl,-u,_hs_atomic_nand64" "-Wl,-u,_hs_atomic_or8" "-Wl,-u,_hs_atomic_or16" "-Wl,-u,_hs_atomic_or32" + "-Wl,-u,_hs_atomic_or64" "-Wl,-u,_hs_atomic_xor8" "-Wl,-u,_hs_atomic_xor16" "-Wl,-u,_hs_atomic_xor32" + "-Wl,-u,_hs_atomic_xor64" "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" @@ -383,9 +366,11 @@ library "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" + "-Wl,-u,_hs_atomicread64" "-Wl,-u,_hs_atomicwrite8" "-Wl,-u,_hs_atomicwrite16" "-Wl,-u,_hs_atomicwrite32" + "-Wl,-u,_hs_atomicwrite64" "-Wl,-u,_base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) @@ -440,21 +425,27 @@ library "-Wl,-u,hs_atomic_add8" "-Wl,-u,hs_atomic_add16" "-Wl,-u,hs_atomic_add32" + "-Wl,-u,hs_atomic_add64" "-Wl,-u,hs_atomic_sub8" "-Wl,-u,hs_atomic_sub16" "-Wl,-u,hs_atomic_sub32" + "-Wl,-u,hs_atomic_sub64" "-Wl,-u,hs_atomic_and8" "-Wl,-u,hs_atomic_and16" "-Wl,-u,hs_atomic_and32" + "-Wl,-u,hs_atomic_and64" "-Wl,-u,hs_atomic_nand8" "-Wl,-u,hs_atomic_nand16" "-Wl,-u,hs_atomic_nand32" + "-Wl,-u,hs_atomic_nand64" "-Wl,-u,hs_atomic_or8" "-Wl,-u,hs_atomic_or16" "-Wl,-u,hs_atomic_or32" + "-Wl,-u,hs_atomic_or64" "-Wl,-u,hs_atomic_xor8" "-Wl,-u,hs_atomic_xor16" "-Wl,-u,hs_atomic_xor32" + "-Wl,-u,hs_atomic_xor64" "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" @@ -466,9 +457,11 @@ library "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" + "-Wl,-u,hs_atomicread64" "-Wl,-u,hs_atomicwrite8" "-Wl,-u,hs_atomicwrite16" "-Wl,-u,hs_atomicwrite32" + "-Wl,-u,hs_atomicwrite64" "-Wl,-u,base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) ===================================== testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm ===================================== @@ -7,17 +7,17 @@ cmm_foo64 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits64 x; + I64 x; - prim %store_seqcst64(q, 42); - (x) = prim %fetch_add64(q, 5); - (x) = prim %fetch_sub64(q, 10); - (x) = prim %fetch_and64(q, 120); - (x) = prim %fetch_or64(q, 2); - (x) = prim %fetch_xor64(q, 33); - (x) = prim %fetch_nand64(q, 127); + prim %store_seqcst64(q, 42 :: I64); + (x) = prim %fetch_add64(q, 5 :: I64); + (x) = prim %fetch_sub64(q, 10 :: I64); + (x) = prim %fetch_and64(q, 120 :: I64); + (x) = prim %fetch_or64(q, 2 :: I64); + (x) = prim %fetch_xor64(q, 33 :: I64); + (x) = prim %fetch_nand64(q, 127 :: I64); (x) = prim %load_seqcst64(q); return (x); } @@ -26,9 +26,9 @@ cmm_foo32 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits32 x; + I32 x; prim %store_seqcst32(q, 42); (x) = prim %fetch_add32(q, 5); @@ -45,9 +45,9 @@ cmm_foo16 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits16 x; + I16 x; prim %store_seqcst16(q, 42); (x) = prim %fetch_add16(q, 5); @@ -64,9 +64,9 @@ cmm_foo8 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits8 x; + I8 x; prim %store_seqcst8(q, 42); (x) = prim %fetch_add8(q, 5); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87095f6a283d95016f66f4a14a3da923c394877c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87095f6a283d95016f66f4a14a3da923c394877c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 16:20:35 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 12:20:35 -0400 Subject: [Git][ghc/ghc][master] compiler: don't install signal handlers when the host platform doesn't have signals Message-ID: <6446ac53e0ccf_178e74ac3a7eb812031d0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1 changed file: - compiler/GHC/Utils/Panic.hs Changes: ===================================== compiler/GHC/Utils/Panic.hs ===================================== @@ -7,6 +7,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables, LambdaCase #-} +#include + -- | Defines basic functions for printing error messages. -- -- It's hard to put these functions anywhere else without causing @@ -236,6 +238,11 @@ signalHandlersRefCount = unsafePerformIO $ newMVar (0,Nothing) -- | Temporarily install standard signal handlers for catching ^C, which just -- throw an exception in the current thread. withSignalHandlers :: ExceptionMonad m => m a -> m a +#if !defined(HAVE_SIGNAL_H) +-- No signal functionality exist on the host platform (e.g. on +-- wasm32-wasi), so don't attempt to set up signal handlers +withSignalHandlers = id +#else withSignalHandlers act = do main_thread <- liftIO myThreadId wtid <- liftIO (mkWeakThreadId main_thread) @@ -295,6 +302,7 @@ withSignalHandlers act = do mayInstallHandlers act `MC.finally` mayUninstallHandlers +#endif callStackDoc :: HasCallStack => SDoc callStackDoc = prettyCallStackDoc callStack View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2685a12d462573ce23ef7f4356a2f8c95ef63e1d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2685a12d462573ce23ef7f4356a2f8c95ef63e1d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 16:51:28 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 12:51:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: testsuite/T20137: Avoid impl.-defined behavior Message-ID: <6446b3909e61d_178e74ad1aca18120752a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - e9a4c9cc by Cheng Shao at 2023-04-24T12:51:17-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - b64bfeeb by Bodigrim at 2023-04-24T12:51:21-04:00 Add since pragma to Data.Functor.unzip - - - - - 11 changed files: - compiler/GHC/Utils/Panic.hs - configure.ac - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/Data/Functor.hs - libraries/ghc-prim/cbits/atomic.c - rts/include/stg/Prim.h - rts/rts.cabal.in - testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm - testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 - testsuite/tests/codeGen/should_run/T20137/T20137C.c Changes: ===================================== compiler/GHC/Utils/Panic.hs ===================================== @@ -7,6 +7,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables, LambdaCase #-} +#include + -- | Defines basic functions for printing error messages. -- -- It's hard to put these functions anywhere else without causing @@ -236,6 +238,11 @@ signalHandlersRefCount = unsafePerformIO $ newMVar (0,Nothing) -- | Temporarily install standard signal handlers for catching ^C, which just -- throw an exception in the current thread. withSignalHandlers :: ExceptionMonad m => m a -> m a +#if !defined(HAVE_SIGNAL_H) +-- No signal functionality exist on the host platform (e.g. on +-- wasm32-wasi), so don't attempt to set up signal handlers +withSignalHandlers = id +#else withSignalHandlers act = do main_thread <- liftIO myThreadId wtid <- liftIO (mkWeakThreadId main_thread) @@ -295,6 +302,7 @@ withSignalHandlers act = do mayInstallHandlers act `MC.finally` mayUninstallHandlers +#endif callStackDoc :: HasCallStack => SDoc callStackDoc = prettyCallStackDoc callStack ===================================== configure.ac ===================================== @@ -904,11 +904,6 @@ FP_CHECK_SIZEOF_AND_ALIGNMENT(uint64_t) dnl for use in settings file TargetWordSize=$ac_cv_sizeof_void_p -if test "x$TargetWordSize" = x8; then - AC_SUBST([Cabal64bit],[True]) -else - AC_SUBST([Cabal64bit],[False]) -fi AC_SUBST(TargetWordSize) AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -295,11 +295,6 @@ rtsCabalFlags = mconcat , flag "CabalUseSystemLibFFI" UseSystemFfi , flag "CabalLibffiAdjustors" UseLibffiForAdjustors , flag "CabalLeadingUnderscore" LeadingUnderscore - , interpolateVar "Cabal64bit" $ do - let settingWord :: Setting -> Action Word - settingWord s = read <$> setting s - ws <- settingWord TargetWordSize - return $ toCabalBool (ws == 8) ] where flag = interpolateCabalFlag ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -315,6 +315,7 @@ getTestArgs = do bindir <- expr $ getBinaryDirectory (testCompiler args) compiler <- expr $ getCompilerPath (testCompiler args) globalVerbosity <- shakeVerbosity <$> expr getShakeOptions + cross_prefix <- expr crossPrefix -- the testsuite driver will itself tell us if we need to generate the docs target -- So we always pass the haddock path if the hadrian configuration allows us to build -- docs @@ -354,12 +355,12 @@ getTestArgs = do Just verbosity -> Just $ "--verbose=" ++ verbosity wayArgs = map ("--way=" ++) (testWays args) compilerArg = ["--config", "compiler=" ++ show (compiler)] - ghcPkgArg = ["--config", "ghc_pkg=" ++ show (bindir -/- "ghc-pkg" <.> exe)] + ghcPkgArg = ["--config", "ghc_pkg=" ++ show (bindir -/- (cross_prefix <> "ghc-pkg") <.> exe)] haddockArg = if haveDocs - then [ "--config", "haddock=" ++ show (bindir -/- "haddock" <.> exe) ] + then [ "--config", "haddock=" ++ show (bindir -/- (cross_prefix <> "haddock") <.> exe) ] else [ "--config", "haddock=" ] - hp2psArg = ["--config", "hp2ps=" ++ show (bindir -/- "hp2ps" <.> exe)] - hpcArg = ["--config", "hpc=" ++ show (bindir -/- "hpc" <.> exe)] + hp2psArg = ["--config", "hp2ps=" ++ show (bindir -/- (cross_prefix <> "hp2ps") <.> exe)] + hpcArg = ["--config", "hpc=" ++ show (bindir -/- (cross_prefix <> "hpc") <.> exe)] inTreeArg = [ "-e", "config.in_tree_compiler=" ++ show (isInTreeCompiler (testCompiler args) || testHasInTreeFiles args) ] ===================================== libraries/base/Data/Functor.hs ===================================== @@ -161,7 +161,10 @@ infixl 4 $> ($>) :: Functor f => f a -> b -> f b ($>) = flip (<$) -unzip :: Functor f => f (a,b) -> (f a, f b) +-- | Generalization of @Data.List.@'Data.List.unzip'. +-- +-- @since 4.19.0.0 +unzip :: Functor f => f (a, b) -> (f a, f b) unzip xs = (fst <$> xs, snd <$> xs) -- | @'void' value@ discards or ignores the result of evaluation, such ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -33,14 +33,12 @@ hs_atomic_add32(StgWord x, StgWord val) return __sync_fetch_and_add((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_add64(StgWord x, StgWord64 val); StgWord64 hs_atomic_add64(StgWord x, StgWord64 val) { return __sync_fetch_and_add((volatile StgWord64 *) x, val); } -#endif // FetchSubByteArrayOp_Int @@ -65,14 +63,12 @@ hs_atomic_sub32(StgWord x, StgWord val) return __sync_fetch_and_sub((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val); StgWord64 hs_atomic_sub64(StgWord x, StgWord64 val) { return __sync_fetch_and_sub((volatile StgWord64 *) x, val); } -#endif // FetchAndByteArrayOp_Int @@ -97,14 +93,12 @@ hs_atomic_and32(StgWord x, StgWord val) return __sync_fetch_and_and((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_and64(StgWord x, StgWord64 val); StgWord64 hs_atomic_and64(StgWord x, StgWord64 val) { return __sync_fetch_and_and((volatile StgWord64 *) x, val); } -#endif // FetchNandByteArrayOp_Int @@ -206,7 +200,6 @@ hs_atomic_nand32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val); StgWord64 hs_atomic_nand64(StgWord x, StgWord64 val) @@ -217,7 +210,6 @@ hs_atomic_nand64(StgWord x, StgWord64 val) CAS_NAND((volatile StgWord64 *) x, val); #endif } -#endif #pragma GCC diagnostic pop @@ -244,14 +236,12 @@ hs_atomic_or32(StgWord x, StgWord val) return __sync_fetch_and_or((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_or64(StgWord x, StgWord64 val); StgWord64 hs_atomic_or64(StgWord x, StgWord64 val) { return __sync_fetch_and_or((volatile StgWord64 *) x, val); } -#endif // FetchXorByteArrayOp_Int @@ -276,14 +266,12 @@ hs_atomic_xor32(StgWord x, StgWord val) return __sync_fetch_and_xor((volatile StgWord32 *) x, (StgWord32) val); } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val); StgWord64 hs_atomic_xor64(StgWord x, StgWord64 val) { return __sync_fetch_and_xor((volatile StgWord64 *) x, val); } -#endif // CasByteArrayOp_Int @@ -338,15 +326,13 @@ hs_xchg32(StgWord x, StgWord val) return (StgWord) __atomic_exchange_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST); } -#if WORD_SIZE_IN_BITS == 64 //GCC provides this even on 32bit, but StgWord is still 32 bits. -extern StgWord hs_xchg64(StgWord x, StgWord val); -StgWord -hs_xchg64(StgWord x, StgWord val) +extern StgWord64 hs_xchg64(StgWord x, StgWord64 val); +StgWord64 +hs_xchg64(StgWord x, StgWord64 val) { - return (StgWord) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); + return (StgWord64) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); } -#endif // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -391,7 +377,6 @@ hs_atomicread32(StgWord x) #endif } -#if WORD_SIZE_IN_BITS == 64 extern StgWord64 hs_atomicread64(StgWord x); StgWord64 hs_atomicread64(StgWord x) @@ -402,7 +387,6 @@ hs_atomicread64(StgWord x) return __sync_add_and_fetch((StgWord64 *) x, 0); #endif } -#endif // AtomicWriteByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) @@ -441,7 +425,6 @@ hs_atomicwrite32(StgWord x, StgWord val) #endif } -#if WORD_SIZE_IN_BITS == 64 extern void hs_atomicwrite64(StgWord x, StgWord64 val); void hs_atomicwrite64(StgWord x, StgWord64 val) @@ -452,6 +435,5 @@ hs_atomicwrite64(StgWord x, StgWord64 val) while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val)); #endif } -#endif #endif ===================================== rts/include/stg/Prim.h ===================================== @@ -53,7 +53,7 @@ void hs_atomicwrite64(StgWord x, StgWord64 val); StgWord hs_xchg8(StgWord x, StgWord val); StgWord hs_xchg16(StgWord x, StgWord val); StgWord hs_xchg32(StgWord x, StgWord val); -StgWord hs_xchg64(StgWord x, StgWord val); +StgWord64 hs_xchg64(StgWord x, StgWord64 val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== rts/rts.cabal.in ===================================== @@ -45,8 +45,6 @@ flag libdw default: @CabalHaveLibdw@ flag libnuma default: @CabalHaveLibNuma@ -flag 64bit - default: @Cabal64bit@ flag leading-underscore default: @CabalLeadingUnderscore@ flag smp @@ -289,27 +287,6 @@ library stg/Types.h -- See Note [Undefined symbols in the RTS] - if flag(64bit) - if flag(leading-underscore) - ld-options: - "-Wl,-u,_hs_atomic_add64" - "-Wl,-u,_hs_atomic_sub64" - "-Wl,-u,_hs_atomic_and64" - "-Wl,-u,_hs_atomic_nand64" - "-Wl,-u,_hs_atomic_or64" - "-Wl,-u,_hs_atomic_xor64" - "-Wl,-u,_hs_atomicread64" - "-Wl,-u,_hs_atomicwrite64" - else - ld-options: - "-Wl,-u,hs_atomic_add64" - "-Wl,-u,hs_atomic_sub64" - "-Wl,-u,hs_atomic_and64" - "-Wl,-u,hs_atomic_nand64" - "-Wl,-u,hs_atomic_or64" - "-Wl,-u,hs_atomic_xor64" - "-Wl,-u,hs_atomicread64" - "-Wl,-u,hs_atomicwrite64" if flag(leading-underscore) ld-options: "-Wl,-u,_base_GHCziTopHandler_runIO_closure" @@ -357,21 +334,27 @@ library "-Wl,-u,_hs_atomic_add8" "-Wl,-u,_hs_atomic_add16" "-Wl,-u,_hs_atomic_add32" + "-Wl,-u,_hs_atomic_add64" "-Wl,-u,_hs_atomic_sub8" "-Wl,-u,_hs_atomic_sub16" "-Wl,-u,_hs_atomic_sub32" + "-Wl,-u,_hs_atomic_sub64" "-Wl,-u,_hs_atomic_and8" "-Wl,-u,_hs_atomic_and16" "-Wl,-u,_hs_atomic_and32" + "-Wl,-u,_hs_atomic_and64" "-Wl,-u,_hs_atomic_nand8" "-Wl,-u,_hs_atomic_nand16" "-Wl,-u,_hs_atomic_nand32" + "-Wl,-u,_hs_atomic_nand64" "-Wl,-u,_hs_atomic_or8" "-Wl,-u,_hs_atomic_or16" "-Wl,-u,_hs_atomic_or32" + "-Wl,-u,_hs_atomic_or64" "-Wl,-u,_hs_atomic_xor8" "-Wl,-u,_hs_atomic_xor16" "-Wl,-u,_hs_atomic_xor32" + "-Wl,-u,_hs_atomic_xor64" "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" @@ -383,9 +366,11 @@ library "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" + "-Wl,-u,_hs_atomicread64" "-Wl,-u,_hs_atomicwrite8" "-Wl,-u,_hs_atomicwrite16" "-Wl,-u,_hs_atomicwrite32" + "-Wl,-u,_hs_atomicwrite64" "-Wl,-u,_base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) @@ -440,21 +425,27 @@ library "-Wl,-u,hs_atomic_add8" "-Wl,-u,hs_atomic_add16" "-Wl,-u,hs_atomic_add32" + "-Wl,-u,hs_atomic_add64" "-Wl,-u,hs_atomic_sub8" "-Wl,-u,hs_atomic_sub16" "-Wl,-u,hs_atomic_sub32" + "-Wl,-u,hs_atomic_sub64" "-Wl,-u,hs_atomic_and8" "-Wl,-u,hs_atomic_and16" "-Wl,-u,hs_atomic_and32" + "-Wl,-u,hs_atomic_and64" "-Wl,-u,hs_atomic_nand8" "-Wl,-u,hs_atomic_nand16" "-Wl,-u,hs_atomic_nand32" + "-Wl,-u,hs_atomic_nand64" "-Wl,-u,hs_atomic_or8" "-Wl,-u,hs_atomic_or16" "-Wl,-u,hs_atomic_or32" + "-Wl,-u,hs_atomic_or64" "-Wl,-u,hs_atomic_xor8" "-Wl,-u,hs_atomic_xor16" "-Wl,-u,hs_atomic_xor32" + "-Wl,-u,hs_atomic_xor64" "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" @@ -466,9 +457,11 @@ library "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" + "-Wl,-u,hs_atomicread64" "-Wl,-u,hs_atomicwrite8" "-Wl,-u,hs_atomicwrite16" "-Wl,-u,hs_atomicwrite32" + "-Wl,-u,hs_atomicwrite64" "-Wl,-u,base_GHCziStackziCloneStack_StackSnapshot_closure" if flag(find-ptr) ===================================== testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm ===================================== @@ -7,17 +7,17 @@ cmm_foo64 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits64 x; + I64 x; - prim %store_seqcst64(q, 42); - (x) = prim %fetch_add64(q, 5); - (x) = prim %fetch_sub64(q, 10); - (x) = prim %fetch_and64(q, 120); - (x) = prim %fetch_or64(q, 2); - (x) = prim %fetch_xor64(q, 33); - (x) = prim %fetch_nand64(q, 127); + prim %store_seqcst64(q, 42 :: I64); + (x) = prim %fetch_add64(q, 5 :: I64); + (x) = prim %fetch_sub64(q, 10 :: I64); + (x) = prim %fetch_and64(q, 120 :: I64); + (x) = prim %fetch_or64(q, 2 :: I64); + (x) = prim %fetch_xor64(q, 33 :: I64); + (x) = prim %fetch_nand64(q, 127 :: I64); (x) = prim %load_seqcst64(q); return (x); } @@ -26,9 +26,9 @@ cmm_foo32 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits32 x; + I32 x; prim %store_seqcst32(q, 42); (x) = prim %fetch_add32(q, 5); @@ -45,9 +45,9 @@ cmm_foo16 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits16 x; + I16 x; prim %store_seqcst16(q, 42); (x) = prim %fetch_add16(q, 5); @@ -64,9 +64,9 @@ cmm_foo8 (P_ p) { // p points to a ByteArray header, q points to its first element P_ q; - q = p + SIZEOF_StgHeader + WDS(1); + q = p + SIZEOF_StgHeader + OFFSET_StgArrBytes_payload; - bits8 x; + I8 x; prim %store_seqcst8(q, 42); (x) = prim %fetch_add8(q, 5); ===================================== testsuite/tests/codeGen/should_run/T20137/T20137.stdout-ws-32 ===================================== @@ -5,9 +5,9 @@ 5 6 77777777 -ffffffff88888888 -ffffffff99999999 -ffffffffaaaaaaaa -ffffffffbbbbbbbb +88888888 +99999999 +aaaaaaaa +bbbbbbbb cccccccc -ffffffffdddddddd +dddddddd ===================================== testsuite/tests/codeGen/should_run/T20137/T20137C.c ===================================== @@ -16,19 +16,19 @@ runInteractiveProcess (char *const * args, { // N.B. We don't use %p here since the rendering of this varies across // libc implementations - printf("%" PRIx64 "\n", (uint64_t) args); - printf("%" PRIx64 "\n", (uint64_t) workingDirectory); - printf("%" PRIx64 "\n", (uint64_t) environment); + printf("%" PRIxPTR "\n", (uintptr_t) args); + printf("%" PRIxPTR "\n", (uintptr_t) workingDirectory); + printf("%" PRIxPTR "\n", (uintptr_t) environment); printf("%x\n", fdStdIn); printf("%x\n", fdStdOut); printf("%x\n", fdStdErr); - printf("%" PRIx64 "\n", (uint64_t) pfdStdInput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdOutput); - printf("%" PRIx64 "\n", (uint64_t) pfdStdError); - printf("%" PRIx64 "\n", (uint64_t) childGroup); - printf("%" PRIx64 "\n", (uint64_t) childUser); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdInput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdOutput); + printf("%" PRIxPTR "\n", (uintptr_t) pfdStdError); + printf("%" PRIxPTR "\n", (uintptr_t) childGroup); + printf("%" PRIxPTR "\n", (uintptr_t) childUser); printf("%x\n", flags); - printf("%" PRIx64 "\n", (uint64_t) failed_doing); + printf("%" PRIxPTR "\n", (uintptr_t) failed_doing); return 0; } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d93729979787f001b74e79f489a910915bc2195...b64bfeeb2f05402cfb8e3e52e464e4e43c164801 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2d93729979787f001b74e79f489a910915bc2195...b64bfeeb2f05402cfb8e3e52e464e4e43c164801 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 18:01:27 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Mon, 24 Apr 2023 14:01:27 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/unitidset Message-ID: <6446c3f71653e_178e74ae4eaa801220927@gitlab.mail> Josh Meredith pushed new branch wip/unitidset at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/unitidset You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 18:41:11 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Mon, 24 Apr 2023 14:41:11 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <6446cd474eaeb_178e74af1aa61c1231737@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 07e1a60a by Sebastian Graf at 2023-04-24T20:37:13+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. That's why the test results in T13143, T19969 and T22112 change. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 12 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/deSugar/should_compile/T19969.stderr - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T22112.stderr - testsuite/tests/stranal/should_compile/T18894.stderr - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/deSugar/should_compile/T19969.stderr ===================================== @@ -6,7 +6,7 @@ Result size of Tidy Core Rec { -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} f [Occ=LoopBreaker] :: [Int] -> [Int] -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] +[GblId, Arity=1, Str=b{rh0->S}, Cpr=b, Unf=OtherCon []] f = \ (x :: [Int]) -> f x end Rec } @@ -14,10 +14,10 @@ end Rec } g [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, - Str=b, + Str=b{rh0->S}, Cpr=b, - Unf=Unf{Src=StableUser, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableUser, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) Tmpl= f}] g = f @@ -26,10 +26,10 @@ g = f h [InlPrag=INLINE (sat-args=1)] :: [Int] -> [Int] [GblId, Arity=1, - Str=b, + Str=b{rh0->S}, Cpr=b, - Unf=Unf{Src=StableUser, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableUser, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=False,boring_ok=True) Tmpl= f}] h = f ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -7,7 +7,7 @@ Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. (# #) -> a -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] +[GblId, Arity=1, Str=b{sBp->S}, Cpr=b, Unf=OtherCon []] T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) end Rec } @@ -15,7 +15,7 @@ end Rec } f [InlPrag=NOINLINE[final]] :: forall a. Int -> a [GblId, Arity=1, - Str=b, + Str=b{sBp->S}, Cpr=b, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, @@ -66,7 +66,7 @@ T13143.$trModule -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} lvl :: Int -[GblId, Str=b, Cpr=b] +[GblId, Str=b{sBp->S}, Cpr=b] lvl = T13143.$wf @Int GHC.Prim.(##) Rec { ===================================== testsuite/tests/simplCore/should_compile/T22112.stderr ===================================== @@ -6,7 +6,7 @@ Result size of Tidy Core Rec { -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} foo [Occ=LoopBreaker] :: () -> () -[GblId, Str=b, Cpr=b] +[GblId, Str=b{r1->S}, Cpr=b] foo = foo end Rec } ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07e1a60ae86cd1a2e40fa198491fdb3e85a72635 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07e1a60ae86cd1a2e40fa198491fdb3e85a72635 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 19:10:06 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 24 Apr 2023 15:10:06 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Fix register allocation bug Message-ID: <6446d40e9773b_178e74af9160401232239@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: f3d1472c by Sven Tennie at 2023-04-24T19:09:14+00:00 Fix register allocation bug - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs - compiler/GHC/CmmToAsm/RISCV64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -139,8 +139,12 @@ pprInstr platform instr = case instr of -- see Note [dualLine and dualDoc] in GHC.Utils.Outputable NEWBLOCK _ -> error "pprInstr: NEWBLOCK" LDATA _ _ -> error "pprInstr: LDATA" + PUSH_STACK_FRAME -> error "pprInstr: PUSH_STACK_FRAME" + POP_STACK_FRAME -> error "pprInstr: POP_STACK_FRAME" J label -> line $ pprJ label LI reg immediate -> line $ pprLI reg immediate + LA reg label -> error $ "pprInstr: LA " ++ show reg ++ " " ++ show label + MV dst src -> error $ "pprInstr: MV " ++ show dst ++ " " ++ show src where pprLI :: IsLine doc => Reg -> Integer -> doc pprLI reg immediate = text "\tli" <+> pprReg reg <> char ',' <+> (text.show) immediate ===================================== compiler/GHC/CmmToAsm/RISCV64/Regs.hs ===================================== @@ -8,7 +8,7 @@ import GHC.Platform import GHC.Platform.Regs allMachRegNos :: [RegNo] -allMachRegNos = [1..31] ++ [32..63] +allMachRegNos = [0..31] ++ [32..63] -- argRegs is the set of regs which are read for an n-argument call to C. allGpArgRegs :: [Reg] ===================================== compiler/GHC/CmmToAsm/Reg/Linear/RISCV64.hs ===================================== @@ -52,7 +52,7 @@ getFreeRegs cls (FreeRegs g f) -- TODO: how to handle small floats? | RcFloat <- cls = [] -- For now we only support double and integer registers, floats will need to be promoted. | RcDouble <- cls = go 32 f 31 - | RcInteger <- cls = go 1 g 30 + | RcInteger <- cls = go 0 g 30 where go _ _ i | i < 0 = [] go off x i | testBit x i = RealRegSingle (off + i) : (go off x $! i - 1) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f3d1472c5e71d6b669fea8854f5ea3d420f3bdae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f3d1472c5e71d6b669fea8854f5ea3d420f3bdae You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 20:02:31 2023 From: gitlab at gitlab.haskell.org (Joachim Breitner (@nomeata)) Date: Mon, 24 Apr 2023 16:02:31 -0400 Subject: [Git][ghc/ghc] Pushed new branch joachim/wip/ghc-all-in-one Message-ID: <6446e05798a08_178e74b0876e681233938@gitlab.mail> Joachim Breitner pushed new branch joachim/wip/ghc-all-in-one at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/joachim/wip/ghc-all-in-one You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 20:21:45 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 16:21:45 -0400 Subject: [Git][ghc/ghc][master] hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC Message-ID: <6446e4d967288_178e74b10f68181237575@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1 changed file: - hadrian/src/Settings/Builders/RunTest.hs Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -315,6 +315,7 @@ getTestArgs = do bindir <- expr $ getBinaryDirectory (testCompiler args) compiler <- expr $ getCompilerPath (testCompiler args) globalVerbosity <- shakeVerbosity <$> expr getShakeOptions + cross_prefix <- expr crossPrefix -- the testsuite driver will itself tell us if we need to generate the docs target -- So we always pass the haddock path if the hadrian configuration allows us to build -- docs @@ -354,12 +355,12 @@ getTestArgs = do Just verbosity -> Just $ "--verbose=" ++ verbosity wayArgs = map ("--way=" ++) (testWays args) compilerArg = ["--config", "compiler=" ++ show (compiler)] - ghcPkgArg = ["--config", "ghc_pkg=" ++ show (bindir -/- "ghc-pkg" <.> exe)] + ghcPkgArg = ["--config", "ghc_pkg=" ++ show (bindir -/- (cross_prefix <> "ghc-pkg") <.> exe)] haddockArg = if haveDocs - then [ "--config", "haddock=" ++ show (bindir -/- "haddock" <.> exe) ] + then [ "--config", "haddock=" ++ show (bindir -/- (cross_prefix <> "haddock") <.> exe) ] else [ "--config", "haddock=" ] - hp2psArg = ["--config", "hp2ps=" ++ show (bindir -/- "hp2ps" <.> exe)] - hpcArg = ["--config", "hpc=" ++ show (bindir -/- "hpc" <.> exe)] + hp2psArg = ["--config", "hp2ps=" ++ show (bindir -/- (cross_prefix <> "hp2ps") <.> exe)] + hpcArg = ["--config", "hpc=" ++ show (bindir -/- (cross_prefix <> "hpc") <.> exe)] inTreeArg = [ "-e", "config.in_tree_compiler=" ++ show (isInTreeCompiler (testCompiler args) || testHasInTreeFiles args) ] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1338b7a3354ed77f6add43c1d33b776db53e7036 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1338b7a3354ed77f6add43c1d33b776db53e7036 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 20:22:24 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 16:22:24 -0400 Subject: [Git][ghc/ghc][master] Add since pragma to Data.Functor.unzip Message-ID: <6446e50087e5f_178e74b0f282fc124120@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 1 changed file: - libraries/base/Data/Functor.hs Changes: ===================================== libraries/base/Data/Functor.hs ===================================== @@ -161,7 +161,10 @@ infixl 4 $> ($>) :: Functor f => f a -> b -> f b ($>) = flip (<$) -unzip :: Functor f => f (a,b) -> (f a, f b) +-- | Generalization of @Data.List.@'Data.List.unzip'. +-- +-- @since 4.19.0.0 +unzip :: Functor f => f (a, b) -> (f a, f b) unzip xs = (fst <$> xs, snd <$> xs) -- | @'void' value@ discards or ignores the result of evaluation, such View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a10f55657a4fc0391a726646552171d5bc7798f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a10f55657a4fc0391a726646552171d5bc7798f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Apr 24 23:14:21 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 24 Apr 2023 19:14:21 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 69 commits: Add release note for GHC.Unicode refactor in base-4.18. Message-ID: <64470d4d7e104_178e74b3e702a8124976d@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 6784698d by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 First steps killing unifyWanted - - - - - b03f8696 by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Fix a boo boo - - - - - 9e98020b by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Fix another error: missing kick-out - - - - - ecf896cb by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Maybe working now - - - - - 4491938a by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Wibbles - - - - - 60e6bc3a by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Stop loop - - - - - b73b35d4 by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Wibbles - - - - - ac83f42c by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 More wibbles - - - - - fce3061e by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 undo accidental change to GHC.Bits - - - - - 3964c885 by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Wibble error messages - - - - - 1390c05f by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Experimental change: coercion holes Experiment with making a constraint non-canonical if it has a coercion hole on the RHS. Simplifies T22707 a lot! - - - - - d9912743 by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 More wibbles - - - - - 40cd1bdd by Simon Peyton Jones at 2023-04-25T00:16:00+01:00 Priorities non-rewritten equalities in the work list Plus update error output - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitmodules - cabal.project-reinstall - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e27d5409352d6c268d33d43c2b5c30fa42a2f43...40cd1bddd39b881a3f0cde10570556916adcf4e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8e27d5409352d6c268d33d43c2b5c30fa42a2f43...40cd1bddd39b881a3f0cde10570556916adcf4e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 01:25:16 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 24 Apr 2023 21:25:16 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC Message-ID: <64472bfc9a72b_178e74b64686b81261896@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 66c6ba1c by Soham Chowdhury at 2023-04-24T21:25:11-04:00 More informative errors for bad imports (#21826) - - - - - 1f4116f6 by Josh Meredith at 2023-04-24T21:25:11-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 30 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/Data/Functor.hs - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - + libraries/base/tests/IO/mkdirExists.stderr - testsuite/tests/driver/recomp001/recomp001.stderr - testsuite/tests/driver/retc001/retc001.stderr - testsuite/tests/ffi/should_fail/ccfail004.stderr - testsuite/tests/ghc-api/target-contents/all.T - testsuite/tests/ghc-e/should_fail/T9905fail2.stderr - testsuite/tests/ghci/scripts/T6007.stderr - + testsuite/tests/module/T21826.hs - + testsuite/tests/module/T21826.stderr - testsuite/tests/module/all.T - testsuite/tests/module/mod114.stderr - testsuite/tests/module/mod124.stderr - testsuite/tests/module/mod125.stderr - testsuite/tests/module/mod126.stderr - testsuite/tests/module/mod127.stderr - testsuite/tests/module/mod130.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b64bfeeb2f05402cfb8e3e52e464e4e43c164801...1f4116f627c8a3b657e163b93facd741fa26e15d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b64bfeeb2f05402cfb8e3e52e464e4e43c164801...1f4116f627c8a3b657e163b93facd741fa26e15d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 04:15:37 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 00:15:37 -0400 Subject: [Git][ghc/ghc][master] More informative errors for bad imports (#21826) Message-ID: <644753e9ee4a7_178e74b902f32812746b4@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - 30 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - testsuite/tests/driver/recomp001/recomp001.stderr - testsuite/tests/driver/retc001/retc001.stderr - testsuite/tests/ffi/should_fail/ccfail004.stderr - testsuite/tests/ghc-e/should_fail/T9905fail2.stderr - testsuite/tests/ghci/scripts/T6007.stderr - + testsuite/tests/module/T21826.hs - + testsuite/tests/module/T21826.stderr - testsuite/tests/module/all.T - testsuite/tests/module/mod114.stderr - testsuite/tests/module/mod124.stderr - testsuite/tests/module/mod125.stderr - testsuite/tests/module/mod126.stderr - testsuite/tests/module/mod127.stderr - testsuite/tests/module/mod130.stderr - testsuite/tests/module/mod134.stderr - testsuite/tests/module/mod29.stderr - testsuite/tests/module/mod36.stderr - testsuite/tests/module/mod79.stderr - testsuite/tests/module/mod80.stderr - testsuite/tests/module/mod81.stderr - testsuite/tests/module/mod87.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0da9e88273a0ffb13132631fb5ea526ea9efeeb9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0da9e88273a0ffb13132631fb5ea526ea9efeeb9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 04:16:14 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 00:16:14 -0400 Subject: [Git][ghc/ghc][master] JS/base: provide implementation for mkdir (issue 22374) Message-ID: <6447540ee2170_178e74b90c4c4812781e7@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 5 changed files: - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - + libraries/base/tests/IO/mkdirExists.stderr - testsuite/tests/ghc-api/target-contents/all.T Changes: ===================================== libraries/base/jsbits/base.js ===================================== @@ -889,3 +889,21 @@ function h$__hscore_free_dirent(a,o) { function h$__hscore_d_name(a,o) { RETURN_UBX_TUP2(h$encodeModifiedUtf8(a.name),0); } + +function h$mkdir(path, path_offset, mode) { + if (!h$isNode()) { + throw "h$mkdir unsupported"; + } + const d = h$decodeUtf8z(path, path_offset); + try { + h$fs.mkdirSync(d, {mode: mode}); + } catch(e) { + // we can't directly set errno code, because numbers may not match + // e.g. e.errno is -17 for EEXIST while we would expect -20 + // this is probably an inconsistency between nodejs using the native + // environment and everything else using Emscripten-provided headers. + h$setErrno(e); + return -1; + } + return 0; +} ===================================== libraries/base/tests/IO/all.T ===================================== @@ -64,7 +64,7 @@ test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run, test('openFile001', normal, compile_and_run, ['']) test('openFile002', [exit_code(1), normalise_win32_io_errors], compile_and_run, ['']) -test('openFile003', [normalise_win32_io_errors, js_broken(22374)], compile_and_run, ['']) +test('openFile003', [normalise_win32_io_errors, js_broken(22362)], compile_and_run, ['']) test('openFile004', [], compile_and_run, ['']) test('openFile005', js_broken(22261), compile_and_run, ['']) test('openFile006', [], compile_and_run, ['']) @@ -152,3 +152,5 @@ test('T17510', expect_broken(17510), compile_and_run, ['']) test('bytestringread001', extra_run_opts('test.data'), compile_and_run, ['']) test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, ['']) test('T18832', only_ways(['threaded1']), compile_and_run, ['']) + +test('mkdirExists', [exit_code(1), when(opsys('mingw32'), ignore_stderr)], compile_and_run, ['']) ===================================== libraries/base/tests/IO/mkdirExists.hs ===================================== @@ -0,0 +1,8 @@ +module Main where + +import System.Directory + +main :: IO () +main = do + createDirectory "foo" + createDirectory "foo" ===================================== libraries/base/tests/IO/mkdirExists.stderr ===================================== @@ -0,0 +1 @@ +mkdirExists: foo: createDirectory: already exists (File exists) ===================================== testsuite/tests/ghc-api/target-contents/all.T ===================================== @@ -1,6 +1,6 @@ test('TargetContents', [ extra_run_opts('"' + config.libdir + '"') - , js_broken(22374) + , js_broken(22362) ] , compile_and_run, ['-package ghc -package exceptions']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebd5b0781c6e6f4642db91353fab0f0ec04af3bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ebd5b0781c6e6f4642db91353fab0f0ec04af3bc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 08:53:34 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 25 Apr 2023 04:53:34 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <6447950e20301_178e74bdeb5128131514e@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 747d8d18 by Sebastian Graf at 2023-04-25T10:49:54+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 14 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs - testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr - testsuite/tests/stranal/should_compile/T18894.stderr - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -110,6 +110,6 @@ test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) -test('T19969', normal, compile, ['-ddump-simpl -dsuppress-uniques']) +test('T19969', [grep_errmsg('LoopBreaker')], compile, ['-ddump-simpl -dsuppress-uniques']) # f should become loopbreaker test('T19883', normal, compile, ['']) test('T22719', normal, compile, ['-ddump-simpl -dsuppress-uniques -dno-typeable-binds']) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -228,7 +228,6 @@ test('T13027', normal, compile, ['']) test('T13025', normal, makefile_test, ['T13025']) -test('T13143', only_ways(['optasm']), compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-ticks']) test('T13156', normal, makefile_test, ['T13156']) test('T11444', normal, compile, ['']) test('str-rules', @@ -414,7 +413,8 @@ test('T17966', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) # We expect to see a SPEC rule for $cm test('T19644', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) test('T21391', normal, compile, ['-O -dcore-lint']) -test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddump-simpl']) +# T22112: Simply test that dumping the Core doesn't loop becuse of the unfolding and ignore the dump output +test('T22112', [ grep_errmsg('never matches') ], compile, ['-O -dsuppress-uniques -dno-typeable-binds -fexpose-all-unfoldings -ddump-simpl']) test('T21391a', normal, compile, ['-O -dcore-lint']) # We don't want to see a thunk allocation for the insertBy expression after CorePrep. test('T21392', [ grep_errmsg(r'sat.* :: \[\(.*Unique, .*Int\)\]'), expect_broken(21392) ], compile, ['-O -ddump-prep -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr ===================================== @@ -7,21 +7,22 @@ Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. (# #) -> a -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] -T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) +[GblId, Arity=1, Str=b{sBp->S}, Cpr=b, Unf=OtherCon []] +T13143.$wf + = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) end Rec } -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} f [InlPrag=NOINLINE[final]] :: forall a. Int -> a [GblId, Arity=1, - Str=b, + Str=b{sBp->S}, Cpr=b, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) - Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)}] -f = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) + Tmpl= \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##)}] +f = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T13143.$trModule4 :: GHC.Prim.Addr# @@ -65,9 +66,9 @@ T13143.$trModule = GHC.Types.Module T13143.$trModule3 T13143.$trModule1 -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} -lvl :: Int -[GblId, Str=b, Cpr=b] -lvl = T13143.$wf @Int GHC.Prim.(##) +lvl_rBN :: Int +[GblId, Str=b{sBp->S}, Cpr=b] +lvl_rBN = T13143.$wf @Int GHC.Prim.(##) Rec { -- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0} @@ -78,17 +79,17 @@ T13143.$wg [InlPrag=[2], Occ=LoopBreaker] Str=<1L><1L>, Unf=OtherCon []] T13143.$wg - = \ (ds :: Bool) (ds1 :: Bool) (ww :: GHC.Prim.Int#) -> - case ds of { + = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (ww_sBv :: GHC.Prim.Int#) -> + case ds_sBr of { False -> - case ds1 of { - False -> T13143.$wg GHC.Types.False GHC.Types.True ww; - True -> GHC.Prim.+# ww 1# + case ds1_sBs of { + False -> T13143.$wg GHC.Types.False GHC.Types.True ww_sBv; + True -> GHC.Prim.+# ww_sBv 1# }; True -> - case ds1 of { - False -> T13143.$wg GHC.Types.True GHC.Types.True ww; - True -> case lvl of wild2 { } + case ds1_sBs of { + False -> T13143.$wg GHC.Types.True GHC.Types.True ww_sBv; + True -> case lvl_rBN of wild2_00 { } } } end Rec } @@ -102,17 +103,20 @@ g [InlPrag=[2]] :: Bool -> Bool -> Int -> Int Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) - Tmpl= \ (ds [Occ=Once1] :: Bool) - (ds1 [Occ=Once1] :: Bool) - (p [Occ=Once1!] :: Int) -> - case p of { GHC.Types.I# ww [Occ=Once1] -> - case T13143.$wg ds ds1 ww of ww1 [Occ=Once1] { __DEFAULT -> - GHC.Types.I# ww1 + Tmpl= \ (ds_sBr [Occ=Once1] :: Bool) + (ds1_sBs [Occ=Once1] :: Bool) + (p_sBt [Occ=Once1!] :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv [Occ=Once1] -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA [Occ=Once1] + { __DEFAULT -> + GHC.Types.I# ww1_sBA } }}] -g = \ (ds :: Bool) (ds1 :: Bool) (p :: Int) -> - case p of { GHC.Types.I# ww -> - case T13143.$wg ds ds1 ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } +g = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (p_sBt :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA { __DEFAULT -> + GHC.Types.I# ww1_sBA + } } ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -42,6 +42,9 @@ test('T13031', normal, makefile_test, []) test('T13077', normal, compile, ['']) test('T13077a', normal, compile, ['']) +# T13143: WW for NOINLINE function f +test('T13143', [ grep_errmsg(r'\$wf') ], compile, ['-ddump-simpl']) + # T15627 # Absent bindings of unlifted types should be WW'ed away. # The idea is to check that both $wmutVar and $warray ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/747d8d1843f1e863b2a152968a8660e41c05d90f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/747d8d1843f1e863b2a152968a8660e41c05d90f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 09:12:05 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 25 Apr 2023 05:12:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23298 Message-ID: <644799657eb54_178e74be5104c813245b2@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T23298 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23298 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 10:27:12 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 25 Apr 2023 06:27:12 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23298a Message-ID: <6447ab0011413_178e74bf964514133843d@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T23298a at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23298a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 10:58:45 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 25 Apr 2023 06:58:45 -0400 Subject: [Git][ghc/ghc][wip/T23298a] Test removing print-explicit-runtime-reps test Message-ID: <6447b265ed24f_178e74c01b1ab413410bf@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23298a at Glasgow Haskell Compiler / GHC Commits: f6ed5254 by Krzysztof Gogolewski at 2023-04-25T12:58:35+02:00 Test removing print-explicit-runtime-reps test - - - - - 1 changed file: - compiler/GHC/Tc/Solver.hs Changes: ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -490,12 +490,9 @@ simplifyTopWanteds wanteds ; try_tyvar_defaulting dflags wc_first_go } where try_tyvar_defaulting :: DynFlags -> WantedConstraints -> TcS WantedConstraints - try_tyvar_defaulting dflags wc + try_tyvar_defaulting _dflags wc | isEmptyWC wc = return wc - | insolubleWC wc - , gopt Opt_PrintExplicitRuntimeReps dflags -- See Note [Defaulting insolubles] - = try_class_defaulting wc | otherwise = do { -- Need to zonk first, as the WantedConstraints are not yet zonked. ; free_tvs <- TcS.zonkTyCoVarsAndFVList (tyCoVarsOfWCList wc) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6ed5254eb949ef02bb65da490b7a1f69e5b5c82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6ed5254eb949ef02bb65da490b7a1f69e5b5c82 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 13:28:29 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 25 Apr 2023 09:28:29 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <6447d57d29abd_178e74c2dd5f281369829@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 850c6369 by Sebastian Graf at 2023-04-25T15:27:40+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 14 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs - testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr - testsuite/tests/stranal/should_compile/T18894.stderr - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -110,6 +110,6 @@ test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) -test('T19969', normal, compile, ['-ddump-simpl -dsuppress-uniques']) +test('T19969', [grep_errmsg('LoopBreaker')], compile, ['-ddump-simpl -dsuppress-uniques']) # f should become loopbreaker test('T19883', normal, compile, ['']) test('T22719', normal, compile, ['-ddump-simpl -dsuppress-uniques -dno-typeable-binds']) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -228,7 +228,6 @@ test('T13027', normal, compile, ['']) test('T13025', normal, makefile_test, ['T13025']) -test('T13143', only_ways(['optasm']), compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-ticks']) test('T13156', normal, makefile_test, ['T13156']) test('T11444', normal, compile, ['']) test('str-rules', @@ -414,7 +413,8 @@ test('T17966', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) # We expect to see a SPEC rule for $cm test('T19644', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) test('T21391', normal, compile, ['-O -dcore-lint']) -test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddump-simpl']) +# T22112: Simply test that dumping the Core doesn't loop becuse of the unfolding and ignore the dump output +test('T22112', [ grep_errmsg('never matches') ], compile, ['-O -dsuppress-uniques -dno-typeable-binds -fexpose-all-unfoldings -ddump-simpl']) test('T21391a', normal, compile, ['-O -dcore-lint']) # We don't want to see a thunk allocation for the insertBy expression after CorePrep. test('T21392', [ grep_errmsg(r'sat.* :: \[\(.*Unique, .*Int\)\]'), expect_broken(21392) ], compile, ['-O -ddump-prep -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr ===================================== @@ -7,21 +7,22 @@ Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. (# #) -> a -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] -T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) +[GblId, Arity=1, Str=b{sBp->S}, Cpr=b, Unf=OtherCon []] +T13143.$wf + = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) end Rec } -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} f [InlPrag=NOINLINE[final]] :: forall a. Int -> a [GblId, Arity=1, - Str=b, + Str=b{sBp->S}, Cpr=b, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) - Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)}] -f = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) + Tmpl= \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##)}] +f = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T13143.$trModule4 :: GHC.Prim.Addr# @@ -65,9 +66,9 @@ T13143.$trModule = GHC.Types.Module T13143.$trModule3 T13143.$trModule1 -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} -lvl :: Int -[GblId, Str=b, Cpr=b] -lvl = T13143.$wf @Int GHC.Prim.(##) +lvl_rBN :: Int +[GblId, Str=b{sBp->S}, Cpr=b] +lvl_rBN = T13143.$wf @Int GHC.Prim.(##) Rec { -- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0} @@ -78,17 +79,17 @@ T13143.$wg [InlPrag=[2], Occ=LoopBreaker] Str=<1L><1L>, Unf=OtherCon []] T13143.$wg - = \ (ds :: Bool) (ds1 :: Bool) (ww :: GHC.Prim.Int#) -> - case ds of { + = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (ww_sBv :: GHC.Prim.Int#) -> + case ds_sBr of { False -> - case ds1 of { - False -> T13143.$wg GHC.Types.False GHC.Types.True ww; - True -> GHC.Prim.+# ww 1# + case ds1_sBs of { + False -> T13143.$wg GHC.Types.False GHC.Types.True ww_sBv; + True -> GHC.Prim.+# ww_sBv 1# }; True -> - case ds1 of { - False -> T13143.$wg GHC.Types.True GHC.Types.True ww; - True -> case lvl of wild2 { } + case ds1_sBs of { + False -> T13143.$wg GHC.Types.True GHC.Types.True ww_sBv; + True -> case lvl_rBN of wild2_00 { } } } end Rec } @@ -102,17 +103,20 @@ g [InlPrag=[2]] :: Bool -> Bool -> Int -> Int Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) - Tmpl= \ (ds [Occ=Once1] :: Bool) - (ds1 [Occ=Once1] :: Bool) - (p [Occ=Once1!] :: Int) -> - case p of { GHC.Types.I# ww [Occ=Once1] -> - case T13143.$wg ds ds1 ww of ww1 [Occ=Once1] { __DEFAULT -> - GHC.Types.I# ww1 + Tmpl= \ (ds_sBr [Occ=Once1] :: Bool) + (ds1_sBs [Occ=Once1] :: Bool) + (p_sBt [Occ=Once1!] :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv [Occ=Once1] -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA [Occ=Once1] + { __DEFAULT -> + GHC.Types.I# ww1_sBA } }}] -g = \ (ds :: Bool) (ds1 :: Bool) (p :: Int) -> - case p of { GHC.Types.I# ww -> - case T13143.$wg ds ds1 ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } +g = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (p_sBt :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA { __DEFAULT -> + GHC.Types.I# ww1_sBA + } } ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -42,6 +42,9 @@ test('T13031', normal, makefile_test, []) test('T13077', normal, compile, ['']) test('T13077a', normal, compile, ['']) +# T13143: WW for NOINLINE function f +test('T13143', [ grep_errmsg(r'T13143\.\$wf') ], compile, ['-ddump-simpl']) + # T15627 # Absent bindings of unlifted types should be WW'ed away. # The idea is to check that both $wmutVar and $warray ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/850c6369265fdce8abb254dddafe15d6777dc4c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/850c6369265fdce8abb254dddafe15d6777dc4c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 14:35:19 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Tue, 25 Apr 2023 10:35:19 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] 67 commits: GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) Message-ID: <6447e527e98eb_178e74c3f44bc414288c0@gitlab.mail> Sylvain Henry pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - ce32d22f by Josh Meredith at 2023-04-25T14:35:15+00:00 WIP refactor GenStgRhs to include the Type in both constructors - - - - - 156ab713 by Josh Meredith at 2023-04-25T14:35:15+00:00 lint - - - - - d023c1a4 by Josh Meredith at 2023-04-25T14:35:15+00:00 lint - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitmodules - cabal.project-reinstall - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Type.hs-boot - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Config/Diagnostic.hs - compiler/GHC/Driver/Config/Tidy.hs - compiler/GHC/Driver/Errors.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9b90863b69e3fce969bb8fcb1bbb2418dd5ece5f...d023c1a4f7863d3e857951ceddb5c6397b51175d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9b90863b69e3fce969bb8fcb1bbb2418dd5ece5f...d023c1a4f7863d3e857951ceddb5c6397b51175d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 14:36:00 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Tue, 25 Apr 2023 10:36:00 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] Apply 1 suggestion(s) to 1 file(s) Message-ID: <6447e550d1b6c_178e74c3f5d6b014311ee@gitlab.mail> Sylvain Henry pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: aebffcc5 by Sylvain Henry at 2023-04-25T14:35:56+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - compiler/GHC/CoreToStg.hs Changes: ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -699,7 +699,7 @@ coreToPreStgRhs :: HasDebugCallStack => CoreExpr -> CtsM PreStgRhs coreToPreStgRhs expr = extendVarEnvCts [ (a, LambdaBound) | a <- args' ] $ do { body' <- coreToStgExpr body - ; return (PreStgRhs args' body' (exprType expr)) } + ; return (PreStgRhs args' body' (exprType body)) } where (args, body) = myCollectBinders expr args' = filterStgBinders args View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aebffcc539466b7475fc319f070c5b14e259288e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aebffcc539466b7475fc319f070c5b14e259288e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 16:22:09 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 12:22:09 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: More informative errors for bad imports (#21826) Message-ID: <6447fe3141e09_178e74c5b576901465028@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - ea5b520c by Josh Meredith at 2023-04-25T12:21:59-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 8139a166 by Andrei Borzenkov at 2023-04-25T12:22:03-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - 30 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - docs/users_guide/exts/implicit_parameters.rst - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/jsbits/base.js - libraries/base/tests/IO/all.T - + libraries/base/tests/IO/mkdirExists.hs - + libraries/base/tests/IO/mkdirExists.stderr - testsuite/tests/ado/all.T - testsuite/tests/driver/recomp001/recomp001.stderr - testsuite/tests/driver/retc001/retc001.stderr - testsuite/tests/ffi/should_fail/ccfail004.stderr - testsuite/tests/ghc-api/target-contents/all.T - testsuite/tests/ghc-e/should_fail/T9905fail2.stderr - testsuite/tests/ghci/scripts/T6007.stderr - + testsuite/tests/module/T21826.hs - + testsuite/tests/module/T21826.stderr - testsuite/tests/module/all.T - testsuite/tests/module/mod114.stderr - testsuite/tests/module/mod124.stderr - testsuite/tests/module/mod125.stderr - testsuite/tests/module/mod126.stderr - testsuite/tests/module/mod127.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f4116f627c8a3b657e163b93facd741fa26e15d...8139a1666277d880c3a3fa57f503fae3f19e5a88 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f4116f627c8a3b657e163b93facd741fa26e15d...8139a1666277d880c3a3fa57f503fae3f19e5a88 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 16:41:05 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Tue, 25 Apr 2023 12:41:05 -0400 Subject: [Git][ghc/ghc][wip/unitidset] ghci module fixes Message-ID: <644802a15c5b6_178e74c64d63c4147142e@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: b7666f0e by Josh Meredith at 2023-04-25T16:39:52+00:00 ghci module fixes - - - - - 4 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Usage.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -395,6 +395,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -418,8 +419,6 @@ import Data.Typeable ( Typeable ) import Data.Word ( Word8 ) import qualified Data.Map.Strict as Map -import Data.Set (Set) -import qualified Data.Set as S import qualified Data.Sequence as Seq import System.Directory @@ -604,7 +603,7 @@ setSessionDynFlags dflags0 = do logger <- getLogger dflags <- checkNewDynFlags logger dflags0 let all_uids = hsc_all_home_unit_ids hsc_env - case S.toList all_uids of + case uniqDSetToList all_uids of [uid] -> do setUnitDynFlagsNoCheck uid dflags modifySession (hscUpdateLoggerFlags . hscSetActiveUnitId (homeUnitId_ dflags)) @@ -1379,7 +1378,7 @@ data ModuleInfo = ModuleInfo { -- | Request information about a loaded 'Module' getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo) -- XXX: Maybe X getModuleInfo mdl = withSession $ \hsc_env -> do - if moduleUnitId mdl `S.member` hsc_all_home_unit_ids hsc_env + if moduleUnitId mdl `elementOfUniqDSet` hsc_all_home_unit_ids hsc_env then liftIO $ getHomeModuleInfo hsc_env mdl else liftIO $ getPackageModuleInfo hsc_env mdl @@ -1756,7 +1755,7 @@ isModuleTrusted m = withSession $ \hsc_env -> liftIO $ hscCheckSafe hsc_env m noSrcSpan -- | Return if a module is trusted and the pkgs it depends on to be trusted. -moduleTrustReqs :: GhcMonad m => Module -> m (Bool, Set UnitId) +moduleTrustReqs :: GhcMonad m => Module -> m (Bool, UnitIdSet) moduleTrustReqs m = withSession $ \hsc_env -> liftIO $ hscGetSafe hsc_env m noSrcSpan ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -126,7 +126,6 @@ import Control.Monad import qualified Control.Monad.Catch as MC (handle) import Data.Maybe import Data.Either ( partitionEithers ) -import qualified Data.Set as Set import Data.Time ( getCurrentTime ) import GHC.Iface.Recomp ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -41,7 +41,6 @@ import Data.IORef import Data.List (sortBy) import Data.Map (Map) import qualified Data.Map as Map -import qualified Data.Set as Set import GHC.Linker.Types import GHC.Unit.Finder ===================================== ghc/GHCi/UI.hs ===================================== @@ -105,6 +105,7 @@ import GHC.Utils.Misc import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Bag (unitBag) import qualified GHC.Data.Strict as Strict +import GHC.Types.Unique.DSet -- Haskell Libraries import System.Console.Haskeline as Haskeline @@ -169,6 +170,7 @@ import GHC.TopHandler ( topHandler ) import GHCi.Leak import qualified GHC.Unit.Module.Graph as GHC +import GHC.Types.Unique.DSet (isEmptyUniqDSet) ----------------------------------------------------------------------------- @@ -2568,15 +2570,15 @@ isSafeModule m = do -- print info to user... liftIO $ putStrLn $ "Trust type is (Module: " ++ trust ++ ", Package: " ++ pkg ++ ")" liftIO $ putStrLn $ "Package Trust: " ++ (if packageTrustOn dflags then "On" else "Off") - when (not $ S.null good) + when (not $ isEmptyUniqDSet good) (liftIO $ putStrLn $ "Trusted package dependencies (trusted): " ++ - (intercalate ", " $ map (showPpr dflags) (S.toList good))) - case msafe && S.null bad of + (intercalate ", " $ map (showPpr dflags) (uniqDSetToList good))) + case msafe && isEmptyUniqDSet bad of True -> liftIO $ putStrLn $ mname ++ " is trusted!" False -> do when (not $ null bad) (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): " - ++ (intercalate ", " $ map (showPpr dflags) (S.toList bad))) + ++ (intercalate ", " $ map (showPpr dflags) (uniqDSetToList bad))) liftIO $ putStrLn $ mname ++ " is NOT trusted!" where @@ -2586,8 +2588,8 @@ isSafeModule m = do | isHomeModule (hsc_home_unit hsc_env) md = True | otherwise = unitIsTrusted $ unsafeLookupUnit (hsc_units hsc_env) (moduleUnit md) - tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (S.empty, S.empty) - | otherwise = S.partition part deps + tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (emptyUniqDSet, emptyUniqDSet) + | otherwise = partitionUniqDSet part deps where part pkg = unitIsTrusted $ unsafeLookupUnitId unit_state pkg unit_state = hsc_units hsc_env dflags = hsc_dflags hsc_env View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7666f0e3fc639d4e383d1d10e3263464b404779 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7666f0e3fc639d4e383d1d10e3263464b404779 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 17:30:41 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 25 Apr 2023 13:30:41 -0400 Subject: [Git][ghc/ghc][wip/toolchain-selection] 1003 commits: Add `Enum (Down a)` instance that swaps `succ` and `pred` Message-ID: <64480e4138f33_178e74c7447f9c14736dc@gitlab.mail> Ben Gamari pushed to branch wip/toolchain-selection at Glasgow Haskell Compiler / GHC Commits: 8c72411d by Gergo ERDI at 2022-10-17T19:20:04-04:00 Add `Enum (Down a)` instance that swaps `succ` and `pred` See https://github.com/haskell/core-libraries-committee/issues/51 for discussion. The key points driving the implementation are the following two ideas: * For the `Int` type, `comparing (complement @Int)` behaves exactly as an order-swapping `compare @Int`. * `enumFrom @(Down a)` can be implemented in terms of `enumFromThen @a`, if only the corner case of starting at the very end is handled specially - - - - - d80ad2f4 by Alan Zimmerman at 2022-10-17T19:20:40-04:00 Update the check-exact infrastructure to match ghc-exactprint GHC tests the exact print annotations using the contents of utils/check-exact. The same functionality is provided via https://github.com/alanz/ghc-exactprint The latter was updated to ensure it works with all of the files on hackage when 9.2 was released, as well as updated to ensure users of the library could work properly (apply-refact, retrie, etc). This commit brings the changes from ghc-exactprint into GHC/utils/check-exact, adapting for the changes to master. Once it lands, it will form the basis for the 9.4 version of ghc-exactprint. See also discussion around this process at #21355 - - - - - 08ab5419 by Andreas Klebinger at 2022-10-17T19:21:15-04:00 Avoid allocating intermediate lists for non recursive bindings. We do so by having an explicit folding function that doesn't need to allocate intermediate lists first. Fixes #22196 - - - - - ff6275ef by Andreas Klebinger at 2022-10-17T19:21:52-04:00 Testsuite: Add a new tables_next_to_code predicate. And use it to avoid T21710a failing on non-tntc archs. Fixes #22169 - - - - - abb82f38 by Eric Lindblad at 2022-10-17T19:22:33-04:00 example rewrite - - - - - 39beb801 by Eric Lindblad at 2022-10-17T19:22:33-04:00 remove redirect - - - - - 0d9fb651 by Eric Lindblad at 2022-10-17T19:22:33-04:00 use heredoc - - - - - 0fa2d185 by Matthew Pickering at 2022-10-17T19:23:10-04:00 testsuite: Fix typo when setting llvm_ways Since 2014 llvm_ways has been set to [] so none of the tests which use only_ways(llvm_ways) have worked as expected. Hopefully the tests still pass with this typo fix! - - - - - ced664a2 by Krzysztof Gogolewski at 2022-10-17T19:23:10-04:00 Fix T15155l not getting -fllvm - - - - - 0ac60423 by Andreas Klebinger at 2022-10-18T03:34:47-04:00 Fix GHCis interaction with tag inference. I had assumed that wrappers were not inlined in interactive mode. Meaning we would always execute the compiled wrapper which properly takes care of upholding the strict field invariant. This turned out to be wrong. So instead we now run tag inference even when we generate bytecode. In that case only for correctness not performance reasons although it will be still beneficial for runtime in some cases. I further fixed a bug where GHCi didn't tag nullary constructors properly when used as arguments. Which caused segfaults when calling into compiled functions which expect the strict field invariant to be upheld. Fixes #22042 and #21083 ------------------------- Metric Increase: T4801 Metric Decrease: T13035 ------------------------- - - - - - 9ecd1ac0 by M Farkas-Dyck at 2022-10-18T03:35:38-04:00 Make `Functor` a superclass of `TrieMap`, which lets us derive the `map` functions. - - - - - f60244d7 by Ben Gamari at 2022-10-18T03:36:15-04:00 configure: Bump minimum bootstrap GHC version Fixes #22245 - - - - - ba4bd4a4 by Matthew Pickering at 2022-10-18T03:36:55-04:00 Build System: Remove out-of-date comment about make build system Both make and hadrian interleave compilation of modules of different modules and don't respect the package boundaries. Therefore I just remove this comment which points out this "difference". Fixes #22253 - - - - - e1bbd368 by Matthew Pickering at 2022-10-18T16:15:49+02:00 Allow configuration of error message printing This MR implements the idea of #21731 that the printing of a diagnostic method should be configurable at the printing time. The interface of the `Diagnostic` class is modified from: ``` class Diagnostic a where diagnosticMessage :: a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` to ``` class Diagnostic a where type DiagnosticOpts a defaultDiagnosticOpts :: DiagnosticOpts a diagnosticMessage :: DiagnosticOpts a -> a -> DecoratedSDoc diagnosticReason :: a -> DiagnosticReason diagnosticHints :: a -> [GhcHint] ``` and so each `Diagnostic` can implement their own configuration record which can then be supplied by a client in order to dictate how to print out the error message. At the moment this only allows us to implement #21722 nicely but in future it is more natural to separate the configuration of how much information we put into an error message and how much we decide to print out of it. Updates Haddock submodule - - - - - 99dc3e3d by Matthew Pickering at 2022-10-18T16:15:53+02:00 Add -fsuppress-error-contexts to disable printing error contexts in errors In many development environments, the source span is the primary means of seeing what an error message relates to, and the In the expression: and In an equation for: clauses are not particularly relevant. However, they can grow to be quite long, which can make the message itself both feel overwhelming and interact badly with limited-space areas. It's simple to implement this flag so we might as well do it and give the user control about how they see their messages. Fixes #21722 - - - - - 5b3a992f by Dai at 2022-10-19T10:45:45-04:00 Add VecSlot for unboxed sums of SIMD vectors This patch adds the missing `VecRep` case to `primRepSlot` function and all the necessary machinery to carry this new `VecSlot` through code generation. This allows programs involving unboxed sums of SIMD vectors to be written and compiled. Fixes #22187 - - - - - 6d7d9181 by sheaf at 2022-10-19T10:45:45-04:00 Remove SIMD conversions This patch makes it so that packing/unpacking SIMD vectors always uses the right sized types, e.g. unpacking a Word16X4# will give a tuple of Word16#s. As a result, we can get rid of the conversion instructions that were previously required. Fixes #22296 - - - - - 3be48877 by sheaf at 2022-10-19T10:45:45-04:00 Cmm Lint: relax SIMD register assignment check As noted in #22297, SIMD vector registers can be used to store different kinds of values, e.g. xmm1 can be used both to store integer and floating point values. The Cmm type system doesn't properly account for this, so we weaken the Cmm register assignment lint check to only compare widths when comparing a vector type with its allocated vector register. - - - - - f7b7a312 by sheaf at 2022-10-19T10:45:45-04:00 Disable some SIMD tests on non-X86 architectures - - - - - 83638dce by M Farkas-Dyck at 2022-10-19T10:46:29-04:00 Scrub various partiality involving lists (again). Lets us avoid some use of `head` and `tail`, and some panics. - - - - - c3732c62 by M Farkas-Dyck at 2022-10-19T10:47:13-04:00 Enforce invariant of `ListBag` constructor. - - - - - 488d3631 by Bodigrim at 2022-10-19T10:47:52-04:00 More precise types for fields of OverlappingInstances and UnsafeOverlap in TcSolverReportMsg It's clear from asserts in `GHC.Tc.Errors` that `overlappingInstances_matches` and `unsafeOverlapped` are supposed to be non-empty, and `unsafeOverlap_matches` contains a single instance, but these invariants are immediately lost afterwards and not encoded in types. This patch enforces the invariants by pattern matching and makes types more precise, avoiding asserts and partial functions such as `head`. - - - - - 607ce263 by sheaf at 2022-10-19T10:47:52-04:00 Rename unsafeOverlap_matches -> unsafeOverlap_match in UnsafeOverlap - - - - - 1fab9598 by Matthew Pickering at 2022-10-19T10:48:29-04:00 Add SpliceTypes test for hie files This test checks that typed splices and quotes get the right type information when used in hiefiles. See #21619 - - - - - a8b52786 by Jan Hrček at 2022-10-19T10:49:09-04:00 Small language fixes in 'Using GHC' - - - - - 1dab1167 by Gergő Érdi at 2022-10-19T10:49:51-04:00 Fix typo in `Opt_WriteIfSimplifiedCore`'s name - - - - - b17cfc9c by sheaf at 2022-10-19T10:50:37-04:00 TyEq:N assertion: only for saturated applications The assertion that checked TyEq:N in canEqCanLHSFinish incorrectly triggered in the case of an unsaturated newtype TyCon heading the RHS, even though we can't unwrap such an application. Now, we only trigger an assertion failure in case of a saturated application of a newtype TyCon. Fixes #22310 - - - - - ff6f2228 by M Farkas-Dyck at 2022-10-20T16:15:51-04:00 CoreToStg: purge `DynFlags`. - - - - - 1ebd521f by Matthew Pickering at 2022-10-20T16:16:27-04:00 ci: Make fat014 test robust For some reason I implemented this as a makefile test rather than a ghci_script test. Hopefully making it a ghci_script test makes it more robust. Fixes #22313 - - - - - 8cd6f435 by Curran McConnell at 2022-10-21T02:58:01-04:00 remove a no-warn directive from GHC.Cmm.ContFlowOpt This patch is motivated by the desire to remove the {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} directive at the top of GHC.Cmm.ContFlowOpt. (Based on the text in this coding standards doc, I understand it's a goal of the project to remove such directives.) I chose this task because I'm a new contributor to GHC, and it seemed like a good way to get acquainted with the patching process. In order to address the warning that arose when I removed the no-warn directive, I added a case to removeUnreachableBlocksProc to handle the CmmData constructor. Clearly, since this partial function has not been erroring out in the wild, its inputs are always in practice wrapped by the CmmProc constructor. Therefore the CmmData case is handled by a precise panic (which is an improvement over the partial pattern match from before). - - - - - a2af7c4c by Nicolas Trangez at 2022-10-21T02:58:39-04:00 build: get rid of `HAVE_TIME_H` As advertized by `autoreconf`: > All current systems provide time.h; it need not be checked for. Hence, remove the check for it in `configure.ac` and remove conditional inclusion of the header in `HAVE_TIME_H` blocks where applicable. The `time.h` header was being included in various source files without a `HAVE_TIME_H` guard already anyway. - - - - - 25cdc630 by Nicolas Trangez at 2022-10-21T02:58:39-04:00 rts: remove use of `TIME_WITH_SYS_TIME` `autoreconf` will insert an `m4_warning` when the obsolescent `AC_HEADER_TIME` macro is used: > Update your code to rely only on HAVE_SYS_TIME_H, > then remove this warning and the obsolete code below it. > All current systems provide time.h; it need not be checked for. > Not all systems provide sys/time.h, but those that do, all allow > you to include it and time.h simultaneously. Presence of `sys/time.h` was already checked in an earlier `AC_CHECK_HEADERS` invocation, so `AC_HEADER_TIME` can be dropped and guards relying on `TIME_WITH_SYS_TIME` can be reworked to (unconditionally) include `time.h` and include `sys/time.h` based on `HAVE_SYS_TIME_H`. Note the documentation of `AC_HEADER_TIME` in (at least) Autoconf 2.67 says > This macro is obsolescent, as current systems can include both files > when they exist. New programs need not use this macro. - - - - - 1fe7921c by Eric Lindblad at 2022-10-21T02:59:21-04:00 runhaskell - - - - - e3b3986e by David Feuer at 2022-10-21T03:00:00-04:00 Document how to quote certain names with spaces Quoting a name for Template Haskell is a bit tricky if the second character of that name is a single quote. The User's Guide falsely claimed that it was impossible. Document how to do it. Fixes #22236 - - - - - 0eba81e8 by Krzysztof Gogolewski at 2022-10-21T03:00:00-04:00 Fix syntax - - - - - a4dbd102 by Ben Gamari at 2022-10-21T09:11:12-04:00 Fix manifest filename when writing Windows .rc files As noted in #12971, we previously used `show` which resulted in inappropriate escaping of non-ASCII characters. - - - - - 30f0d9a9 by Ben Gamari at 2022-10-21T09:11:12-04:00 Write response files in UTF-8 on Windows This reverts the workaround introduced in f63c8ef33ec9666688163abe4ccf2d6c0428a7e7, which taught our response file logic to write response files with the `latin1` encoding to workaround `gcc`'s lacking Unicode support. This is now no longer necessary (and in fact actively unhelpful) since we rather use Clang. - - - - - b8304648 by M Farkas-Dyck at 2022-10-21T09:11:56-04:00 Scrub some partiality in `GHC.Core.Opt.Simplify.Utils`. - - - - - 09ec7de2 by Teo Camarasu at 2022-10-21T13:23:07-04:00 template-haskell: Improve documentation of strictness annotation types Before it was undocumentated that DecidedLazy can be returned by reifyConStrictness for strict fields. This can happen when a field has an unlifted type or its the single field of a newtype constructor. Fixes #21380 - - - - - 88172069 by M Farkas-Dyck at 2022-10-21T13:23:51-04:00 Delete `eqExpr`, since GHC 9.4 has been released. - - - - - 86e6549e by Ömer Sinan Ağacan at 2022-10-22T07:41:30-04:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const 0; // padding for indirectee const 0; // static link const 0; // saved info const hey1_r1Gg_bytes; // the payload } This is much smaller in code. Metric Decrease: T10421 T11195 T12150 T12425 T16577 T18282 T18698a T18698b Co-Authored By: Ben Gamari <ben at well-typed.com> - - - - - 1937016b by Andreas Klebinger at 2022-10-22T07:42:06-04:00 hadrian: Improve error for wrong key/value errors. - - - - - 11fe42d8 by Vladislav Zavialov at 2022-10-23T00:11:50+03:00 Class layout info (#19623) Updates the haddock submodule. - - - - - f0a90c11 by Sven Tennie at 2022-10-24T00:12:51-04:00 Pin used way for test cloneMyStack (#21977) cloneMyStack checks the order of closures on the cloned stack. This may change for different ways. Thus we limit this test to one way (normal). - - - - - 0614e74d by Aaron Allen at 2022-10-24T17:11:21+02:00 Convert Diagnostics in GHC.Tc.Gen.Splice (#20116) Replaces uses of `TcRnUnknownMessage` in `GHC.Tc.Gen.Splice` with structured diagnostics. closes #20116 - - - - - 8d2dbe2d by Andreas Klebinger at 2022-10-24T15:59:41-04:00 Improve stg lint for unboxed sums. It now properly lints cases where sums end up distributed over multiple args after unarise. Fixes #22026. - - - - - 41406da5 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Fix binder-swap bug This patch fixes #21229 properly, by avoiding doing a binder-swap on dictionary Ids. This is pretty subtle, and explained in Note [Care with binder-swap on dictionaries]. Test is already in simplCore/should_run/T21229 This allows us to restore a feature to the specialiser that we had to revert: see Note [Specialising polymorphic dictionaries]. (This is done in a separate patch.) I also modularised things, using a new function scrutBinderSwap_maybe in all the places where we are (effectively) doing a binder-swap, notably * Simplify.Iteration.addAltUnfoldings * SpecConstr.extendCaseBndrs In Simplify.Iteration.addAltUnfoldings I also eliminated a guard Many <- idMult case_bndr because we concluded, in #22123, that it was doing no good. - - - - - 5a997e16 by Simon Peyton Jones at 2022-10-25T18:07:03-04:00 Make the specialiser handle polymorphic specialisation Ticket #13873 unexpectedly showed that a SPECIALISE pragma made a program run (a lot) slower, because less specialisation took place overall. It turned out that the specialiser was missing opportunities because of quantified type variables. It was quite easy to fix. The story is given in Note [Specialising polymorphic dictionaries] Two other minor fixes in the specialiser * There is no benefit in specialising data constructor /wrappers/. (They can appear overloaded because they are given a dictionary to store in the constructor.) Small guard in canSpecImport. * There was a buglet in the UnspecArg case of specHeader, in the case where there is a dead binder. We need a LitRubbish filler for the specUnfolding stuff. I expanded Note [Drop dead args from specialisations] to explain. There is a 4% increase in compile time for T15164, because we generate more specialised code. This seems OK. Metric Increase: T15164 - - - - - 7f203d00 by Sylvain Henry at 2022-10-25T18:07:43-04:00 Numeric exceptions: replace FFI calls with primops ghc-bignum needs a way to raise numerical exceptions defined in base package. At the time we used FFI calls into primops defined in the RTS. These FFI calls had to be wrapped into hacky bottoming functions because "foreign import prim" syntax doesn't support giving a bottoming demand to the foreign call (cf #16929). These hacky wrapper functions trip up the JavaScript backend (#21078) because they are polymorphic in their return type. This commit replaces them with primops very similar to raise# but raising predefined exceptions. - - - - - 0988a23d by Sylvain Henry at 2022-10-25T18:08:24-04:00 Enable popcount rewrite rule when cross-compiling The comment applies only when host's word size < target's word size. So we can relax the guard. - - - - - a2f53ac8 by Sylvain Henry at 2022-10-25T18:09:05-04:00 Add GHC.SysTools.Cpp module Move doCpp out of the driver to be able to use it in the upcoming JS backend. - - - - - 1fd7f201 by Ben Gamari at 2022-10-25T18:09:42-04:00 llvm-targets: Add datalayouts for big-endian AArch64 targets Fixes #22311. Thanks to @zeldin for the patch. - - - - - f5a486eb by Krzysztof Gogolewski at 2022-10-25T18:10:19-04:00 Cleanup String/FastString conversions Remove unused mkPtrString and isUnderscoreFS. We no longer use mkPtrString since 1d03d8bef96. Remove unnecessary conversions between FastString and String and back. - - - - - f7bfb40c by Ryan Scott at 2022-10-26T00:01:24-04:00 Broaden the in-scope sets for liftEnvSubst and composeTCvSubst This patch fixes two distinct (but closely related) buglets that were uncovered in #22235: * `liftEnvSubst` used an empty in-scope set, which was not wide enough to cover the variables in the range of the substitution. This patch fixes this by populating the in-scope set from the free variables in the range of the substitution. * `composeTCvSubst` applied the first substitution argument to the range of the second substitution argument, but the first substitution's in-scope set was not wide enough to cover the range of the second substutition. We similarly fix this issue in this patch by widening the first substitution's in-scope set before applying it. Fixes #22235. - - - - - 0270cc54 by Vladislav Zavialov at 2022-10-26T00:02:01-04:00 Introduce TcRnWithHsDocContext (#22346) Before this patch, GHC used withHsDocContext to attach an HsDocContext to an error message: addErr $ mkTcRnUnknownMessage $ mkPlainError noHints (withHsDocContext ctxt msg) The problem with this approach is that it only works with TcRnUnknownMessage. But could we attach an HsDocContext to a structured error message in a generic way? This patch solves the problem by introducing a new constructor to TcRnMessage: data TcRnMessage where ... TcRnWithHsDocContext :: !HsDocContext -> !TcRnMessage -> TcRnMessage ... - - - - - 9ab31f42 by Sylvain Henry at 2022-10-26T09:32:20+02:00 Testsuite: more precise test options Necessary for newer cross-compiling backends (JS, Wasm) that don't support TH yet. - - - - - f60a1a62 by Vladislav Zavialov at 2022-10-26T12:17:14-04:00 Use TcRnVDQInTermType in noNestedForallsContextsErr (#20115) When faced with VDQ in the type of a term, GHC generates the following error message: Illegal visible, dependent quantification in the type of a term (GHC does not yet support this) Prior to this patch, there were two ways this message could have been generated and represented: 1. with the dedicated constructor TcRnVDQInTermType (see check_type in GHC.Tc.Validity) 2. with the transitional constructor TcRnUnknownMessage (see noNestedForallsContextsErr in GHC.Rename.Utils) Not only this led to duplication of code generating the final SDoc, it also made it tricky to track the origin of the error message. This patch fixes the problem by using TcRnVDQInTermType exclusively. - - - - - 223e159d by Owen Shepherd at 2022-10-27T13:54:33-04:00 Remove source location information from interface files This change aims to minimize source location information leaking into interface files, which makes ABI hashes dependent on the build location. The `Binary (Located a)` instance has been removed completely. It seems that the HIE interface still needs the ability to serialize SrcSpans, but by wrapping the instances, it should be a lot more difficult to inadvertently add source location information. - - - - - 22e3deb9 by Simon Peyton Jones at 2022-10-27T13:55:37-04:00 Add missing dict binds to specialiser I had forgotten to add the auxiliary dict bindings to the /unfolding/ of a specialised function. This caused #22358, which reports failures when compiling Hackage packages fixed-vector indexed-traversable Regression test T22357 is snarfed from indexed-traversable - - - - - a8ed36f9 by Evan Relf at 2022-10-27T13:56:36-04:00 Fix broken link to `async` package - - - - - 750846cd by Zubin Duggal at 2022-10-28T00:49:22-04:00 Pass correct package db when testing stage1. It used to pick the db for stage-2 which obviously didn't work. - - - - - ad612f55 by Krzysztof Gogolewski at 2022-10-28T00:50:00-04:00 Minor SDoc-related cleanup * Rename pprCLabel to pprCLabelStyle, and use the name pprCLabel for a function using CStyle (analogous to pprAsmLabel) * Move LabelStyle to the CLabel module, it no longer needs to be in Outputable. * Move calls to 'text' right next to literals, to make sure the text/str rule is triggered. * Remove FastString/String roundtrip in Tc.Deriv.Generate * Introduce showSDocForUser', which abstracts over a pattern in GHCi.UI - - - - - c2872f3f by Bryan Richter at 2022-10-28T11:36:34+03:00 CI: Don't run lint-submods on nightly Fixes #22325 - - - - - 270037fa by Hécate Moonlight at 2022-10-28T19:46:12-04:00 Start the deprecation process for GHC.Pack - - - - - d45d8cb3 by M Farkas-Dyck at 2022-11-01T12:47:21-04:00 Drop a kludge for binutils<2.17, which is now over 10 years old. - - - - - 8ee8b418 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: `name` argument of `createOSThread` can be `const` Since we don't intend to ever change the incoming string, declare this to be true. Also, in the POSIX implementation, the argument is no longer `STG_UNUSED` (since ee0deb8054da2a597fc5624469b4c44fd769ada2) in any code path. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 - - - - - 13b5f102 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix lifetime of `start_thread`s `name` value Since, unlike the code in ee0deb8054da2^, usage of the `name` value passed to `createOSThread` now outlives said function's lifetime, and could hence be released by the caller by the time the new thread runs `start_thread`, it needs to be copied. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2#note_460080 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - edd175c9 by Nicolas Trangez at 2022-11-01T12:47:58-04:00 rts: fix OS thread naming in ticker Since ee0deb805, the use of `pthread_setname_np` on Darwin was fixed when invoking `createOSThread`. However, the 'ticker' has some thread-creation code which doesn't rely on `createOSThread`, yet also uses `pthread_setname_np`. This patch enforces all thread creation to go through a single function, which uses the (correct) thread-naming code introduced in ee0deb805. See: https://gitlab.haskell.org/ghc/ghc/-/commit/ee0deb8054da2a597fc5624469b4c44fd769ada2 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22206 See: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9066 - - - - - b7a00113 by Krzysztof Gogolewski at 2022-11-01T12:48:35-04:00 Typo: rename -fwrite-if-simplfied-core to -fwrite-if-simplified-core - - - - - 30e625e6 by Vladislav Zavialov at 2022-11-01T12:49:10-04:00 ThToHs: fix overzealous parenthesization Before this patch, when converting from TH.Exp to LHsExpr GhcPs, the compiler inserted more parentheses than required: ((f a) (b + c)) d This was happening because the LHS of the function application was parenthesized as if it was the RHS. Now we use funPrec and appPrec appropriately and produce sensibly parenthesized expressions: f a (b + c) d I also took the opportunity to remove the special case for LamE, which was not special at all and simply duplicated code. - - - - - 0560821f by Simon Peyton Jones at 2022-11-01T12:49:47-04:00 Add accurate skolem info when quantifying Ticket #22379 revealed that skolemiseQuantifiedTyVar was dropping the passed-in skol_info on the floor when it encountered a SkolemTv. Bad! Several TyCons thereby share a single SkolemInfo on their binders, which lead to bogus error reports. - - - - - 38d19668 by Fendor at 2022-11-01T12:50:25-04:00 Expose UnitEnvGraphKey for user-code - - - - - 77e24902 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Shrink test case for #22357 Ryan Scott offered a cut-down repro case (60 lines instead of more than 700 lines) - - - - - 4521f649 by Simon Peyton Jones at 2022-11-01T12:51:00-04:00 Add two tests for #17366 - - - - - 6b400d26 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_NORETURN` Instead of sprinkling the codebase with `GNU(C3)_ATTRIBUTE(__noreturn__)`, add a `STG_NORETURN` macro (for, basically, the same thing) similar to `STG_UNUSED` and others, and update the code to use this macro where applicable. - - - - - f9638654 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: consistently use `STG_UNUSED` - - - - - 81a58433 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_USED` Similar to `STG_UNUSED`, have a specific macro for `__attribute__(used)`. - - - - - 41e1f748 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: introduce (and use) `STG_MALLOC` Instead of using `GNUC3_ATTRIBUTE(__malloc__)`, provide a `STG_MALLOC` macro definition and use it instead. - - - - - 3a9a8bde by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `STG_UNUSED` - - - - - 9ab999de by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: specify deallocator of allocating functions This patch adds a new `STG_MALLOC1` macro (and its counterpart `STG_MALLOC2` for completeness) which allows to specify the deallocation function to be used with allocations of allocating functions, and applies it to `stg*allocBytes`. It also fixes a case where `free` was used to free up an `stgMallocBytes` allocation, found by the above change. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 81c0c7c9 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: use `alloc_size` attribute This patch adds the `STG_ALLOC_SIZE1` and `STG_ALLOC_SIZE2` macros which allow to set the `alloc_size` attribute on functions, when available. See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - 99a1d896 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: add and use `STG_RETURNS_NONNULL` See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-returns_005fnonnull-function-attribute See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - c235b399 by Nicolas Trangez at 2022-11-02T12:06:48-04:00 rts: tag `stgStrndup` as `STG_MALLOC` See: https://gitlab.haskell.org/ghc/ghc/-/issues/22381 - - - - - ed81b448 by Oleg Grenrus at 2022-11-02T12:07:27-04:00 Move Symbol implementation note out of public haddock - - - - - 284fd39c by Ben Gamari at 2022-11-03T01:58:54-04:00 gen-dll: Drop it Currently it is only used by the make build system, which is soon to be retired, and it has not built since 41cf758b. We may need to reintroduce it when dynamic-linking support is introduced on Windows, but we will cross that bridge once we get there. Fixes #21753. - - - - - 24f4f54f by Matthew Pickering at 2022-11-03T01:59:30-04:00 Port foundation numeric tests to GHC testsuite This commit ports the numeric tests which found a regression in GHC-9.4. https://github.com/haskell-foundation/foundation/issues/571 Included in the commit is a simple random number generator and simplified QuickCheck implementation. In future these could be factored out of this standalone file and reused as a general purpose library which could be used for other QuickCheck style tests in the testsuite. See #22282 - - - - - d51bf7bd by M Farkas-Dyck at 2022-11-03T02:00:13-04:00 git: ignore HIE files. Cleans up git status if one sets -fwrite-ide-info in hadrian/ghci. - - - - - a9fc15b1 by Matthew Pickering at 2022-11-03T02:00:49-04:00 Clarify status of bindings in WholeCoreBindings Gergo points out that these bindings are tidied, rather than prepd as the variable claims. Therefore we update the name of the variable to reflect reality and add a comment to the data type to try to erase any future confusion. Fixes #22307 - - - - - 634da448 by Bodigrim at 2022-11-03T21:25:02+00:00 Fix haddocks for GHC.IORef - - - - - 31125154 by Andreas Klebinger at 2022-11-03T23:08:09-04:00 Export pprTrace and friends from GHC.Prelude. Introduces GHC.Prelude.Basic which can be used in modules which are a dependency of the ppr code. - - - - - bdc8cbb3 by Bryan Richter at 2022-11-04T10:27:37+02:00 CI: Allow hadrian-ghc-in-ghci to run in nightlies Since lint-submods doesn't run in nightlies, hadrian-ghc-in-ghci needs to mark it as "optional" so it can run if the job doesn't exist. Fixes #22396. - - - - - 3c0e3793 by Krzysztof Gogolewski at 2022-11-05T00:29:57-04:00 Minor refactor around FastStrings Pass FastStrings to functions directly, to make sure the rule for fsLit "literal" fires. Remove SDoc indirection in GHCi.UI.Tags and GHC.Unit.Module.Graph. - - - - - e41b2f55 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump unix submodule to 2.8.0.0 Also bumps process and ghc-boot bounds on unix. For hadrian, when cross-compiling, we add -Wwarn=unused-imports -Wwarn=unused-top-binds to validation flavour. Further fixes in unix and/or hsc2hs is needed to make it completely free of warnings; for the time being, this change is needed to unblock other cross-compilation related work. - - - - - 42938a58 by Matthew Pickering at 2022-11-05T14:18:10+00:00 Bump Win32 submodule to 2.13.4.0 Fixes #22098 - - - - - e7372bc5 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump ci-images revision ci-images has recently been updated, including changes needed for wasm32-wasi CI. - - - - - 88cb9492 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump gmp-tarballs submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 69427ce9 by Cheng Shao at 2022-11-06T13:15:22+00:00 Bump haskeline submodule Includes a fix for wasm support, doesn't impact other targets. - - - - - 5fe11fe6 by Carter Schonwald at 2022-11-07T13:22:14-05:00 bump llvm upper bound - - - - - 68f49874 by M Farkas-Dyck at 2022-11-08T12:53:55-05:00 Define `Infinite` list and use where appropriate. Also add perf test for infinite list fusion. In particular, in `GHC.Core`, often we deal with infinite lists of roles. Also in a few locations we deal with infinite lists of names. Thanks to simonpj for helping to write the Note [Fusion for `Infinite` lists]. - - - - - ce726cd2 by Ross Paterson at 2022-11-08T12:54:34-05:00 Fix TypeData issues (fixes #22315 and #22332) There were two bugs here: 1. Treating type-level constructors as PromotedDataCon doesn't always work, in particular because constructors promoted via DataKinds are called both T and 'T. (Tests T22332a, T22332b, T22315a, T22315b) Fix: guard these cases with isDataKindsPromotedDataCon. 2. Type-level constructors were sent to the code generator, producing things like constructor wrappers. (Tests T22332a, T22332b) Fix: test for them in isDataTyCon. Other changes: * changed the marking of "type data" DataCon's as suggested by SPJ. * added a test TDGADT for a type-level GADT. * comment tweaks * change tcIfaceTyCon to ignore IfaceTyConInfo, so that IfaceTyConInfo is used only for pretty printing, not for typechecking. (SPJ) - - - - - 132f8908 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Clarify msum/asum documentation - - - - - bb5888c5 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Add example for (<$) - - - - - 080fffa1 by Jade Lovelace at 2022-11-08T12:55:18-05:00 Document what Alternative/MonadPlus instances actually do - - - - - 92ccb8de by Giles Anderson at 2022-11-09T09:27:52-05:00 Use TcRnDiagnostic in GHC.Tc.TyCl.Instance (#20117) The following `TcRnDiagnostic` messages have been introduced: TcRnWarnUnsatisfiedMinimalDefinition TcRnMisplacedInstSig TcRnBadBootFamInstDeclErr TcRnIllegalFamilyInstance TcRnAssocInClassErr TcRnBadFamInstDecl TcRnNotOpenFamily - - - - - 90c5abd4 by Hécate Moonlight at 2022-11-09T09:28:30-05:00 GHCi tags generation phase 2 see #19884 - - - - - f9f17b68 by Simon Peyton Jones at 2022-11-10T12:20:03+00:00 Fire RULES in the Specialiser The Specialiser has, for some time, fires class-op RULES in the specialiser itself: see Note [Specialisation modulo dictionary selectors] This MR beefs it up a bit, so that it fires /all/ RULES in the specialiser, not just class-op rules. See Note [Fire rules in the specialiser] The result is a bit more specialisation; see test simplCore/should_compile/T21851_2 This pushed me into a bit of refactoring. I made a new data types GHC.Core.Rules.RuleEnv, which combines - the several source of rules (local, home-package, external) - the orphan-module dependencies in a single record for `getRules` to consult. That drove a bunch of follow-on refactoring, including allowing me to remove cr_visible_orphan_mods from the CoreReader data type. I moved some of the RuleBase/RuleEnv stuff into GHC.Core.Rule. The reorganisation in the Simplifier improve compile times a bit (geom mean -0.1%), but T9961 is an outlier Metric Decrease: T9961 - - - - - 2b3d0bee by Simon Peyton Jones at 2022-11-10T12:21:13+00:00 Make indexError work better The problem here is described at some length in Note [Boxity for bottoming functions] and Note [Reboxed crud for bottoming calls] in GHC.Core.Opt.DmdAnal. This patch adds a SPECIALISE pragma for indexError, which makes it much less vulnerable to the problem described in these Notes. (This came up in another line of work, where a small change made indexError do reboxing (in nofib/spectral/simple/table_sort) that didn't happen before my change. I've opened #22404 to document the fagility. - - - - - 399e921b by Simon Peyton Jones at 2022-11-10T12:21:14+00:00 Fix DsUselessSpecialiseForClassMethodSelector msg The error message for DsUselessSpecialiseForClassMethodSelector was just wrong (a typo in some earlier work); trivial fix - - - - - dac0682a by Sebastian Graf at 2022-11-10T21:16:01-05:00 WorkWrap: Unboxing unboxed tuples is not always useful (#22388) See Note [Unboxing through unboxed tuples]. Fixes #22388. - - - - - 1230c268 by Sebastian Graf at 2022-11-10T21:16:01-05:00 Boxity: Handle argument budget of unboxed tuples correctly (#21737) Now Budget roughly tracks the combined width of all arguments after unarisation. See the changes to `Note [Worker argument budgets]`. Fixes #21737. - - - - - 2829fd92 by Cheng Shao at 2022-11-11T00:26:54-05:00 autoconf: check getpid getuid raise This patch adds checks for getpid, getuid and raise in autoconf. These functions are absent in wasm32-wasi and thus needs to be checked. - - - - - f5dfd1b4 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add -Wwarn only for cross-compiling unix - - - - - 2e6ab453 by Cheng Shao at 2022-11-11T00:26:55-05:00 hadrian: add targetSupportsThreadedRts flag This patch adds a targetSupportsThreadedRts flag to indicate whether the target supports the threaded rts at all, different from existing targetSupportsSMP that checks whether -N is supported by the RTS. All existing flavours have also been updated accordingly to respect this flags. Some targets (e.g. wasm32-wasi) does not support the threaded rts, therefore this flag is needed for the default flavours to work. It makes more sense to have proper autoconf logic to check for threading support, but for the time being, we just set the flag to False iff the target is wasm32. - - - - - 8104f6f5 by Cheng Shao at 2022-11-11T00:26:55-05:00 Fix Cmm symbol kind - - - - - b2035823 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add the two key graph modules from Martin Erwig's FGL Martin Erwig's FGL (Functional Graph Library) provides an "inductive" representation of graphs. A general graph has labeled nodes and labeled edges. The key operation on a graph is to decompose it by removing one node, together with the edges that connect the node to the rest of the graph. There is also an inverse composition operation. The decomposition and composition operations make this representation of graphs exceptionally well suited to implement graph algorithms in which the graph is continually changing, as alluded to in #21259. This commit adds `GHC.Data.Graph.Inductive.Graph`, which defines the interface, and `GHC.Data.Graph.Inductive.PatriciaTree`, which provides an implementation. Both modules are taken from `fgl-5.7.0.3` on Hackage, with these changes: - Copyright and license text have been copied into the files themselves, not stored separately. - Some calls to `error` have been replaced with calls to `panic`. - Conditional-compilation support for older versions of GHC, `containers`, and `base` has been removed. - - - - - 3633a5f5 by Norman Ramsey at 2022-11-11T00:26:55-05:00 add new modules for reducibility and WebAssembly translation - - - - - df7bfef8 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add support for the wasm32-wasi target tuple This patch adds the wasm32-wasi tuple support to various places in the tree: autoconf, hadrian, ghc-boot and also the compiler. The codegen logic will come in subsequent commits. - - - - - 32ae62e6 by Cheng Shao at 2022-11-11T00:26:55-05:00 deriveConstants: parse .ll output for wasm32 due to broken nm This patch makes deriveConstants emit and parse an .ll file when targeting wasm. It's a necessary workaround for broken llvm-nm on wasm, which isn't capable of reporting correct constant values when parsing an object. - - - - - 07e92c92 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: workaround cmm's improper variadic ccall breaking wasm32 typechecking Unlike other targets, wasm requires the function signature of the call site and callee to strictly match. So in Cmm, when we call a C function that actually returns a value, we need to add an _unused local variable to receive it, otherwise type error awaits. An even bigger problem is calling variadic functions like barf() and such. Cmm doesn't support CAPI calling convention yet, so calls to variadic functions just happen to work in some cases with some target's ABI. But again, it doesn't work with wasm. Fortunately, the wasm C ABI lowers varargs to a stack pointer argument, and it can be passed NULL when no other arguments are expected to be passed. So we also add the additional unused NULL arguments to those functions, so to fix wasm, while not affecting behavior on other targets. - - - - - 00124d12 by Cheng Shao at 2022-11-11T00:26:55-05:00 testsuite: correct sleep() signature in T5611 In libc, sleep() returns an integer. The ccall type signature should match the libc definition, otherwise it causes linker error on wasm. - - - - - d72466a9 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: prefer ffi_type_void over FFI_TYPE_VOID This patch uses ffi_type_void instead of FFI_TYPE_VOID in the interpreter code, since the FFI_TYPE_* macros are not available in libffi-wasm32 yet. The libffi public documentation also only mentions the lower-case ffi_type_* symbols, so we should prefer the lower-case API here. - - - - - 4d36a1d3 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't define RTS_USER_SIGNALS when signal.h is not present In the rts, we have a RTS_USER_SIGNALS macro, and most signal-related logic is guarded with RTS_USER_SIGNALS. This patch extends the range of code guarded with RTS_USER_SIGNALS, and define RTS_USER_SIGNALS iff signal.h is actually detected by autoconf. This is required for wasm32-wasi to work, which lacks signals. - - - - - 3f1e164f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: use HAVE_GETPID to guard subprocess related logic We've previously added detection of getpid() in autoconf. This patch uses HAVE_GETPID to guard some subprocess related logic in the RTS. This is required for certain targets like wasm32-wasi, where there isn't a process model at all. - - - - - 50bf5e77 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: IPE.c: don't do mutex stuff when THREADED_RTS is not defined This patch adds the missing THREADED_RTS CPP guard to mutex logic in IPE.c. - - - - - ed3b3da0 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: genericRaise: use exit() instead when not HAVE_RAISE We check existence of raise() in autoconf, and here, if not HAVE_RAISE, we should use exit() instead in genericRaise. - - - - - c0ba1547 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: checkSuid: don't do it when not HAVE_GETUID When getuid() is not present, don't do checkSuid since it doesn't make sense anyway on that target. - - - - - d2d6dfd2 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 placeholder linker This patch adds minimal placeholder linker logic for wasm32, just enough to unblock compiling rts on wasm32. RTS linker functionality is not properly implemented yet for wasm32. - - - - - 65ba3285 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: chdir to PWD on wasm32 This patch adds a wasm32-specific behavior to RtsStartup logic. When the PWD environment variable is present, we chdir() to it first. The point is to workaround an issue in wasi-libc: it's currently not possible to specify the initial working directory, it always defaults to / (in the virtual filesystem mapped from some host directory). For some use cases this is sufficient, but there are some other cases (e.g. in the testsuite) where the program needs to access files outside. - - - - - 65b82542 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: no timer for wasm32 Due to the lack of threads, on wasm32 there can't be a background timer that periodically resets the context switch flag. This patch disables timer for wasm32, and also makes the scheduler default to -C0 on wasm32 to avoid starving threads. - - - - - e007586f by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsSymbols: empty RTS_POSIX_ONLY_SYMBOLS for wasm32 The default RTS_POSIX_ONLY_SYMBOLS doesn't make sense on wasm32. - - - - - 0e33f667 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: Schedule: no FORKPROCESS_PRIMOP_SUPPORTED on wasm32 On wasm32 there isn't a process model at all, so no FORKPROCESS_PRIMOP_SUPPORTED. - - - - - 88bbdb31 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: LibffiAdjustor: adapt to ffi_alloc_prep_closure interface for wasm32 libffi-wasm32 only supports non-standard libffi closure api via ffi_alloc_prep_closure(). This patch implements ffi_alloc_prep_closure() via standard libffi closure api on other targets, and uses it to implement adjustor functionality. - - - - - 15138746 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: don't return memory to OS on wasm32 This patch makes the storage manager not return any memory on wasm32. The detailed reason is described in Note [Megablock allocator on wasm]. - - - - - 631af3cc by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: make flushExec a no-op on wasm32 This patch makes flushExec a no-op on wasm32, since there's no such thing as executable memory on wasm32 in the first place. - - - - - 654a3d46 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: RtsStartup: don't call resetTerminalSettings, freeThreadingResources on wasm32 This patch prevents resetTerminalSettings and freeThreadingResources to be called on wasm32, since there is no TTY or threading on wasm32 at all. - - - - - f271e7ca by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: OSThreads.h: stub types for wasm32 This patch defines stub Condition/Mutex/OSThreadId/ThreadLocalKey types for wasm32, just enough to unblock compiling RTS. Any threading-related functionality has been patched to be disabled on wasm32. - - - - - a6ac67b0 by Cheng Shao at 2022-11-11T00:26:55-05:00 Add register mapping for wasm32 This patch adds register mapping logic for wasm32. See Note [Register mapping on WebAssembly] in wasm32 NCG for more description. - - - - - d7b33982 by Cheng Shao at 2022-11-11T00:26:55-05:00 rts: wasm32 specific logic This patch adds the rest of wasm32 specific logic in rts. - - - - - 7f59b0f3 by Cheng Shao at 2022-11-11T00:26:55-05:00 base: fall back to using monotonic clock to emulate cputime on wasm32 On wasm32, we have to fall back to using monotonic clock to emulate cputime, since there's no native support for cputime as a clock id. - - - - - 5fcbae0b by Cheng Shao at 2022-11-11T00:26:55-05:00 base: more autoconf checks for wasm32 This patch adds more autoconf checks to base, since those functions and headers may exist on other POSIX systems but don't exist on wasm32. - - - - - 00a9359f by Cheng Shao at 2022-11-11T00:26:55-05:00 base: avoid using unsupported posix functionality on wasm32 This base patch avoids using unsupported posix functionality on wasm32. - - - - - 34b8f611 by Cheng Shao at 2022-11-11T00:26:55-05:00 autoconf: set CrossCompiling=YES in cross bindist configure This patch fixes the bindist autoconf logic to properly set CrossCompiling=YES when it's a cross GHC bindist. - - - - - 5ebeaa45 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: add util functions for UniqFM and UniqMap This patch adds addToUFM_L (backed by insertLookupWithKey), addToUniqMap_L and intersectUniqMap_C. These UniqFM/UniqMap util functions are used by the wasm32 NCG. - - - - - 177c56c1 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: avoid -Wl,--no-as-needed for wasm32 The driver used to pass -Wl,--no-as-needed for LLD linking. This is actually only supported for ELF targets, and must be avoided when linking for wasm32. - - - - - 06f01c74 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: allow big arith for wasm32 This patch enables Cmm big arithmetic on wasm32, since 64-bit arithmetic can be efficiently lowered to wasm32 opcodes. - - - - - df6bb112 by Cheng Shao at 2022-11-11T00:26:55-05:00 driver: pass -Wa,--no-type-check for wasm32 when runAsPhase This patch passes -Wa,--no-type-check for wasm32 when compiling assembly. See the added note for more detailed explanation. - - - - - c1fe4ab6 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: enforce cmm switch planning for wasm32 This patch forcibly enable Cmm switch planning for wasm32, since otherwise the switch tables we generate may exceed the br_table maximum allowed size. - - - - - a8adc71e by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: annotate CmmFileEmbed with blob length This patch adds the blob length field to CmmFileEmbed. The wasm32 NCG needs to know the precise size of each data segment. - - - - - 36340328 by Cheng Shao at 2022-11-11T00:26:55-05:00 compiler: wasm32 NCG This patch adds the wasm32 NCG. - - - - - 435f42ea by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add wasm32-wasi release bindist job - - - - - d8262fdc by Cheng Shao at 2022-11-11T00:26:55-05:00 ci: add a stronger test for cross bindists This commit adds a simple GHC API program that parses and reprints the original hello world program used for basic testing of cross bindists. Before there's full cross-compilation support in the test suite driver, this provides better coverage than the original test. - - - - - 8e6ae882 by Cheng Shao at 2022-11-11T00:26:55-05:00 CODEOWNERS: add wasm-specific maintainers - - - - - 707d5651 by Zubin Duggal at 2022-11-11T00:27:31-05:00 Clarify that LLVM upper bound is non-inclusive during configure (#22411) - - - - - 430eccef by Ben Gamari at 2022-11-11T13:16:45-05:00 rts: Check for program_invocation_short_name via autoconf Instead of assuming support on all Linuxes. - - - - - 6dab0046 by Matthew Pickering at 2022-11-11T13:17:22-05:00 driver: Fix -fdefer-diagnostics flag The `withDeferredDiagnostics` wrapper wasn't doing anything because the session it was modifying wasn't used in hsc_env. Therefore the fix is simple, just push the `getSession` call into the scope of `withDeferredDiagnostics`. Fixes #22391 - - - - - d0c691b6 by Simon Peyton Jones at 2022-11-11T13:18:07-05:00 Add a fast path for data constructor workers See Note [Fast path for data constructors] in GHC.Core.Opt.Simplify.Iteration This bypasses lots of expensive logic, in the special case of applications of data constructors. It is a surprisingly worthwhile improvement, as you can see in the figures below. Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Read(normal) -2.0% CoOpt_Singletons(normal) -2.0% ManyConstructors(normal) -1.3% T10421(normal) -1.9% GOOD T10421a(normal) -1.5% T10858(normal) -1.6% T11545(normal) -1.7% T12234(optasm) -1.3% T12425(optasm) -1.9% GOOD T13035(normal) -1.0% GOOD T13056(optasm) -1.8% T13253(normal) -3.3% GOOD T15164(normal) -1.7% T15304(normal) -3.4% T15630(normal) -2.8% T16577(normal) -4.3% GOOD T17096(normal) -1.1% T17516(normal) -3.1% T18282(normal) -1.9% T18304(normal) -1.2% T18698a(normal) -1.2% GOOD T18698b(normal) -1.5% GOOD T18923(normal) -1.3% T1969(normal) -1.3% GOOD T19695(normal) -4.4% GOOD T21839c(normal) -2.7% GOOD T21839r(normal) -2.7% GOOD T4801(normal) -3.8% GOOD T5642(normal) -3.1% GOOD T6048(optasm) -2.5% GOOD T9020(optasm) -2.7% GOOD T9630(normal) -2.1% GOOD T9961(normal) -11.7% GOOD WWRec(normal) -1.0% geo. mean -1.1% minimum -11.7% maximum +0.1% Metric Decrease: T10421 T12425 T13035 T13253 T16577 T18698a T18698b T1969 T19695 T21839c T21839r T4801 T5642 T6048 T9020 T9630 T9961 - - - - - 3c37d30b by Krzysztof Gogolewski at 2022-11-11T19:18:39+01:00 Use a more efficient printer for code generation (#21853) The changes in `GHC.Utils.Outputable` are the bulk of the patch and drive the rest. The types `HLine` and `HDoc` in Outputable can be used instead of `SDoc` and support printing directly to a handle with `bPutHDoc`. See Note [SDoc versus HDoc] and Note [HLine versus HDoc]. The classes `IsLine` and `IsDoc` are used to make the existing code polymorphic over `HLine`/`HDoc` and `SDoc`. This is done for X86, PPC, AArch64, DWARF and dependencies (printing module names, labels etc.). Co-authored-by: Alexis King <lexi.lambda at gmail.com> Metric Decrease: CoOpt_Read ManyAlternatives ManyConstructors T10421 T12425 T12707 T13035 T13056 T13253 T13379 T18140 T18282 T18698a T18698b T1969 T20049 T21839c T21839r T3064 T3294 T4801 T5321FD T5321Fun T5631 T6048 T783 T9198 T9233 - - - - - 6b92b47f by Matthew Craven at 2022-11-11T18:32:14-05:00 Weaken wrinkle 1 of Note [Scrutinee Constant Folding] Fixes #22375. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 154c70f6 by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Fix fragile RULE setup in GHC.Float In testing my type-vs-constraint patch I found that the handling of Natural literals was very fragile -- and I somehow tripped that fragility in my work. So this patch fixes the fragility. See Note [realToFrac natural-to-float] This made a big (9%) difference in one existing test in perf/should_run/T1-359 Metric Decrease: T10359 - - - - - 778c6adc by Simon Peyton Jones at 2022-11-11T23:40:10+00:00 Type vs Constraint: finally nailed This big patch addresses the rats-nest of issues that have plagued us for years, about the relationship between Type and Constraint. See #11715/#21623. The main payload of the patch is: * To introduce CONSTRAINT :: RuntimeRep -> Type * To make TYPE and CONSTRAINT distinct throughout the compiler Two overview Notes in GHC.Builtin.Types.Prim * Note [TYPE and CONSTRAINT] * Note [Type and Constraint are not apart] This is the main complication. The specifics * New primitive types (GHC.Builtin.Types.Prim) - CONSTRAINT - ctArrowTyCon (=>) - tcArrowTyCon (-=>) - ccArrowTyCon (==>) - funTyCon FUN -- Not new See Note [Function type constructors and FunTy] and Note [TYPE and CONSTRAINT] * GHC.Builtin.Types: - New type Constraint = CONSTRAINT LiftedRep - I also stopped nonEmptyTyCon being built-in; it only needs to be wired-in * Exploit the fact that Type and Constraint are distinct throughout GHC - Get rid of tcView in favour of coreView. - Many tcXX functions become XX functions. e.g. tcGetCastedTyVar --> getCastedTyVar * Kill off Note [ForAllTy and typechecker equality], in (old) GHC.Tc.Solver.Canonical. It said that typechecker-equality should ignore the specified/inferred distinction when comparein two ForAllTys. But that wsa only weakly supported and (worse) implies that we need a separate typechecker equality, different from core equality. No no no. * GHC.Core.TyCon: kill off FunTyCon in data TyCon. There was no need for it, and anyway now we have four of them! * GHC.Core.TyCo.Rep: add two FunTyFlags to FunCo See Note [FunCo] in that module. * GHC.Core.Type. Lots and lots of changes driven by adding CONSTRAINT. The key new function is sORTKind_maybe; most other changes are built on top of that. See also `funTyConAppTy_maybe` and `tyConAppFun_maybe`. * Fix a longstanding bug in GHC.Core.Type.typeKind, and Core Lint, in kinding ForAllTys. See new tules (FORALL1) and (FORALL2) in GHC.Core.Type. (The bug was that before (forall (cv::t1 ~# t2). blah), where blah::TYPE IntRep, would get kind (TYPE IntRep), but it should be (TYPE LiftedRep). See Note [Kinding rules for types] in GHC.Core.Type. * GHC.Core.TyCo.Compare is a new module in which we do eqType and cmpType. Of course, no tcEqType any more. * GHC.Core.TyCo.FVs. I moved some free-var-like function into this module: tyConsOfType, visVarsOfType, and occCheckExpand. Refactoring only. * GHC.Builtin.Types. Compiletely re-engineer boxingDataCon_maybe to have one for each /RuntimeRep/, rather than one for each /Type/. This dramatically widens the range of types we can auto-box. See Note [Boxing constructors] in GHC.Builtin.Types The boxing types themselves are declared in library ghc-prim:GHC.Types. GHC.Core.Make. Re-engineer the treatment of "big" tuples (mkBigCoreVarTup etc) GHC.Core.Make, so that it auto-boxes unboxed values and (crucially) types of kind Constraint. That allows the desugaring for arrows to work; it gathers up free variables (including dictionaries) into tuples. See Note [Big tuples] in GHC.Core.Make. There is still work to do here: #22336. But things are better than before. * GHC.Core.Make. We need two absent-error Ids, aBSENT_ERROR_ID for types of kind Type, and aBSENT_CONSTRAINT_ERROR_ID for vaues of kind Constraint. Ditto noInlineId vs noInlieConstraintId in GHC.Types.Id.Make; see Note [inlineId magic]. * GHC.Core.TyCo.Rep. Completely refactor the NthCo coercion. It is now called SelCo, and its fields are much more descriptive than the single Int we used to have. A great improvement. See Note [SelCo] in GHC.Core.TyCo.Rep. * GHC.Core.RoughMap.roughMatchTyConName. Collapse TYPE and CONSTRAINT to a single TyCon, so that the rough-map does not distinguish them. * GHC.Core.DataCon - Mainly just improve documentation * Some significant renamings: GHC.Core.Multiplicity: Many --> ManyTy (easier to grep for) One --> OneTy GHC.Core.TyCo.Rep TyCoBinder --> GHC.Core.Var.PiTyBinder GHC.Core.Var TyCoVarBinder --> ForAllTyBinder AnonArgFlag --> FunTyFlag ArgFlag --> ForAllTyFlag GHC.Core.TyCon TyConTyCoBinder --> TyConPiTyBinder Many functions are renamed in consequence e.g. isinvisibleArgFlag becomes isInvisibleForAllTyFlag, etc * I refactored FunTyFlag (was AnonArgFlag) into a simple, flat data type data FunTyFlag = FTF_T_T -- (->) Type -> Type | FTF_T_C -- (-=>) Type -> Constraint | FTF_C_T -- (=>) Constraint -> Type | FTF_C_C -- (==>) Constraint -> Constraint * GHC.Tc.Errors.Ppr. Some significant refactoring in the TypeEqMisMatch case of pprMismatchMsg. * I made the tyConUnique field of TyCon strict, because I saw code with lots of silly eval's. That revealed that GHC.Settings.Constants.mAX_SUM_SIZE can only be 63, because we pack the sum tag into a 6-bit field. (Lurking bug squashed.) Fixes * #21530 Updates haddock submodule slightly. Performance changes ~~~~~~~~~~~~~~~~~~~ I was worried that compile times would get worse, but after some careful profiling we are down to a geometric mean 0.1% increase in allocation (in perf/compiler). That seems fine. There is a big runtime improvement in T10359 Metric Decrease: LargeRecord MultiLayerModulesTH_OneShot T13386 T13719 Metric Increase: T8095 - - - - - 360f5fec by Simon Peyton Jones at 2022-11-11T23:40:11+00:00 Indent closing "#-}" to silence HLint - - - - - e160cf47 by Krzysztof Gogolewski at 2022-11-12T08:05:28-05:00 Fix merge conflict in T18355.stderr Fixes #22446 - - - - - 294f9073 by Simon Peyton Jones at 2022-11-12T23:14:13+00:00 Fix a trivial typo in dataConNonlinearType Fixes #22416 - - - - - 268a3ce9 by Ben Gamari at 2022-11-14T09:36:57-05:00 eventlog: Ensure that IPE output contains actual info table pointers The refactoring in 866c736e introduced a rather subtle change in the semantics of the IPE eventlog output, changing the eventlog field from encoding info table pointers to "TNTC pointers" (which point to entry code when tables-next-to-code is enabled). Fix this. Fixes #22452. - - - - - d91db679 by Matthew Pickering at 2022-11-14T16:48:10-05:00 testsuite: Add tests for T22347 These are fixed in recent versions but might as well add regression tests. See #22347 - - - - - 8f6c576b by Matthew Pickering at 2022-11-14T16:48:45-05:00 testsuite: Improve output from tests which have failing pre_cmd There are two changes: * If a pre_cmd fails, then don't attempt to run the test. * If a pre_cmd fails, then print the stdout and stderr from running that command (which hopefully has a nice error message). For example: ``` =====> 1 of 1 [0, 0, 0] *** framework failure for test-defaulting-plugin(normal) pre_cmd failed: 2 ** pre_cmd was "$MAKE -s --no-print-directory -C defaulting-plugin package.test-defaulting-plugin TOP={top}". stdout: stderr: DefaultLifted.hs:19:13: error: [GHC-76037] Not in scope: type constructor or class ‘Typ’ Suggested fix: Perhaps use one of these: ‘Type’ (imported from GHC.Tc.Utils.TcType), data constructor ‘Type’ (imported from GHC.Plugins) | 19 | instance Eq Typ where | ^^^ make: *** [Makefile:17: package.test-defaulting-plugin] Error 1 Performance Metrics (test environment: local): ``` Fixes #22329 - - - - - 2b7d5ccc by Madeline Haraj at 2022-11-14T22:44:17+00:00 Implement UNPACK support for sum types. This is based on osa's unpack_sums PR from ages past. The meat of the patch is implemented in dataConArgUnpackSum and described in Note [UNPACK for sum types]. - - - - - 78f7ecb0 by Andreas Klebinger at 2022-11-14T22:20:29-05:00 Expand on the need to clone local binders. Fixes #22402. - - - - - 65ce43cc by Krzysztof Gogolewski at 2022-11-14T22:21:05-05:00 Fix :i Constraint printing "type Constraint = Constraint" Since Constraint became a synonym for CONSTRAINT 'LiftedRep, we need the same code for handling printing as for the synonym Type = TYPE 'LiftedRep. This addresses the same bug as #18594, so I'm reusing the test. - - - - - 94549f8f by ARATA Mizuki at 2022-11-15T21:36:03-05:00 configure: Don't check for an unsupported version of LLVM The upper bound is not inclusive. Fixes #22449 - - - - - 02d3511b by Bodigrim at 2022-11-15T21:36:41-05:00 Fix capitalization in haddock for TestEquality - - - - - 08bf2881 by Cheng Shao at 2022-11-16T09:16:29+00:00 base: make Foreign.Marshal.Pool use RTS internal arena for allocation `Foreign.Marshal.Pool` used to call `malloc` once for each allocation request. Each `Pool` maintained a list of allocated pointers, and traverses the list to `free` each one of those pointers. The extra O(n) overhead is apparently bad for a `Pool` that serves a lot of small allocation requests. This patch uses the RTS internal arena to implement `Pool`, with these benefits: - Gets rid of the extra O(n) overhead. - The RTS arena is simply a bump allocator backed by the block allocator, each allocation request is likely faster than a libc `malloc` call. Closes #14762 #18338. - - - - - 37cfe3c0 by Krzysztof Gogolewski at 2022-11-16T14:50:06-05:00 Misc cleanup * Replace catMaybes . map f with mapMaybe f * Use concatFS to concatenate multiple FastStrings * Fix documentation of -exclude-module * Cleanup getIgnoreCount in GHCi.UI - - - - - b0ac3813 by Lawton Nichols at 2022-11-19T03:22:14-05:00 Give better errors for code corrupted by Unicode smart quotes (#21843) Previously, we emitted a generic and potentially confusing error during lexical analysis on programs containing smart quotes (“/”/‘/’). This commit adds smart quote-aware lexer errors. - - - - - cb8430f8 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make OpaqueNo* tests less noisy to unrelated changes - - - - - b1a8af69 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Simplifier: Consider `seq` as a `BoringCtxt` (#22317) See `Note [Seq is boring]` for the rationale. Fixes #22317. - - - - - 9fd11585 by Sebastian Graf at 2022-11-19T03:22:49-05:00 Make T21839c's ghc/max threshold more forgiving - - - - - 4b6251ab by Simon Peyton Jones at 2022-11-19T03:23:24-05:00 Be more careful when reporting unbound RULE binders See Note [Variables unbound on the LHS] in GHC.HsToCore.Binds. Fixes #22471. - - - - - e8f2b80d by Peter Trommler at 2022-11-19T03:23:59-05:00 PPC NCG: Fix generating assembler code Fixes #22479 - - - - - f2f9ef07 by Bodigrim at 2022-11-20T18:39:30-05:00 Extend documentation for Data.IORef - - - - - ef511b23 by Simon Peyton Jones at 2022-11-20T18:40:05-05:00 Buglet in GHC.Tc.Module.checkBootTyCon This lurking bug used the wrong function to compare two types in GHC.Tc.Module.checkBootTyCon It's hard to trigger the bug, which only came up during !9343, so there's no regression test in this MR. - - - - - 451aeac3 by Bodigrim at 2022-11-20T18:40:44-05:00 Add since pragmas for c_interruptible_open and hostIsThreaded - - - - - 8d6aaa49 by Duncan Coutts at 2022-11-22T02:06:16-05:00 Introduce CapIOManager as the per-cap I/O mangager state Rather than each I/O manager adding things into the Capability structure ad-hoc, we should have a common CapIOManager iomgr member of the Capability structure, with a common interface to initialise etc. The content of the CapIOManager struct will be defined differently for each I/O manager implementation. Eventually we should be able to have the CapIOManager be opaque to the rest of the RTS, and known just to the I/O manager implementation. We plan for that by making the Capability contain a pointer to the CapIOManager rather than containing the structure directly. Initially just move the Unix threaded I/O manager's control FD. - - - - - 8901285e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Add hook markCapabilityIOManager To allow I/O managers to have GC roots in the Capability, within the CapIOManager structure. Not yet used in this patch. - - - - - 5cf709c5 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move APPEND_TO_BLOCKED_QUEUE from cmm to C The I/O and delay blocking primitives for the non-threaded way currently access the blocked_queue and sleeping_queue directly. We want to move where those queues are to make their ownership clearer: to have them clearly belong to the I/O manager impls rather than to the scheduler. Ultimately we will want to change their representation too. It's inconvenient to do that if these queues are accessed directly from cmm code. So as a first step, replace the APPEND_TO_BLOCKED_QUEUE with a C version appendToIOBlockedQueue(), and replace the open-coded sleeping_queue insertion with insertIntoSleepingQueue(). - - - - - ced9acdb by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move {blocked,sleeping}_queue from scheduler global vars to CapIOManager The blocked_queue_{hd,tl} and the sleeping_queue are currently cooperatively managed between the scheduler and (some but not all of) the non-threaded I/O manager implementations. They lived as global vars with the scheduler, but are poked by I/O primops and the I/O manager backends. This patch is a step on the path towards making the management of I/O or timer blocking belong to the I/O managers and not the scheduler. Specifically, this patch moves the {blocked,sleeping}_queue from being global vars in the scheduler to being members of the CapIOManager struct within each Capability. They are not yet exclusively used by the I/O managers: they are still poked from a couple other places, notably in the scheduler before calling awaitEvent. - - - - - 0f68919e by Duncan Coutts at 2022-11-22T02:06:17-05:00 Remove the now-unused markScheduler The global vars {blocked,sleeping}_queue are now in the Capability and so get marked there via markCapabilityIOManager. - - - - - 39a91f60 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move macros for checking for pending IO or timers from Schedule.h to Schedule.c and IOManager.h This is just moving, the next step will be to rejig them slightly. For the non-threaded RTS the scheduler needs to be able to test for there being pending I/O operation or pending timers. The implementation of these tests should really be considered to be part of the I/O managers and not part of the scheduler. - - - - - 664b034b by Duncan Coutts at 2022-11-22T02:06:17-05:00 Replace EMPTY_{BLOCKED,SLEEPING}_QUEUE macros by function These are the macros originaly from Scheduler.h, previously moved to IOManager.h, and now replaced with a single inline function anyPendingTimeoutsOrIO(). We can use a single function since the two macros were always checked together. Note that since anyPendingTimeoutsOrIO is defined for all IO manager cases, including threaded, we do not need to guard its use by cpp #if !defined(THREADED_RTS) - - - - - 32946220 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Expand emptyThreadQueues inline for clarity It was not really adding anything. The name no longer meant anything since those I/O and timeout queues do not belong to the scheuler. In one of the two places it was used, the comments already had to explain what it did, whereas now the code matches the comment nicely. - - - - - 9943baf9 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Move the awaitEvent declaration into IOManager.h And add or adjust comments at the use sites of awaitEvent. - - - - - 054dcc9d by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to awaitEvent It is currently only used in the non-threaded RTS so it works to use MainCapability, but it's a bit nicer to pass the cap anyway. It's certainly shorter. - - - - - 667fe5a4 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Pass the Capability *cap explicitly to appendToIOBlockedQueue And to insertIntoSleepingQueue. Again, it's a bit cleaner and simpler though not strictly necessary given that these primops are currently only used in the non-threaded RTS. - - - - - 7181b074 by Duncan Coutts at 2022-11-22T02:06:17-05:00 Reveiew feedback: improve one of the TODO comments The one about the nonsense (const False) test on WinIO for there being any IO or timers pending, leading to unnecessary complication later in the scheduler. - - - - - e5b68183 by Andreas Klebinger at 2022-11-22T02:06:52-05:00 Optimize getLevity. Avoid the intermediate data structures allocated by splitTyConApp. This avoids ~0.5% of allocations for a build using -O2. Fixes #22254 - - - - - de5fb348 by Andreas Klebinger at 2022-11-22T02:07:28-05:00 hadrian:Set TNTC when running testsuite. - - - - - 9d61c182 by Oleg Grenrus at 2022-11-22T15:59:34-05:00 Add unsafePtrEquality# restricted to UnliftedTypes - - - - - e817c871 by Jonathan Dowland at 2022-11-22T16:00:14-05:00 utils/unlit: adjust parser to match Report spec The Haskell 2010 Report says that, for Latex-style Literate format, "Program code begins on the first line following a line that begins \begin{code}". (This is unchanged from the 98 Report) However the unlit.c implementation only matches a line that contains "\begin{code}" and nothing else. One consequence of this is that one cannot suffix Latex options to the code environment. I.e., this does not work: \begin{code}[label=foo,caption=Foo Code] Adjust the matcher to conform to the specification from the Report. The Haskell Wiki currently recommends suffixing a '%' to \begin{code} in order to deliberately hide a code block from Haskell. This is bad advice, as it's relying on an implementation quirk rather than specified behaviour. None-the-less, some people have tried to use it, c.f. <https://mail.haskell.org/pipermail/haskell-cafe/2009-September/066780.html> An alternative solution is to define a separate, equivalent Latex environment to "code", that is functionally identical in Latex but ignored by unlit. This should not be a burden: users are required to manually define the code environment anyway, as it is not provided by the Latex verbatim or lstlistings packages usually used for presenting code in documents. Fixes #3549. - - - - - 0b7fef11 by Teo Camarasu at 2022-11-23T12:44:33-05:00 Fix eventlog all option Previously it didn't enable/disable nonmoving_gc and ticky event types Fixes #21813 - - - - - 04d0618c by Arnaud Spiwack at 2022-11-23T12:45:14-05:00 Expand Note [Linear types] with the stance on linting linearity Per the discussion on #22123 - - - - - e1538516 by Lawton Nichols at 2022-11-23T12:45:55-05:00 Add documentation on custom Prelude modules (#22228) Specifically, custom Prelude modules that are named `Prelude`. - - - - - b5c71454 by Sylvain Henry at 2022-11-23T12:46:35-05:00 Don't let configure perform trivial substitutions (#21846) Hadrian now performs substitutions, especially to generate .cabal files from .cabal.in files. Two benefits: 1. We won't have to re-configure when we modify thing.cabal.in. Hadrian will take care of this for us. 2. It paves the way to allow the same package to be configured differently by Hadrian in the same session. This will be useful to fix #19174: we want to build a stage2 cross-compiler for the host platform and a stage1 compiler for the cross target platform in the same Hadrian session. - - - - - 99aca26b by nineonine at 2022-11-23T12:47:11-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043) Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043 - - - - - 040bfdc3 by M Farkas-Dyck at 2022-11-23T21:59:03-05:00 Scrub some no-warning pragmas. - - - - - 178c1fd8 by Vladislav Zavialov at 2022-11-23T21:59:39-05:00 Check if the SDoc starts with a single quote (#22488) This patch fixes pretty-printing of character literals inside promoted lists and tuples. When we pretty-print a promoted list or tuple whose first element starts with a single quote, we want to add a space between the opening bracket and the element: '[True] -- ok '[ 'True] -- ok '['True] -- not ok If we don't add the space, we accidentally produce a character literal '['. Before this patch, pprSpaceIfPromotedTyCon inspected the type as an AST and tried to guess if it would be rendered with a single quote. However, it missed the case when the inner type was itself a character literal: '[ 'x'] -- ok '['x'] -- not ok Instead of adding this particular case, I opted for a more future-proof solution: check the SDoc directly. This way we can detect if the single quote is actually there instead of trying to predict it from the AST. The new function is called spaceIfSingleQuote. - - - - - 11627c42 by Matthew Pickering at 2022-11-23T22:00:15-05:00 notes: Fix references to HPT space leak note Updating this note was missed when updating the HPT to the HUG. Fixes #22477 - - - - - 86ff1523 by Andrei Borzenkov at 2022-11-24T17:24:51-05:00 Convert diagnostics in GHC.Rename.Expr to proper TcRnMessage (#20115) Problem: avoid usage of TcRnMessageUnknown Solution: The following `TcRnMessage` messages has been introduced: TcRnNoRebindableSyntaxRecordDot TcRnNoFieldPunsRecordDot TcRnIllegalStaticExpression TcRnIllegalStaticFormInSplice TcRnListComprehensionDuplicateBinding TcRnEmptyStmtsGroup TcRnLastStmtNotExpr TcRnUnexpectedStatementInContext TcRnIllegalTupleSection TcRnIllegalImplicitParameterBindings TcRnSectionWithoutParentheses Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - d198a19a by Cheng Shao at 2022-11-24T17:25:29-05:00 rts: fix missing Arena.h symbols in RtsSymbols.c It was an unfortunate oversight in !8961 and broke devel2 builds. - - - - - 5943e739 by Bodigrim at 2022-11-25T04:38:28-05:00 Assorted fixes to avoid Data.List.{head,tail} - - - - - 1f1b99b8 by sheaf at 2022-11-25T04:38:28-05:00 Review suggestions for assorted fixes to avoid Data.List.{head,tail} - - - - - 13d627bb by Vladislav Zavialov at 2022-11-25T04:39:04-05:00 Print unticked promoted data constructors (#20531) Before this patch, GHC unconditionally printed ticks before promoted data constructors: ghci> type T = True -- unticked (user-written) ghci> :kind! T T :: Bool = 'True -- ticked (compiler output) After this patch, GHC prints ticks only when necessary: ghci> type F = False -- unticked (user-written) ghci> :kind! F F :: Bool = False -- unticked (compiler output) ghci> data False -- introduce ambiguity ghci> :kind! F F :: Bool = 'False -- ticked by necessity (compiler output) The old behavior can be enabled by -fprint-redundant-promotion-ticks. Summary of changes: * Rename PrintUnqualified to NamePprCtx * Add QueryPromotionTick to it * Consult the GlobalRdrEnv to decide whether to print a tick (see mkPromTick) * Introduce -fprint-redundant-promotion-ticks Co-authored-by: Artyom Kuznetsov <hi at wzrd.ht> - - - - - d10dc6bd by Simon Peyton Jones at 2022-11-25T22:31:27+00:00 Fix decomposition of TyConApps Ticket #22331 showed that we were being too eager to decompose a Wanted TyConApp, leading to incompleteness in the solver. To understand all this I ended up doing a substantial rewrite of the old Note [Decomposing equalities], now reborn as Note [Decomposing TyConApp equalities]. Plus rewrites of other related Notes. The actual fix is very minor and actually simplifies the code: in `can_decompose` in `GHC.Tc.Solver.Canonical.canTyConApp`, we now call `noMatchableIrreds`. A closely related refactor: we stop trying to use the same "no matchable givens" function here as in `matchClassInst`. Instead split into two much simpler functions. - - - - - 2da5c38a by Will Hawkins at 2022-11-26T04:05:04-05:00 Redirect output of musttail attribute test Compilation output from test for support of musttail attribute leaked to the console. - - - - - 0eb1c331 by Cheng Shao at 2022-11-28T08:55:53+00:00 Move hs_mulIntMayOflo cbits to ghc-prim It's only used by wasm NCG at the moment, but ghc-prim is a more reasonable place for hosting out-of-line primops. Also, we only need a single version of hs_mulIntMayOflo. - - - - - 36b53a9d by Cheng Shao at 2022-11-28T09:05:57+00:00 compiler: generate ccalls for clz/ctz/popcnt in wasm NCG We used to generate a single wasm clz/ctz/popcnt opcode, but it's wrong when it comes to subwords, so might as well generate ccalls for them. See #22470 for details. - - - - - d4134e92 by Cheng Shao at 2022-11-28T23:48:14-05:00 compiler: remove unused MO_U_MulMayOflo We actually only emit MO_S_MulMayOflo and never emit MO_U_MulMayOflo anywhere. - - - - - 8d15eadc by Apoorv Ingle at 2022-11-29T03:09:31-05:00 Killing cc_fundeps, streamlining kind equality orientation, and type equality processing order Fixes: #217093 Associated to #19415 This change * Flips the orientation of the the generated kind equality coercion in canEqLHSHetero; * Removes `cc_fundeps` in CDictCan as the check was incomplete; * Changes `canDecomposableTyConAppOk` to ensure we process kind equalities before type equalities and avoiding a call to `canEqLHSHetero` while processing wanted TyConApp equalities * Adds 2 new tests for validating the change - testsuites/typecheck/should_compile/T21703.hs and - testsuites/typecheck/should_fail/T19415b.hs (a simpler version of T19415.hs) * Misc: Due to the change in the equality direction some error messages now have flipped type mismatch errors * Changes in Notes: - Note [Fundeps with instances, and equality orientation] supercedes Note [Fundeps with instances] - Added Note [Kind Equality Orientation] to visualize the kind flipping - Added Note [Decomposing Dependent TyCons and Processing Wanted Equalties] - - - - - 646969d4 by Krzysztof Gogolewski at 2022-11-29T03:10:13-05:00 Change printing of sized literals to match the proposal Literals in Core were printed as e.g. 0xFF#16 :: Int16#. The proposal 451 now specifies syntax 0xFF#Int16. This change affects the Core printer only - more to be done later. Part of #21422. - - - - - 02e282ec by Simon Peyton Jones at 2022-11-29T03:10:48-05:00 Be a bit more selective about floating bottoming expressions This MR arranges to float a bottoming expression to the top only if it escapes a value lambda. See #22494 and Note [Floating to the top] in SetLevels. This has a generally beneficial effect in nofib +-------------------------------++----------+ | ||tsv (rel) | +===============================++==========+ | imaginary/paraffins || -0.93% | | imaginary/rfib || -0.05% | | real/fem || -0.03% | | real/fluid || -0.01% | | real/fulsom || +0.05% | | real/gamteb || -0.27% | | real/gg || -0.10% | | real/hidden || -0.01% | | real/hpg || -0.03% | | real/scs || -11.13% | | shootout/k-nucleotide || -0.01% | | shootout/n-body || -0.08% | | shootout/reverse-complement || -0.00% | | shootout/spectral-norm || -0.02% | | spectral/fibheaps || -0.20% | | spectral/hartel/fft || -1.04% | | spectral/hartel/solid || +0.33% | | spectral/hartel/wave4main || -0.35% | | spectral/mate || +0.76% | +===============================++==========+ | geom mean || -0.12% | The effect on compile time is generally slightly beneficial Metrics: compile_time/bytes allocated ---------------------------------------------- MultiLayerModulesTH_OneShot(normal) +0.3% PmSeriesG(normal) -0.2% PmSeriesT(normal) -0.1% T10421(normal) -0.1% T10421a(normal) -0.1% T10858(normal) -0.1% T11276(normal) -0.1% T11303b(normal) -0.2% T11545(normal) -0.1% T11822(normal) -0.1% T12150(optasm) -0.1% T12234(optasm) -0.3% T13035(normal) -0.2% T16190(normal) -0.1% T16875(normal) -0.4% T17836b(normal) -0.2% T17977(normal) -0.2% T17977b(normal) -0.2% T18140(normal) -0.1% T18282(normal) -0.1% T18304(normal) -0.2% T18698a(normal) -0.1% T18923(normal) -0.1% T20049(normal) -0.1% T21839r(normal) -0.1% T5837(normal) -0.4% T6048(optasm) +3.2% BAD T9198(normal) -0.2% T9630(normal) -0.1% TcPlugin_RewritePerf(normal) -0.4% hard_hole_fits(normal) -0.1% geo. mean -0.0% minimum -0.4% maximum +3.2% The T6048 outlier is hard to pin down, but it may be the effect of reading in more interface files definitions. It's a small program for which compile time is very short, so I'm not bothered about it. Metric Increase: T6048 - - - - - ab23dc5e by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Mark unpack_sums_6 as fragile due to #22504 This test is explicitly dependent upon runtime, which is generally not appropriate given that the testsuite is run in parallel and generally saturates the CPU. - - - - - def47dd3 by Ben Gamari at 2022-11-29T03:11:25-05:00 testsuite: Don't use grep -q in unpack_sums_7 `grep -q` closes stdin as soon as it finds the pattern it is looking for, resulting in #22484. - - - - - cc25d52e by Sylvain Henry at 2022-11-29T09:44:31+01:00 Add Javascript backend Add JS backend adapted from the GHCJS project by Luite Stegeman. Some features haven't been ported or implemented yet. Tests for these features have been disabled with an associated gitlab ticket. Bump array submodule Work funded by IOG. Co-authored-by: Jeffrey Young <jeffrey.young at iohk.io> Co-authored-by: Luite Stegeman <stegeman at gmail.com> Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com> - - - - - 68c966cd by sheaf at 2022-11-30T09:31:25-05:00 Fix @since annotations on WithDict and Coercible Fixes #22453 - - - - - a3a8e9e9 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Be more careful in GHC.Tc.Solver.Interact.solveOneFromTheOther We were failing to account for the cc_pend_sc flag in this important function, with the result that we expanded superclasses forever. Fixes #22516. - - - - - a9d9b8c0 by Simon Peyton Jones at 2022-11-30T09:32:03-05:00 Use mkNakedFunTy in tcPatSynSig As #22521 showed, in tcPatSynSig we make a "fake type" to kind-generalise; and that type has unzonked type variables in it. So we must not use `mkFunTy` (which checks FunTy's invariants) via `mkPhiTy` when building this type. Instead we need to use `mkNakedFunTy`. Easy fix. - - - - - 31462d98 by Andreas Klebinger at 2022-11-30T14:50:58-05:00 Properly cast values when writing/reading unboxed sums. Unboxed sums might store a Int8# value as Int64#. This patch makes sure we keep track of the actual value type. See Note [Casting slot arguments] for the details. - - - - - 10a2a7de by Oleg Grenrus at 2022-11-30T14:51:39-05:00 Move Void to GHC.Base... This change would allow `Void` to be used deeper in module graph. For example exported from `Prelude` (though that might be already possible). Also this change includes a change `stimes @Void _ x = x`, https://github.com/haskell/core-libraries-committee/issues/95 While the above is not required, maintaining old stimes behavior would be tricky as `GHC.Base` doesn't know about `Num` or `Integral`, which would require more hs-boot files. - - - - - b4cfa8e2 by Sebastian Graf at 2022-11-30T14:52:24-05:00 DmdAnal: Reflect the `seq` of strict fields of a DataCon worker (#22475) See the updated `Note [Data-con worker strictness]` and the new `Note [Demand transformer for data constructors]`. Fixes #22475. - - - - - d87f28d8 by Baldur Blöndal at 2022-11-30T21:16:36+01:00 Make Functor a quantified superclass of Bifunctor. See https://github.com/haskell/core-libraries-committee/issues/91 for discussion. This change relates Bifunctor with Functor by requiring second = fmap. Moreover this change is a step towards unblocking the major version bump of bifunctors and profunctors to major version 6. This paves the way to move the Profunctor class into base. For that Functor first similarly becomes a superclass of Profunctor in the new major version 6. - - - - - 72cf4c5d by doyougnu at 2022-12-01T12:36:44-05:00 FastString: SAT bucket_match Metric Decrease: MultiLayerModulesTH_OneShot - - - - - afc2540d by Simon Peyton Jones at 2022-12-01T12:37:20-05:00 Add a missing varToCoreExpr in etaBodyForJoinPoint This subtle bug showed up when compiling a library with 9.4. See #22491. The bug is present in master, but it is hard to trigger; the new regression test T22491 fails in 9.4. The fix was easy: just add a missing varToCoreExpr in etaBodyForJoinPoint. The fix is definitely right though! I also did some other minor refatoring: * Moved the preInlineUnconditionally test in simplExprF1 to before the call to joinPointBinding_maybe, to avoid fruitless eta-expansion. * Added a boolean from_lam flag to simplNonRecE, to avoid two fruitless tests, and commented it a bit better. These refactorings seem to save 0.1% on compile-time allocation in perf/compiler; with a max saving of 1.4% in T9961 Metric Decrease: T9961 - - - - - 81eeec7f by M Farkas-Dyck at 2022-12-01T12:37:56-05:00 CI: Forbid the fully static build on Alpine to fail. To do so, we mark some tests broken in this configuration. - - - - - c5d1bf29 by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Remove ARMv7 jobs These jobs fail (and are allowed to fail) nearly every time. Soon they won't even be able to run at all, as we won't currently have runners that can run them. Fixing the latter problem is tracked in #22409. I went ahead and removed all settings and configurations. - - - - - d82992fd by Bryan Richter at 2022-12-01T12:37:56-05:00 CI: Fix CI lint Failure was introduced by conflicting changes to gen_ci.hs that did *not* trigger git conflicts. - - - - - ce126993 by Simon Peyton Jones at 2022-12-02T01:22:12-05:00 Refactor TyCon to have a top-level product This patch changes the representation of TyCon so that it has a top-level product type, with a field that gives the details (newtype, type family etc), #22458. Not much change in allocation, but execution seems to be a bit faster. Includes a change to the haddock submodule to adjust for API changes. - - - - - 74c767df by Matthew Pickering at 2022-12-02T01:22:48-05:00 ApplicativeDo: Set pattern location before running exhaustiveness checker This improves the error messages of the exhaustiveness checker when checking statements which have been moved around with ApplicativeDo. Before: Test.hs:2:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 2 | let x = () | ^^^^^^^^^^ After: Test.hs:4:3: warning: [GHC-62161] [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns of type ‘Maybe ()’ not matched: Nothing | 4 | ~(Just res1) <- seq x (pure $ Nothing @()) | Fixes #22483 - - - - - 85ecc1a0 by Matthew Pickering at 2022-12-02T19:46:43-05:00 Add special case for :Main module in `GHC.IfaceToCore.mk_top_id` See Note [Root-main Id] The `:Main` special binding is actually defined in the current module (hence don't go looking for it externally) but the module name is rOOT_MAIN rather than the current module so we need this special case. There was already some similar logic in `GHC.Rename.Env` for External Core, but now the "External Core" is in interface files it needs to be moved here instead. Fixes #22405 - - - - - 108c319f by Krzysztof Gogolewski at 2022-12-02T19:47:18-05:00 Fix linearity checking in Lint Lint was not able to see that x*y <= x*y, because this inequality was decomposed to x <= x*y && y <= x*y, but there was no rule to see that x <= x*y. Fixes #22546. - - - - - bb674262 by Bryan Richter at 2022-12-03T04:38:46-05:00 Mark T16916 fragile See https://gitlab.haskell.org/ghc/ghc/-/issues/16966 - - - - - 5d267d46 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 Refactor: FreshOrReuse instead of addTyClTyVarBinds This is a refactoring that should have no effect on observable behavior. Prior to this change, GHC.HsToCore.Quote contained a few closely related functions to process type variable bindings: addSimpleTyVarBinds, addHsTyVarBinds, addQTyVarBinds, and addTyClTyVarBinds. We can classify them by their input type and name generation strategy: Fresh names only Reuse bound names +---------------------+-------------------+ [Name] | addSimpleTyVarBinds | | [LHsTyVarBndr flag GhcRn] | addHsTyVarBinds | | LHsQTyVars GhcRn | addQTyVarBinds | addTyClTyVarBinds | +---------------------+-------------------+ Note how two functions are missing. Because of this omission, there were two places where a LHsQTyVars value was constructed just to be able to pass it to addTyClTyVarBinds: 1. mk_qtvs in addHsOuterFamEqnTyVarBinds -- bad 2. mkHsQTvs in repFamilyDecl -- bad This prevented me from making other changes to LHsQTyVars, so the main goal of this refactoring is to get rid of those workarounds. The most direct solution would be to define the missing functions. But that would lead to a certain amount of code duplication. To avoid code duplication, I factored out the name generation strategy into a function parameter: data FreshOrReuse = FreshNamesOnly | ReuseBoundNames addSimpleTyVarBinds :: FreshOrReuse -> ... addHsTyVarBinds :: FreshOrReuse -> ... addQTyVarBinds :: FreshOrReuse -> ... - - - - - c189b831 by Vladislav Zavialov at 2022-12-03T04:39:22-05:00 addHsOuterFamEqnTyVarBinds: use FreshNamesOnly for explicit binders Consider this example: [d| instance forall a. C [a] where type forall b. G [a] b = Proxy b |] When we process "forall b." in the associated type instance, it is unambiguously the binding site for "b" and we want a fresh name for it. Therefore, FreshNamesOnly is more fitting than ReuseBoundNames. This should not have any observable effect but it avoids pointless lookups in the MetaEnv. - - - - - 42512264 by Ross Paterson at 2022-12-03T10:32:45+00:00 Handle type data declarations in Template Haskell quotations and splices (fixes #22500) This adds a TypeDataD constructor to the Template Haskell Dec type, and ensures that the constructors it contains go in the TyCls namespace. - - - - - 1a767fa3 by Vladislav Zavialov at 2022-12-05T05:18:50-05:00 Add BufSpan to EpaLocation (#22319, #22558) The key part of this patch is the change to mkTokenLocation: - mkTokenLocation (RealSrcSpan r _) = TokenLoc (EpaSpan r) + mkTokenLocation (RealSrcSpan r mb) = TokenLoc (EpaSpan r mb) mkTokenLocation used to discard the BufSpan, but now it is saved and can be retrieved from LHsToken or LHsUniToken. This is made possible by the following change to EpaLocation: - data EpaLocation = EpaSpan !RealSrcSpan + data EpaLocation = EpaSpan !RealSrcSpan !(Strict.Maybe BufSpan) | ... The end goal is to make use of the BufSpan in Parser/PostProcess/Haddock. - - - - - cd31acad by sheaf at 2022-12-06T15:45:58-05:00 Hadrian: fix ghcDebugAssertions off-by-one error Commit 6b2f7ffe changed the logic that decided whether to enable debug assertions. However, it had an off-by-one error, as the stage parameter to the function inconsistently referred to the stage of the compiler being used to build or the stage of the compiler we are building. This patch makes it consistent. Now the parameter always refers to the the compiler which is being built. In particular, this patch re-enables assertions in the stage 2 compiler when building with devel2 flavour, and disables assertions in the stage 2 compiler when building with validate flavour. Some extra performance tests are now run in the "validate" jobs because the stage2 compiler no longer contains assertions. ------------------------- Metric Decrease: CoOpt_Singletons MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot T11374 T12227 T12234 T13253-spj T13701 T14683 T14697 T15703 T17096 T17516 T18304 T18478 T18923 T5030 T9872b TcPlugin_RewritePerf Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T13386 T13719 T3294 T9233 T9675 parsing001 ------------------------- - - - - - 21d66db1 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInstallNameTool - - - - - aaaaa79b by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of askOtool - - - - - 4e28f49e by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of runInjectRPaths - - - - - a7422580 by mrkun at 2022-12-06T15:46:38-05:00 Push DynFlags out of Linker.MacOS - - - - - e902d771 by Matthew Craven at 2022-12-08T08:30:23-05:00 Fix bounds-checking buglet in Data.Array.Byte ...another manifestation of #20851 which I unfortunately missed in my first pass. - - - - - 8d36c0c6 by Gergő Érdi at 2022-12-08T08:31:03-05:00 Remove copy-pasted definitions of `graphFromEdgedVertices*` - - - - - c5d8ed3a by Gergő Érdi at 2022-12-08T08:31:03-05:00 Add version of `reachableGraph` that avoids loop for cyclic inputs by building its result connected component by component Fixes #22512 - - - - - 90cd5396 by Krzysztof Gogolewski at 2022-12-08T08:31:39-05:00 Mark Type.Reflection.Unsafe as Unsafe This module can be used to construct ill-formed TypeReps, so it should be Unsafe. - - - - - 2057c77d by Ian-Woo Kim at 2022-12-08T08:32:19-05:00 Truncate eventlog event for large payload (#20221) RTS eventlog events for postCapsetVecEvent are truncated if payload is larger than EVENT_PAYLOAD_SIZE_MAX Previously, postCapsetVecEvent records eventlog event with payload of variable size larger than EVENT_PAYLOAD_SIZE_MAX (2^16) without any validation, resulting in corrupted data. For example, this happens when a Haskell binary is invoked with very long command line arguments exceeding 2^16 bytes (see #20221). Now we check the size of accumulated payload messages incrementally, and truncate the message just before the payload size exceeds EVENT_PAYLOAD_SIZE_MAX. RTS will warn the user with a message showing how many arguments are truncated. - - - - - 9ec76f61 by Cheng Shao at 2022-12-08T08:32:59-05:00 hadrian: don't add debug info to non-debug ways of rts Hadrian used to pass -g when building all ways of rts. It makes output binaries larger (especially so for wasm backend), and isn't needed by most users out there, so this patch removes that flag. In case the debug info is desired, we still pass -g3 when building the debug way, and there's also the debug_info flavour transformer which ensures -g3 is passed for all rts ways. - - - - - 7658cdd4 by Krzysztof Gogolewski at 2022-12-08T08:33:36-05:00 Restore show (typeRep @[]) == "[]" The Show instance for TypeRep [] has changed in 9.5 to output "List" because the name of the type constructor changed. This seems to be accidental and is inconsistent with TypeReps of saturated lists, which are printed as e.g. "[Int]". For now, I'm restoring the old behavior; in the future, maybe we should show TypeReps without puns (List, Tuple, Type). - - - - - 216deefd by Matthew Pickering at 2022-12-08T22:45:27-05:00 Add test for #22162 - - - - - 5d0a311f by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job to test interface file determinism guarantees In this job we can run on every commit we add a test which builds the Cabal library twice and checks that the ABI hash and interface hash is stable across the two builds. * We run the test 20 times to try to weed out any race conditions due to `-j` * We run the builds in different temporary directories to try to weed out anything related to build directory affecting ABI or interface file hash. Fixes #22180 - - - - - 0a76d7d4 by Matthew Pickering at 2022-12-08T22:45:27-05:00 ci: Add job for testing interface stability across builds The idea is that both the bindists should product libraries with the same ABI and interface hash. So the job checks with ghc-pkg to make sure the computed ABI is the same. In future this job can be extended to check for the other facets of interface determinism. Fixes #22180 - - - - - 74c9bf91 by Matthew Pickering at 2022-12-08T22:45:27-05:00 backpack: Be more careful when adding together ImportAvails There was some code in the signature merging logic which added together the ImportAvails of the signature and the signature which was merged into it. This had the side-effect of making the merged signature depend on the signature (via a normal module dependency). The intention was to propagate orphan instances through the merge but this also messed up recompilation logic because we shouldn't be attempting to load B.hi when mergeing it. The fix is to just combine the part of ImportAvails that we intended to (transitive info, orphan instances and type family instances) rather than the whole thing. - - - - - d122e022 by Matthew Pickering at 2022-12-08T22:45:27-05:00 Fix mk_mod_usage_info if the interface file is not already loaded In #22217 it was observed that the order modules are compiled in affects the contents of an interface file. This was because a module dependended on another module indirectly, via a re-export but the interface file for this module was never loaded because the symbol was never used in the file. If we decide that we depend on a module then we jolly well ought to record this fact in the interface file! Otherwise it could lead to very subtle recompilation bugs if the dependency is not tracked and the module is updated. Therefore the best thing to do is just to make sure the file is loaded by calling the `loadSysInterface` function. This first checks the caches (like we did before) but then actually goes to find the interface on disk if it wasn't loaded. Fixes #22217 - - - - - ea25088d by lrzlin at 2022-12-08T22:46:06-05:00 Add initial support for LoongArch Architecture. - - - - - 9eb9d2f4 by Bodigrim at 2022-12-08T22:46:47-05:00 Update submodule mtl to 2.3.1, parsec to 3.1.15.1, haddock and Cabal to HEAD - - - - - 08d8fe2a by Bodigrim at 2022-12-08T22:46:47-05:00 Allow mtl-2.3 in hadrian - - - - - 3807a46c by Bodigrim at 2022-12-08T22:46:47-05:00 Support mtl-2.3 in check-exact - - - - - ef702a18 by Bodigrim at 2022-12-08T22:46:47-05:00 Fix tests - - - - - 3144e8ff by Sebastian Graf at 2022-12-08T22:47:22-05:00 Make (^) INLINE (#22324) So that we get to cancel away the allocation for the lazily used base. We can move `powImpl` (which *is* strict in the base) to the top-level so that we don't duplicate too much code and move the SPECIALISATION pragmas onto `powImpl`. The net effect of this change is that `(^)` plays along much better with inlining thresholds and loopification (#22227), for example in `x2n1`. Fixes #22324. - - - - - 1d3a8b8e by Matthew Pickering at 2022-12-08T22:47:59-05:00 Typeable: Fix module locations of some definitions in GHC.Types There was some confusion in Data.Typeable about which module certain wired-in things were defined in. Just because something is wired-in doesn't mean it comes from GHC.Prim, in particular things like LiftedRep and RuntimeRep are defined in GHC.Types and that's the end of the story. Things like Int#, Float# etc are defined in GHC.Prim as they have no Haskell definition site at all so we need to generate type representations for them (which live in GHC.Types). Fixes #22510 - - - - - 0f7588b5 by Sebastian Graf at 2022-12-08T22:48:34-05:00 Make `drop` and `dropWhile` fuse (#18964) I copied the fusion framework we have in place for `take`. T18964 asserts that we regress neither when fusion fires nor when it doesn't. Fixes #18964. - - - - - 26e71562 by Sebastian Graf at 2022-12-08T22:49:10-05:00 Do not strictify a DFun's parameter dictionaries (#22549) ... thus fixing #22549. The details are in the refurbished and no longer dead `Note [Do not strictify a DFun's parameter dictionaries]`. There's a regression test in T22549. - - - - - 36093407 by John Ericson at 2022-12-08T22:49:45-05:00 Delete `rts/package.conf.in` It is a relic of the Make build system. The RTS now uses a `package.conf` file generated the usual way by Cabal. - - - - - b0cc2fcf by Krzysztof Gogolewski at 2022-12-08T22:50:21-05:00 Fixes around primitive literals * The SourceText of primitive characters 'a'# did not include the #, unlike for other primitive literals 1#, 1##, 1.0#, 1.0##, "a"#. We can now remove the function pp_st_suffix, which was a hack to add the # back. * Negative primitive literals shouldn't use parentheses, as described in Note [Printing of literals in Core]. Added a testcase to T14681. - - - - - aacf616d by Bryan Richter at 2022-12-08T22:50:56-05:00 testsuite: Mark conc024 fragile on Windows - - - - - ed239a24 by Ryan Scott at 2022-12-09T09:42:16-05:00 Document TH splices' interaction with INCOHERENT instances Top-level declaration splices can having surprising interactions with `INCOHERENT` instances, as observed in #22492. This patch resolves #22492 by documenting this strange interaction in the GHC User's Guide. [ci skip] - - - - - 1023b432 by Mike Pilgrem at 2022-12-09T09:42:56-05:00 Fix #22300 Document GHC's extensions to valid whitespace - - - - - 79b0cec0 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Add support for environments that don't have setImmediate - - - - - 5b007ec5 by Luite Stegeman at 2022-12-09T09:43:38-05:00 Fix bound thread status - - - - - 65335d10 by Matthew Pickering at 2022-12-09T20:15:45-05:00 Update containers submodule This contains a fix necessary for the multi-repl to work on GHC's code base where we try to load containers and template-haskell into the same session. - - - - - 4937c0bb by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-multi: Put interface files in separate directories Before we were putting all the interface files in the same directory which was leading to collisions if the files were called the same thing. - - - - - 8acb5b7b by Matthew Pickering at 2022-12-09T20:15:45-05:00 hadrian-toolargs: Add filepath to allowed repl targets - - - - - 5949d927 by Matthew Pickering at 2022-12-09T20:15:45-05:00 driver: Set correct UnitId when rehydrating modules We were not setting the UnitId before rehydrating modules which just led to us attempting to find things in the wrong HPT. The test for this is the hadrian-multi command (which is now added as a CI job). Fixes #22222 - - - - - ab06c0f0 by Matthew Pickering at 2022-12-09T20:15:45-05:00 ci: Add job to test hadrian-multi command I am not sure this job is good because it requires booting HEAD with HEAD, but it should be fine. - - - - - fac3e568 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hadrian: Update bootstrap plans to 9.2.* series and 9.4.* series. This updates the build plans for the most recent compiler versions, as well as fixing the hadrian-bootstrap-gen script to a specific GHC version. - - - - - 195b08b4 by Matthew Pickering at 2022-12-09T20:16:20-05:00 ci: Bump boot images to use ghc-9.4.3 Also updates the bootstrap jobs to test booting 9.2 and 9.4. - - - - - c658c580 by Matthew Pickering at 2022-12-09T20:16:20-05:00 hlint: Removed redundant UnboxedSums pragmas UnboxedSums is quite confusingly implied by UnboxedTuples, alas, just the way it is. See #22485 - - - - - b3e98a92 by Oleg Grenrus at 2022-12-11T12:26:17-05:00 Add heqT, a kind-heterogeneous variant of heq CLC proposal https://github.com/haskell/core-libraries-committee/issues/99 - - - - - bfd7c1e6 by Bodigrim at 2022-12-11T12:26:55-05:00 Document that Bifunctor instances for tuples are lawful only up to laziness - - - - - 5d1a1881 by Bryan Richter at 2022-12-12T16:22:36-05:00 Mark T21336a fragile - - - - - c30accc2 by Matthew Pickering at 2022-12-12T16:23:11-05:00 Add test for #21476 This issues seems to have been fixed since the ticket was made, so let's add a test and move on. Fixes #21476 - - - - - e9d74a3e by Sebastian Graf at 2022-12-13T22:18:39-05:00 Respect -XStrict in the pattern-match checker (#21761) We were missing a call to `decideBangHood` in the pattern-match checker. There is another call in `matchWrapper.mk_eqn_info` which seems redundant but really is not; see `Note [Desugaring -XStrict matches in Pmc]`. Fixes #21761. - - - - - 884790e2 by Gergő Érdi at 2022-12-13T22:19:14-05:00 Fix loop in the interface representation of some `Unfolding` fields As discovered in #22272, dehydration of the unfolding info of a recursive definition used to involve a traversal of the definition itself, which in turn involves traversing the unfolding info. Hence, a loop. Instead, we now store enough data in the interface that we can produce the unfolding info without this traversal. See Note [Tying the 'CoreUnfolding' knot] for details. Fixes #22272 Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 9f301189 by Alan Zimmerman at 2022-12-13T22:19:50-05:00 EPA: When splitting out header comments, keep ones for first decl Any comments immediately preceding the first declaration are no longer kept as header comments, but attach to the first declaration instead. - - - - - 8b1f1b45 by Sylvain Henry at 2022-12-13T22:20:28-05:00 JS: fix object file name comparison (#22578) - - - - - e9e161bb by Bryan Richter at 2022-12-13T22:21:03-05:00 configure: Bump min bootstrap GHC version to 9.2 - - - - - 75855643 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Don't enable TSAN in stage0 build - - - - - da7b51d8 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce blockConcat - - - - - 34f6b09c by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm: Introduce MemoryOrderings - - - - - 43beaa7b by Ben Gamari at 2022-12-15T03:54:02-05:00 llvm: Respect memory specified orderings - - - - - 8faf74fc by Ben Gamari at 2022-12-15T03:54:02-05:00 Codegen/x86: Eliminate barrier for relaxed accesses - - - - - 6cc3944a by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Reduce some repetition - - - - - 6c9862c4 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Add syntax for ordered loads and stores - - - - - 748490d2 by Ben Gamari at 2022-12-15T03:54:02-05:00 cmm/Parser: Atomic load syntax Originally I had thought I would just use the `prim` call syntax instead of introducing new syntax for atomic loads. However, it turns out that `prim` call syntax tends to make things quite unreadable. This new syntax seems quite natural. - - - - - 28c6781a by Ben Gamari at 2022-12-15T03:54:02-05:00 codeGen: Introduce ThreadSanitizer instrumentation This introduces a new Cmm pass which instruments the program with ThreadSanitizer annotations, allowing full tracking of mutator memory accesses via TSAN. - - - - - d97aa311 by Ben Gamari at 2022-12-15T03:54:02-05:00 Hadrian: Drop TSAN_ENABLED define from flavour This is redundant since the TSANUtils.h already defines it. - - - - - 86974ef1 by Ben Gamari at 2022-12-15T03:54:02-05:00 hadrian: Enable Cmm instrumentation in TSAN flavour - - - - - 93723290 by Ben Gamari at 2022-12-15T03:54:02-05:00 rts: Ensure that global regs are never passed as fun call args This is in general unsafe as they may be clobbered if they are mapped to caller-saved machine registers. See Note [Register parameter passing]. - - - - - 2eb0fb87 by Matthew Pickering at 2022-12-15T03:54:39-05:00 Package Imports: Get candidate packages also from re-exported modules Previously we were just looking at the direct imports to try and work out what a package qualifier could apply to but #22333 pointed out we also needed to look for reexported modules. Fixes #22333 - - - - - 552b7908 by Ben Gamari at 2022-12-15T03:55:15-05:00 compiler: Ensure that MutVar operations have necessary barriers Here we add acquire and release barriers in readMutVar# and writeMutVar#, which are necessary for soundness. Fixes #22468. - - - - - 933d61a4 by Simon Peyton Jones at 2022-12-15T03:55:51-05:00 Fix bogus test in Lint The Lint check for branch compatiblity within an axiom, in GHC.Core.Lint.compatible_branches was subtly different to the check made when contructing an axiom, in GHC.Core.FamInstEnv.compatibleBranches. The latter is correct, so I killed the former and am now using the latter. On the way I did some improvements to pretty-printing and documentation. - - - - - 03ed0b95 by Ryan Scott at 2022-12-15T03:56:26-05:00 checkValidInst: Don't expand synonyms when splitting sigma types Previously, the `checkValidInst` function (used when checking that an instance declaration is headed by an actual type class, not a type synonym) was using `tcSplitSigmaTy` to split apart the `forall`s and instance context. This is incorrect, however, as `tcSplitSigmaTy` expands type synonyms, which can cause instances headed by quantified constraint type synonyms to be accepted erroneously. This patch introduces `splitInstTyForValidity`, a variant of `tcSplitSigmaTy` specialized for validity checking that does _not_ expand type synonyms, and uses it in `checkValidInst`. Fixes #22570. - - - - - ed056bc3 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/Messages: Refactor This doesn't change behavior but makes the code a bit easier to follow. - - - - - 7356f8e0 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/ThreadPaused: Ordering fixes - - - - - 914f0025 by Ben Gamari at 2022-12-16T16:12:44-05:00 eventlog: Silence spurious data race - - - - - fbc84244 by Ben Gamari at 2022-12-16T16:12:44-05:00 Introduce SET_INFO_RELEASE for Cmm - - - - - 821b5472 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Use fences instead of explicit barriers - - - - - 2228c999 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts/stm: Fix memory ordering in readTVarIO# See #22421. - - - - - 99269b9f by Ben Gamari at 2022-12-16T16:12:44-05:00 Improve heap memory barrier Note Also introduce MUT_FIELD marker in Closures.h to document mutable fields. - - - - - 70999283 by Ben Gamari at 2022-12-16T16:12:44-05:00 rts: Introduce getNumCapabilities And ensure accesses to n_capabilities are atomic (although with relaxed ordering). This is necessary as RTS API callers may concurrently call into the RTS without holding a capability. - - - - - 98689f77 by Ben Gamari at 2022-12-16T16:12:44-05:00 ghc: Fix data race in dump file handling Previously the dump filename cache would use a non-atomic update which could potentially result in lost dump contents. Note that this is still a bit racy since the first writer may lag behind a later appending writer. - - - - - 605d9547 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Always use atomics for context_switch and interrupt Since these are modified by the timer handler. - - - - - 86f20258 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts/Timer: Always use atomic operations As noted in #22447, the existence of the pthread-based ITimer implementation means that we cannot assume that the program is single-threaded. - - - - - f8e901dc by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate recent_activity access This makes it easier to ensure that it is accessed using the necessary atomic operations. - - - - - e0affaa9 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate access to capabilities array - - - - - 7ca683e4 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Encapsulate sched_state - - - - - 1cf13bd0 by Ben Gamari at 2022-12-16T16:12:45-05:00 PrimOps: Fix benign MutVar race Relaxed ordering is fine here since the later CAS implies a release. - - - - - 3d2a7e08 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Style fix - - - - - 82c62074 by Ben Gamari at 2022-12-16T16:12:45-05:00 compiler: Use release store in eager blackholing - - - - - eb1a0136 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Fix ordering of makeStableName - - - - - ad0e260a by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Use ordered accesses instead of explicit barriers - - - - - a3eccf06 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Statically allocate capabilities This is a rather simplistic way of solving #17289. - - - - - 287fa3fb by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Ensure that all accesses to pending_sync are atomic - - - - - 351eae58 by Ben Gamari at 2022-12-16T16:12:45-05:00 rts: Note race with wakeBlockingQueue - - - - - 5acf33dd by Bodigrim at 2022-12-16T16:13:22-05:00 Bump submodule directory to 1.3.8.0 and hpc to HEAD - - - - - 0dd95421 by Bodigrim at 2022-12-16T16:13:22-05:00 Accept allocations increase on Windows This is because of `filepath-1.4.100.0` and AFPP, causing increasing round-trips between lists and ByteArray. See #22625 for discussion. Metric Increase: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp T10421 T10547 T12150 T12227 T12234 T12425 T13035 T13253 T13253-spj T13701 T13719 T15703 T16875 T18140 T18282 T18304 T18698a T18698b T18923 T20049 T21839c T21839r T5837 T6048 T9198 T9961 TcPlugin_RewritePerf hard_hole_fits - - - - - ef9ac9d2 by Cheng Shao at 2022-12-16T16:13:59-05:00 testsuite: Mark T9405 as fragile instead of broken on Windows It's starting to pass again, and the unexpected pass blocks CI. - - - - - 1f3abd85 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: remove obsolete commented code in wasm NCG It was just a temporary hack to workaround a bug in the relooper, that bug has been fixed long before the wasm backend is merged. - - - - - e3104eab by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add missing export list of GHC.CmmToAsm.Wasm.FromCmm Also removes some unreachable code here. - - - - - 1c6930bf by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: change fallback function signature to Cmm function signature in wasm NCG In the wasm NCG, when handling a `CLabel` of undefined function without knowing its function signature, we used to fallback to `() -> ()` which is accepted by `wasm-ld`. This patch changes it to the signature of Cmm functions, which equally works, but would be required when we emit tail call instructions. - - - - - 8a81d9d9 by Cheng Shao at 2022-12-16T21:16:28+00:00 compiler: add optional tail-call support in wasm NCG When the `-mtail-call` clang flag is passed at configure time, wasm tail-call extension is enabled, and the wasm NCG will emit `return_call`/`return_call_indirect` instructions to take advantage of it and avoid the `StgRun` trampoline overhead. Closes #22461. - - - - - d1431cc0 by Cheng Shao at 2022-12-17T08:07:15-05:00 base: add missing autoconf checks for waitpid/umask These are not present in wasi-libc. Required for fixing #22589 - - - - - da3f1e91 by Cheng Shao at 2022-12-17T08:07:51-05:00 compiler: make .wasm the default executable extension on wasm32 Following convention as in other wasm toolchains. Fixes #22594. - - - - - ad21f4ef by Cheng Shao at 2022-12-17T08:07:51-05:00 ci: support hello.wasm in ci.sh cross testing logic - - - - - 6fe2d778 by amesgen at 2022-12-18T19:33:49-05:00 Correct `exitWith` Haddocks The `IOError`-specific `catch` in the Prelude is long gone. - - - - - b3eacd64 by Ben Gamari at 2022-12-18T19:34:24-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 761c1f49 by Ben Gamari at 2022-12-18T19:35:00-05:00 rts/libdw: Silence uninitialized usage warnings As noted in #22538, previously some GCC versions warned that various locals in Libdw.c may be used uninitialized. Although this wasn't strictly true (since they were initialized in an inline assembler block) we fix this by providing explicit empty initializers. Fixes #22538 - - - - - 5e047eff by Matthew Pickering at 2022-12-20T15:12:04+00:00 testsuite: Mark T16392 as fragile on windows See #22649 - - - - - 703a4665 by M Farkas-Dyck at 2022-12-20T21:14:46-05:00 Scrub some partiality in `GHC.Cmm.Info.Build`: `doSRTs` takes a `[(CAFSet, CmmDecl)]` but truly wants a `[(CAFSet, CmmStatics)]`. - - - - - 9736ab74 by Matthew Pickering at 2022-12-20T21:15:22-05:00 packaging: Fix upload_ghc_libs.py script This change reflects the changes where .cabal files are now generated by hadrian rather than ./configure. Fixes #22518 - - - - - 7c6de18d by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Drop uses of AC_PROG_CC_C99 As noted in #22566, this macro is deprecated as of autoconf-2.70 `AC_PROG_CC` now sets `ac_cv_prog_cc_c99` itself. Closes #22566. - - - - - 36c5d98e by Ben Gamari at 2022-12-20T21:15:57-05:00 configure: Use AS_HELP_STRING instead of AC_HELP_STRING The latter has been deprecated. See #22566. - - - - - befe6ff8 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: fix various usages of head and tail - - - - - 666d0ba7 by Bodigrim at 2022-12-20T21:16:37-05:00 GHCi.UI: avoid head and tail in parseCallEscape and around - - - - - 5d96fd50 by Bodigrim at 2022-12-20T21:16:37-05:00 Make GHC.Driver.Main.hscTcRnLookupRdrName to return NonEmpty - - - - - 3ce2ab94 by Bodigrim at 2022-12-21T06:17:56-05:00 Allow transformers-0.6 in ghc, ghci, ghc-bin and hadrian - - - - - 954de93a by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule haskeline to HEAD (to allow transformers-0.6) - - - - - cefbeec3 by Bodigrim at 2022-12-21T06:17:56-05:00 Update submodule transformers to 0.6.0.4 - - - - - b4730b62 by Bodigrim at 2022-12-21T06:17:56-05:00 Fix tests T13253 imports MonadTrans, which acquired a quantified constraint in transformers-0.6, thus increase in allocations Metric Increase: T13253 - - - - - 0be75261 by Simon Peyton Jones at 2022-12-21T06:18:32-05:00 Abstract over the right free vars Fix #22459, in two ways: (1) Make the Specialiser not create a bogus specialisation if it is presented by strangely polymorphic dictionary. See Note [Weird special case in SpecDict] in GHC.Core.Opt.Specialise (2) Be more careful in abstractFloats See Note [Which type variables to abstract over] in GHC.Core.Opt.Simplify.Utils. So (2) stops creating the excessively polymorphic dictionary in abstractFloats, while (1) stops crashing if some other pass should nevertheless create a weirdly polymorphic dictionary. - - - - - df7bc6b3 by Ying-Ruei Liang (TheKK) at 2022-12-21T14:31:54-05:00 rts: explicitly store return value of ccall checkClosure to prevent type error (#22617) - - - - - e193e537 by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix shadowing lacuna in OccurAnal Issue #22623 demonstrated another lacuna in the implementation of wrinkle (BS3) in Note [The binder-swap substitution] in the occurrence analyser. I was failing to add TyVar lambda binders using addInScope/addOneInScope and that led to a totally bogus binder-swap transformation. Very easy to fix. - - - - - 3d55d8ab by Simon Peyton Jones at 2022-12-21T14:32:30-05:00 Fix an assertion check in addToEqualCtList The old assertion saw that a constraint ct could rewrite itself (of course it can) and complained (stupid). Fixes #22645 - - - - - ceb2e9b9 by Ben Gamari at 2022-12-21T15:26:08-05:00 configure: Bump version to 9.6 - - - - - fb4d36c4 by Ben Gamari at 2022-12-21T15:27:49-05:00 base: Bump version to 4.18 Requires various submodule bumps. - - - - - 93ee7e90 by Ben Gamari at 2022-12-21T15:27:49-05:00 ghc-boot: Fix bootstrapping - - - - - fc3a2232 by Ben Gamari at 2022-12-22T13:45:06-05:00 Bump GHC version to 9.7 - - - - - 914f7fe3 by Andreas Klebinger at 2022-12-22T23:36:10-05:00 Don't consider large byte arrays/compact regions pinned. Workaround for #22255 which showed how treating large/compact regions as pinned could cause segfaults. - - - - - 32b32d7f by Matthew Pickering at 2022-12-22T23:36:46-05:00 hadrian bindist: Install manpages to share/man/man1/ghc.1 When the installation makefile was copied over the manpages were no longer installed in the correct place. Now we install it into share/man/man1/ghc.1 as the make build system did. Fixes #22371 - - - - - b3ddf803 by Ben Gamari at 2022-12-22T23:37:23-05:00 rts: Drop paths from configure from cabal file A long time ago we would rely on substitutions from the configure script to inject paths of the include and library directories of libffi and libdw. However, now these are instead handled inside Hadrian when calling Cabal's `configure` (see the uses of `cabalExtraDirs` in Hadrian's `Settings.Packages.packageArgs`). While the occurrences in the cabal file were redundant, they did no harm. However, since b5c714545abc5f75a1ffdcc39b4bfdc7cd5e64b4 they have no longer been interpolated. @mpickering noticed the suspicious uninterpolated occurrence of `@FFIIncludeDir@` in #22595, prompting this commit to finally remove them. - - - - - b2c7523d by Ben Gamari at 2022-12-22T23:37:59-05:00 Bump libffi-tarballs submodule We will now use libffi-3.4.4. - - - - - 3699a554 by Alan Zimmerman at 2022-12-22T23:38:35-05:00 EPA: Make EOF position part of AnnsModule Closes #20951 Closes #19697 - - - - - 99757ce8 by Sylvain Henry at 2022-12-22T23:39:13-05:00 JS: fix support for -outputdir (#22641) The `-outputdir` option wasn't correctly handled with the JS backend because the same code path was used to handle both objects produced by the JS backend and foreign .js files. Now we clearly distinguish the two in the pipeline, fixing the bug. - - - - - 02ed7d78 by Simon Peyton Jones at 2022-12-22T23:39:49-05:00 Refactor mkRuntimeError This patch fixes #22634. Because we don't have TYPE/CONSTRAINT polymorphism, we need two error functions rather than one. I took the opportunity to rname runtimeError to impossibleError, to line up with mkImpossibleExpr, and avoid confusion with the genuine runtime-error-constructing functions. - - - - - 35267f07 by Ben Gamari at 2022-12-22T23:40:32-05:00 base: Fix event manager shutdown race on non-Linux platforms During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this. - - - - - 317f45c1 by Simon Peyton Jones at 2022-12-22T23:41:07-05:00 Fix unifier bug: failing to decompose over-saturated type family This simple patch fixes #22647 - - - - - 14b2e3d3 by Ben Gamari at 2022-12-22T23:41:42-05:00 rts/m32: Fix sanity checking Previously we would attempt to clear pages which were marked as read-only. Fix this. - - - - - 16a1bcd1 by Matthew Pickering at 2022-12-23T09:15:24+00:00 ci: Move wasm pipelines into nightly rather than master See #22664 for the changes which need to be made to bring one of these back to the validate pipeline. - - - - - 18d2acd2 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in marking of blackholes We must use an acquire-fence when marking to ensure that the indirectee is visible. - - - - - 11241efa by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix segment list races - - - - - 602455c9 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Use atomic when looking at bd->gen Since it may have been mutated by a moving GC. - - - - - 9d63b160 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Eliminate race in bump_static_flag To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer. - - - - - 26837523 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that mutable fields have acquire barrier - - - - - 8093264a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix races in collector status tracking Mark a number of accesses to do with tracking of the status of the concurrent collection thread as atomic. No interesting races here, merely necessary to satisfy TSAN. - - - - - 387d4fcc by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make segment state updates atomic - - - - - 543cae00 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Refactor update remembered set initialization This avoids a lock inversion between the storage manager mutex and the stable pointer table mutex by not dropping the SM_MUTEX in nonmovingCollect. This requires quite a bit of rejiggering but it does seem like a better strategy. - - - - - c9936718 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Ensure that we aren't holding locks when closing them TSAN complains about this sort of thing. - - - - - 0cd31f7d by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make bitmap accesses atomic This is a benign race on any sensible hard since these are byte accesses. Nevertheless, atomic accesses are necessary to satisfy TSAN. - - - - - d3fe110a by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix benign race in update remembered set check Relaxed load is fine here since we will take the lock before looking at the list. - - - - - ab6cf893 by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Fix race in shortcutting We must use an acquire load to read the info table pointer since if we find an indirection we must be certain that we see the indirectee. - - - - - 36c9f23c by Ben Gamari at 2022-12-23T19:09:30-05:00 nonmoving: Make free list counter accesses atomic Since these may race with the allocator(s). - - - - - aebef31c by doyougnu at 2022-12-23T19:10:09-05:00 add GHC.Utils.Binary.foldGet' and use for Iface A minor optimization to remove lazy IO and a lazy accumulator strictify foldGet' IFace.Binary: use strict foldGet' remove superfluous bang - - - - - 5eb357d9 by Ben Gamari at 2022-12-24T00:41:05-05:00 compiler: Ensure that GHC toolchain is first in search path As noted in #22561, it is important that GHC's toolchain look first for its own headers and libraries to ensure that the system's are not found instead. If this happens things can break in surprising ways (e.g. see #22561). - - - - - cbaebfb9 by Matthew Pickering at 2022-12-24T00:41:40-05:00 head.hackage: Use slow-validate bindist for linting jobs This enables the SLOW_VALIDATE env var for the linting head.hackage jobs, namely the jobs enabled manually, by the label or on the nightly build now use the deb10-numa-slow-validate bindist which has assertions enabled. See #22623 for a ticket which was found by using this configuration already! The head.hackage jobs triggered by upstream CI are now thusly: hackage-lint: Can be triggered on any MR, normal validate pipeline or nightly build. Runs head.hackage with -dlint and a slow-validate bindist hackage-label-lint: Trigged on MRs with "user-facing" label, runs the slow-validate head.hackage build with -dlint. nightly-hackage-lint: Runs automatically on nightly pipelines with slow-validate + dlint config. nightly-hackage-perf: Runs automaticaly on nightly pipelines with release build and eventlogging enabled. release-hackage-lint: Runs automatically on release pipelines with -dlint on a release bindist. - - - - - f4850f36 by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Don't run abi-test-nightly on release jobs The test is not configured to get the correct dependencies for the release pipelines (and indeed stops the release pipeline being run at all) - - - - - c264b06b by Matthew Pickering at 2022-12-24T00:41:40-05:00 ci: Run head.hackage jobs on upstream-testing branch rather than master This change allows less priviledged users to trigger head.hackage jobs because less permissions are needed to trigger jobs on the upstream-testing branch, which is not protected. There is a CI job which updates upstream-testing each hour to the state of the master branch so it should always be relatively up-to-date. - - - - - 63b97430 by Ben Gamari at 2022-12-24T00:42:16-05:00 llvmGen: Fix relaxed ordering Previously I used LLVM's `unordered` ordering for the C11 `relaxed` ordering. However, this is wrong and should rather use the LLVM `monotonic` ordering. Fixes #22640 - - - - - f42ba88f by Ben Gamari at 2022-12-24T00:42:16-05:00 gitlab-ci: Introduce aarch64-linux-llvm job This nightly job will ensure that we don't break the LLVM backend on AArch64/Linux by bootstrapping GHC. This would have caught #22640. - - - - - 6d62f6bf by Matthew Pickering at 2022-12-24T00:42:51-05:00 Store RdrName rather than OccName in Holes In #20472 it was pointed out that you couldn't defer out of scope but the implementation collapsed a RdrName into an OccName to stuff it into a Hole. This leads to the error message for a deferred qualified name dropping the qualification which affects the quality of the error message. This commit adds a bit more structure to a hole, so a hole can replace a RdrName without losing information about what that RdrName was. This is important when printing error messages. I also added a test which checks the Template Haskell deferral of out of scope qualified names works properly. Fixes #22130 - - - - - 3c3060e4 by Richard Eisenberg at 2022-12-24T17:34:19+00:00 Drop support for kind constraints. This implements proposal 547 and closes ticket #22298. See the proposal and ticket for motivation. Compiler perf improves a bit Metrics: compile_time/bytes allocated ------------------------------------- CoOpt_Singletons(normal) -2.4% GOOD T12545(normal) +1.0% T13035(normal) -13.5% GOOD T18478(normal) +0.9% T9872d(normal) -2.2% GOOD geo. mean -0.2% minimum -13.5% maximum +1.0% Metric Decrease: CoOpt_Singletons T13035 T9872d - - - - - 6d7d4393 by Ben Gamari at 2022-12-24T21:09:56-05:00 hadrian: Ensure that linker scripts are used when merging objects In #22527 @rui314 inadvertantly pointed out a glaring bug in Hadrian's implementation of the object merging rules: unlike the old `make` build system we utterly failed to pass the needed linker scripts. Fix this. - - - - - a5bd0eb8 by Bodigrim at 2022-12-24T21:10:34-05:00 Document infelicities of instance Ord Double and workarounds - - - - - 62b9a7b2 by Zubin Duggal at 2023-01-03T12:22:11+00:00 Force the Docs structure to prevent leaks in GHCi with -haddock without -fwrite-interface Involves adding many new NFData instances. Without forcing Docs, references to the TcGblEnv for each module are retained by the Docs structure. Usually these are forced when the ModIface is serialised but not when we aren't writing the interface. - - - - - 21bedd84 by Facundo Domínguez at 2023-01-03T23:27:30-05:00 Explain the auxiliary functions of permutations - - - - - 32255d05 by Matthew Pickering at 2023-01-04T11:58:42+00:00 compiler: Add -f[no-]split-sections flags Here we add a `-fsplit-sections` flag which may some day replace `-split-sections`. This has the advantage of automatically providing a `-fno-split-sections` flag, which is useful for our packaging because we enable `-split-sections` by default but want to disable it in certain configurations. - - - - - e640940c by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Fix computation of tables_next_to_code for outOfTreeCompiler This copy-pasto was introduced in de5fb3489f2a9bd6dc75d0cb8925a27fe9b9084b - - - - - 15bee123 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add test:all_deps to build just testsuite dependencies Fixes #22534 - - - - - fec6638e by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Add no_split_sections tranformer This transformer reverts the effect of `split_sections`, which we intend to use for platforms which don't support split sections. In order to achieve this we have to modify the implemntation of the split_sections transformer to store whether we are enabling split_sections directly in the `Flavour` definition. This is because otherwise there's no convenient way to turn off split_sections due to having to pass additional linker scripts when merging objects. - - - - - 3dc05726 by Matthew Pickering at 2023-01-04T11:58:42+00:00 check-exact: Fix build with -Werror - - - - - 53a6ae7a by Matthew Pickering at 2023-01-04T11:58:42+00:00 ci: Build all test dependencies with in-tree compiler This means that these executables will honour flavour transformers such as "werror". Fixes #22555 - - - - - 32e264c1 by Matthew Pickering at 2023-01-04T11:58:42+00:00 hadrian: Document using GHC environment variable to select boot compiler Fixes #22340 - - - - - be9dd9b0 by Matthew Pickering at 2023-01-04T11:58:42+00:00 packaging: Build perf builds with -split-sections In 8f71d958 the make build system was made to use split-sections on linux systems but it appears this logic never made it to hadrian. There is the split_sections flavour transformer but this doesn't appear to be used for perf builds on linux. This is disbled on deb9 and windows due to #21670 Closes #21135 - - - - - 00dc5106 by Matthew Pickering at 2023-01-04T14:32:45-05:00 sphinx: Use modern syntax for extlinks This fixes the following build error: ``` Command line: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build -b man -d /private/tmp/extra-dir-55768274273/.doctrees-man -n -w /private/tmp/extra-dir-55768274273/.log docs/users_guide /private/tmp/extra-dir-55768274273 ===> Command failed with error code: 2 Exception occurred: File "/opt/homebrew/Cellar/sphinx-doc/6.0.0/libexec/lib/python3.11/site-packages/sphinx/ext/extlinks.py", line 101, in role title = caption % part ~~~~~~~~^~~~~~ TypeError: not all arguments converted during string formatting ``` I tested on Sphinx-5.1.1 and Sphinx-6.0.0 Thanks for sterni for providing instructions about how to test using sphinx-6.0.0. Fixes #22690 - - - - - 541aedcd by Krzysztof Gogolewski at 2023-01-05T10:48:34-05:00 Misc cleanup - Remove unused uniques and hs-boot declarations - Fix types of seq and unsafeCoerce# - Remove FastString/String roundtrip in JS - Use TTG to enforce totality - Remove enumeration in Heap/Inspect; the 'otherwise' clause serves the primitive types well. - - - - - 22bb8998 by Alan Zimmerman at 2023-01-05T10:49:09-05:00 EPA: Do not collect comments from end of file In Parser.y semis1 production triggers for the virtual semi at the end of the file. This is detected by it being zero length. In this case, do not extend the span being used to gather comments, so any final comments are allocated at the module level instead. - - - - - 9e077999 by Vladislav Zavialov at 2023-01-05T23:01:55-05:00 HsToken in TypeArg (#19623) Updates the haddock submodule. - - - - - b2a2db04 by Matthew Pickering at 2023-01-05T23:02:30-05:00 Revert "configure: Drop uses of AC_PROG_CC_C99" This reverts commit 7c6de18dd3151ead954c210336728e8686c91de6. Centos7 using a very old version of the toolchain (autotools-2.69) where the behaviour of these macros has not yet changed. I am reverting this without haste as it is blocking the 9.6 branch. Fixes #22704 - - - - - 28f8c0eb by Luite Stegeman at 2023-01-06T18:16:24+09:00 Add support for sized literals in the bytecode interpreter. The bytecode interpreter only has branching instructions for word-sized values. These are used for pattern matching. Branching instructions for other types (e.g. Int16# or Word8#) weren't needed, since unoptimized Core or STG never requires branching on types like this. It's now possible for optimized STG to reach the bytecode generator (e.g. fat interface files or certain compiler flag combinations), which requires dealing with various sized literals in branches. This patch improves support for generating bytecode from optimized STG by adding the following new bytecode instructions: TESTLT_I64 TESTEQ_I64 TESTLT_I32 TESTEQ_I32 TESTLT_I16 TESTEQ_I16 TESTLT_I8 TESTEQ_I8 TESTLT_W64 TESTEQ_W64 TESTLT_W32 TESTEQ_W32 TESTLT_W16 TESTEQ_W16 TESTLT_W8 TESTEQ_W8 Fixes #21945 - - - - - ac39e8e9 by Matthew Pickering at 2023-01-06T13:47:00-05:00 Only store Name in FunRhs rather than Id with knot-tied fields All the issues here have been caused by #18758. The goal of the ticket is to be able to talk about things like `LTyClDecl GhcTc`. In the case of HsMatchContext, the correct "context" is whatever we want, and in fact storing just a `Name` is sufficient and correct context, even if the rest of the AST is storing typechecker Ids. So this reverts (#20415, !5579) which intended to get closed to #18758 but didn't really and introduced a few subtle bugs. Printing of an error message in #22695 would just hang, because we would attempt to print the `Id` in debug mode to assertain whether it was empty or not. Printing the Name is fine for the error message. Another consequence is that when `-dppr-debug` was enabled the compiler would hang because the debug printing of the Id would try and print fields which were not populated yet. This also led to 32070e6c2e1b4b7c32530a9566fe14543791f9a6 having to add a workaround for the `checkArgs` function which was probably a very similar bug to #22695. Fixes #22695 - - - - - c306d939 by Matthew Pickering at 2023-01-06T22:08:53-05:00 ci: Upgrade darwin, windows and freebsd CI to use GHC-9.4.3 Fixes #22599 - - - - - 0db496ff by Matthew Pickering at 2023-01-06T22:08:53-05:00 darwin ci: Explicitly pass desired build triple to configure On the zw3rk machines for some reason the build machine was inferred to be arm64. Setting the build triple appropiately resolve this confusion and we produce x86 binaries. - - - - - 2459c358 by Ben Gamari at 2023-01-06T22:09:29-05:00 rts: MUT_VAR is not a StgMutArrPtrs There was previously a comment claiming that the MUT_VAR closure type had the layout of StgMutArrPtrs. - - - - - 6206cb92 by Simon Peyton Jones at 2023-01-07T12:14:40-05:00 Make FloatIn robust to shadowing This MR fixes #22622. See the new Note [Shadowing and name capture] I did a bit of refactoring in sepBindsByDropPoint too. The bug doesn't manifest in HEAD, but it did show up in 9.4, so we should backport this patch to 9.4 - - - - - a960ca81 by Matthew Pickering at 2023-01-07T12:15:15-05:00 T10955: Set DYLD_LIBRARY_PATH for darwin The correct path to direct the dynamic linker on darwin is DYLD_LIBRARY_PATH rather than LD_LIBRARY_PATH. On recent versions of OSX using LD_LIBRARY_PATH seems to have stopped working. For more reading see: https://stackoverflow.com/questions/3146274/is-it-ok-to-use-dyld-library-path-on-mac-os-x-and-whats-the-dynamic-library-s - - - - - 73484710 by Matthew Pickering at 2023-01-07T12:15:15-05:00 Skip T18623 on darwin (to add to the long list of OSs) On recent versions of OSX, running `ulimit -v` results in ``` ulimit: setrlimit failed: invalid argument ``` Time is too short to work out what random stuff Apple has been doing with ulimit, so just skip the test like we do for other platforms. - - - - - 8c0ea25f by Matthew Pickering at 2023-01-07T12:15:15-05:00 Pass -Wl,-no_fixup_chains to ld64 when appropiate Recent versions of MacOS use a version of ld where `-fixup_chains` is on by default. This is incompatible with our usage of `-undefined dynamic_lookup`. Therefore we explicitly disable `fixup-chains` by passing `-no_fixup_chains` to the linker on darwin. This results in a warning of the form: ld: warning: -undefined dynamic_lookup may not work with chained fixups The manual explains the incompatible nature of these two flags: -undefined treatment Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error. Note: dynamic_lookup that depends on lazy binding will not work with chained fixups. A relevant ticket is #22429 Here are also a few other links which are relevant to the issue: Official comment: https://developer.apple.com/forums/thread/719961 More relevant links: https://openradar.appspot.com/radar?id=5536824084660224 https://github.com/python/cpython/issues/97524 Note in release notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-releas e-notes - - - - - 365b3045 by Matthew Pickering at 2023-01-09T02:36:20-05:00 Disable split sections on aarch64-deb10 build See #22722 Failure on this job: https://gitlab.haskell.org/ghc/ghc/-/jobs/1287852 ``` Unexpected failures: /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T10828.run T10828 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T13123.run T13123 [exit code non-0] (ext-interp) /builds/ghc/ghc/tmp/ghctest-s3d8g1hj/test spaces/testsuite/tests/th/T20590.run T20590 [exit code non-0] (ext-interp) Appending 232 stats to file: /builds/ghc/ghc/performance-metrics.tsv ``` ``` Compile failed (exit code 1) errors were: data family D_0 a_1 :: * -> * data instance D_0 GHC.Types.Int GHC.Types.Bool :: * where DInt_2 :: D_0 GHC.Types.Int GHC.Types.Bool data E_3 where MkE_4 :: a_5 -> E_3 data Foo_6 a_7 b_8 where MkFoo_9, MkFoo'_10 :: a_11 -> Foo_6 a_11 b_12 newtype Bar_13 :: * -> GHC.Types.Bool -> * where MkBar_14 :: a_15 -> Bar_13 a_15 b_16 data T10828.T (a_0 :: *) where T10828.MkT :: forall (a_1 :: *) . a_1 -> a_1 -> T10828.T a_1 T10828.MkC :: forall (a_2 :: *) (b_3 :: *) . (GHC.Types.~) a_2 GHC.Types.Int => {T10828.foo :: a_2, T10828.bar :: b_3} -> T10828.T GHC.Types.Int T10828.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: (do TyConI dec <- runQ $ reify (mkName "T") runIO $ putStrLn (pprint dec) >> hFlush stdout d <- runQ $ [d| data T' a :: Type where MkT' :: a -> a -> T' a MkC' :: forall a b. (a ~ Int) => {foo :: a, bar :: b} -> T' Int |] runIO $ putStrLn (pprint d) >> hFlush stdout ....) *** unexpected failure for T10828(ext-interp) =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] =====> 7000 of 9215 [0, 1, 0] Compile failed (exit code 1) errors were: T13123.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data GADT where MkGADT :: forall k proxy (a :: k). proxy a -> GADT |]) *** unexpected failure for T13123(ext-interp) =====> 7100 of 9215 [0, 2, 0] =====> 7100 of 9215 [0, 2, 0] =====> 7200 of 9215 [0, 2, 0] Compile failed (exit code 1) errors were: T20590.hs:1:1: error: [GHC-87897] Exception when trying to run compile-time code: ghc-iserv terminated (-4) Code: ([d| data T where MkT :: forall a. a -> T |]) *** unexpected failure for T20590(ext-interp) ``` Looks fairly worrying to me. - - - - - 965a2735 by Alan Zimmerman at 2023-01-09T02:36:20-05:00 EPA: exact print HsDocTy To match ghc-exactprint https://github.com/alanz/ghc-exactprint/pull/121 - - - - - 5d65773e by John Ericson at 2023-01-09T20:39:27-05:00 Remove RTS hack for configuring See the brand new Note [Undefined symbols in the RTS] for additional details. - - - - - e3fff751 by Sebastian Graf at 2023-01-09T20:40:02-05:00 Handle shadowing in DmdAnal (#22718) Previously, when we had a shadowing situation like ```hs f x = ... -- demand signature <1L><1L> main = ... \f -> f 1 ... ``` we'd happily use the shadowed demand signature at the call site inside the lambda. Of course, that's wrong and solution is simply to remove the demand signature from the `AnalEnv` when we enter the lambda. This patch does so for all binding constructs Core. In #22718 the issue was caused by LetUp not shadowing away the existing demand signature for the let binder in the let body. The resulting absent error is fickle to reproduce; hence no reproduction test case. #17478 would help. Fixes #22718. It appears that TcPlugin_Rewrite regresses by ~40% on Darwin. It is likely that DmdAnal was exploiting ill-scoped analysis results. Metric increase ['bytes allocated'] (test_env=x86_64-darwin-validate): TcPlugin_Rewrite - - - - - d53f6f4d by Oleg Grenrus at 2023-01-09T21:11:02-05:00 Add safe list indexing operator: !? With Joachim's amendments. Implements https://github.com/haskell/core-libraries-committee/issues/110 - - - - - cfaf1ad7 by Nicolas Trangez at 2023-01-09T21:11:03-05:00 rts, tests: limit thread name length to 15 bytes On Linux, `pthread_setname_np` (or rather, the kernel) only allows for thread names up to 16 bytes, including the terminating null byte. This commit adds a note pointing this out in `createOSThread`, and fixes up two instances where a thread name of more than 15 characters long was used (in the RTS, and in a test-case). Fixes: #22366 Fixes: https://gitlab.haskell.org/ghc/ghc/-/issues/22366 See: https://gitlab.haskell.org/ghc/ghc/-/issues/22366#note_460796 - - - - - 64286132 by Matthew Pickering at 2023-01-09T21:11:03-05:00 Store bootstrap_llvm_target and use it to set LlvmTarget in bindists This mirrors some existing logic for the bootstrap_target which influences how TargetPlatform is set. As described on #21970 not storing this led to `LlvmTarget` being set incorrectly and hence the wrong `--target` flag being passed to the C compiler. Towards #21970 - - - - - 4724e8d1 by Matthew Pickering at 2023-01-09T21:11:04-05:00 Check for FP_LD_NO_FIXUP_CHAINS in installation configure script Otherwise, when installing from a bindist the C flag isn't passed to the C compiler. This completes the fix for #22429 - - - - - 2e926b88 by Georgi Lyubenov at 2023-01-09T21:11:07-05:00 Fix outdated link to Happy section on sequences - - - - - 146a1458 by Matthew Pickering at 2023-01-09T21:11:07-05:00 Revert "NCG(x86): Compile add+shift as lea if possible." This reverts commit 20457d775885d6c3df020d204da9a7acfb3c2e5a. See #22666 and #21777 - - - - - 6e6adbe3 by Jade Lovelace at 2023-01-11T00:55:30-05:00 Fix tcPluginRewrite example - - - - - faa57138 by Jade Lovelace at 2023-01-11T00:55:31-05:00 fix missing haddock pipe - - - - - 0470ea7c by Florian Weimer at 2023-01-11T00:56:10-05:00 m4/fp_leading_underscore.m4: Avoid implicit exit function declaration And switch to a new-style function definition. Fixes build issues with compilers that do not accept implicit function declarations. - - - - - b2857df4 by HaskellMouse at 2023-01-11T00:56:52-05:00 Added a new warning about compatibility with RequiredTypeArguments This commit introduces a new warning that indicates code incompatible with future extension: RequiredTypeArguments. Enabling this extension may break some code and the warning will help to make it compatible in advance. - - - - - 5f17e21a by Ben Gamari at 2023-01-11T00:57:27-05:00 testsuite: Drop testheapalloced.c As noted in #22414, this file (which appears to be a benchmark for characterising the one-step allocator's MBlock cache) is currently unreferenced. Remove it. Closes #22414. - - - - - bc125775 by Vladislav Zavialov at 2023-01-11T00:58:03-05:00 Introduce the TypeAbstractions language flag GHC Proposals #448 "Modern scoped type variables" and #425 "Invisible binders in type declarations" introduce a new language extension flag: TypeAbstractions. Part of the functionality guarded by this flag has already been implemented, namely type abstractions in constructor patterns, but it was guarded by a combination of TypeApplications and ScopedTypeVariables instead of a dedicated language extension flag. This patch does the following: * introduces a new language extension flag TypeAbstractions * requires TypeAbstractions for @a-syntax in constructor patterns instead of TypeApplications and ScopedTypeVariables * creates a User's Guide page for TypeAbstractions and moves the "Type Applications in Patterns" section there To avoid a breaking change, the new flag is implied by ScopedTypeVariables and is retroactively added to GHC2021. Metric Decrease: MultiLayerModulesTH_OneShot - - - - - 083f7015 by Krzysztof Gogolewski at 2023-01-11T00:58:38-05:00 Misc cleanup - Remove unused mkWildEvBinder - Use typeTypeOrConstraint - more symmetric and asserts that that the type is Type or Constraint - Fix escape sequences in Python; they raise a deprecation warning with -Wdefault - - - - - aed1974e by Richard Eisenberg at 2023-01-11T08:30:42+00:00 Refactor the treatment of loopy superclass dicts This patch completely re-engineers how we deal with loopy superclass dictionaries in instance declarations. It fixes #20666 and #19690 The highlights are * Recognise that the loopy-superclass business should use precisely the Paterson conditions. This is much much nicer. See Note [Recursive superclasses] in GHC.Tc.TyCl.Instance * With that in mind, define "Paterson-smaller" in Note [Paterson conditions] in GHC.Tc.Validity, and the new data type `PatersonSize` in GHC.Tc.Utils.TcType, along with functions to compute and compare PatsonSizes * Use the new PatersonSize stuff when solving superclass constraints See Note [Solving superclass constraints] in GHC.Tc.TyCl.Instance * In GHC.Tc.Solver.Monad.lookupInInerts, add a missing call to prohibitedSuperClassSolve. This was the original cause of #20666. * Treat (TypeError "stuff") as having PatersonSize zero. See Note [Paterson size for type family applications] in GHC.Tc.Utils.TcType. * Treat the head of a Wanted quantified constraint in the same way as the superclass of an instance decl; this is what fixes #19690. See GHC.Tc.Solver.Canonical Note [Solving a Wanted forall-constraint] (Thanks to Matthew Craven for this insight.) This entailed refactoring the GivenSc constructor of CtOrigin a bit, to say whether it comes from an instance decl or quantified constraint. * Some refactoring way in which redundant constraints are reported; we don't want to complain about the extra, apparently-redundant constraints that we must add to an instance decl because of the loopy-superclass thing. I moved some work from GHC.Tc.Errors to GHC.Tc.Solver. * Add a new section to the user manual to describe the loopy superclass issue and what rules it follows. - - - - - 300bcc15 by HaskellMouse at 2023-01-11T13:43:36-05:00 Parse qualified terms in type signatures This commit allows qualified terms in type signatures to pass the parser and to be cathced by renamer with more informative error message. Adds a few tests. Fixes #21605 - - - - - 964284fc by Simon Peyton Jones at 2023-01-11T13:44:12-05:00 Fix void-arg-adding mechanism for worker/wrapper As #22725 shows, in worker/wrapper we must add the void argument /last/, not first. See GHC.Core.Opt.WorkWrap.Utils Note [Worker/wrapper needs to add void arg last]. That led me to to study GHC.Core.Opt.SpecConstr Note [SpecConstr needs to add void args first] which suggests the opposite! And indeed I think it's the other way round for SpecConstr -- or more precisely the void arg must precede the "extra_bndrs". That led me to some refactoring of GHC.Core.Opt.SpecConstr.calcSpecInfo. - - - - - f7ceafc9 by Krzysztof Gogolewski at 2023-01-11T22:36:59-05:00 Add 'docWithStyle' to improve codegen This new combinator docWithStyle :: IsOutput doc => doc -> (PprStyle -> SDoc) -> doc let us remove the need for code to be polymorphic in HDoc when not used in code style. Metric Decrease: ManyConstructors T13035 T1969 - - - - - b3be0d18 by Simon Peyton Jones at 2023-01-11T22:37:35-05:00 Fix finaliseArgBoxities for OPAQUE function We never do worker wrapper for OPAQUE functions, so we must zap the unboxing info during strictness analysis. This patch fixes #22502 - - - - - db11f358 by Ben Gamari at 2023-01-12T07:49:04-05:00 Revert "rts: Drop racy assertion" The logic here was inverted. Reverting the commit to avoid confusion when examining the commit history. This reverts commit b3eacd64fb36724ed6c5d2d24a81211a161abef1. - - - - - 3242139f by Ben Gamari at 2023-01-12T07:49:04-05:00 rts: Drop racy assertion 0e274c39bf836d5bb846f5fa08649c75f85326ac added an assertion in `dirty_MUT_VAR` checking that the MUT_VAR being dirtied was clean. However, this isn't necessarily the case since another thread may have raced us to dirty the object. - - - - - 9ffd5d57 by Ben Gamari at 2023-01-12T07:49:41-05:00 configure: Fix escaping of `$tooldir` In !9547 I introduced `$tooldir` directories into GHC's default link and compilation flags to ensure that our C toolchain finds its own headers and libraries before others on the system. However, the patch was subtly wrong in the escaping of `$tooldir`. Fix this. Fixes #22561. - - - - - 905d0b6e by Sebastian Graf at 2023-01-12T15:51:47-05:00 Fix contification with stable unfoldings (#22428) Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with a `JoinArity` that reflects the number of join point binders around the body for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by `occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`. I adjusted `Note [Join points and unfoldings/rules]` and `Note [Adjusting right-hand sides]` to account for the new machinery. I also wrote a new `Note [Join arity prediction based on joinRhsArity]` and refer to it when we combine `TailUsageDetails` for a recursive RHS. I also renamed * `occAnalLam` to `occAnalLamTail` * `adjustRhsUsage` to `adjustTailUsage` * a few other less important functions and properly documented the that each call of `occAnalLamTail` must pair up with `adjustTailUsage`. I removed `Note [Unfoldings and join points]` because it was redundant with `Note [Occurrences in stable unfoldings]`. While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed `NodeDetails` called `SimpleNodeDetails`. Fixes #22428. The refactoring seems to have quite beneficial effect on ghc/alloc performance: ``` CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2% T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6% T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2% T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0% T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5% T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6% T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9% T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD geo. mean -0.6% minimum -2.4% maximum -0.0% ``` Metric Decrease: CoOpt_Read T10421 T12150 T12425 T13056 T18698a T18698b T21839c T21839r T9961 - - - - - a1491c87 by Andreas Klebinger at 2023-01-12T15:52:23-05:00 Only gc sparks locally when we can ensure marking is done. When performing GC without work stealing there was no guarantee that spark pruning was happening after marking of the sparks. This could cause us to GC live sparks under certain circumstances. Fixes #22528. - - - - - 8acfe930 by Cheng Shao at 2023-01-12T15:53:00-05:00 Change MSYSTEM to CLANG64 uniformly - - - - - 73bc162b by M Farkas-Dyck at 2023-01-12T15:53:42-05:00 Make `GHC.Tc.Errors.Reporter` take `NonEmpty ErrorItem` rather than `[ErrorItem]`, which lets us drop some panics. Also use the `BasicMismatch` constructor rather than `mkBasicMismatchMsg`, which lets us drop the "-Wno-incomplete-record-updates" flag. - - - - - 1b812b69 by Oleg Grenrus at 2023-01-12T15:54:21-05:00 Fix #22728: Not all diagnostics in safe check are fatal Also add tests for the issue and -Winferred-safe-imports in general - - - - - c79b2b65 by Matthew Pickering at 2023-01-12T15:54:58-05:00 Don't run hadrian-multi on fast-ci label Fixes #22667 - - - - - 9a3d6add by Bodigrim at 2023-01-13T00:46:36-05:00 Bump submodule bytestring to 0.11.4.0 Metric Decrease: T21839c T21839r - - - - - df33c13c by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Bump Darwin bootstrap toolchain This updates the bootstrap compiler on Darwin from 8.10.7 to 9.2.5, ensuring that we have the fix for #21964. - - - - - 756a66ec by Ben Gamari at 2023-01-13T00:47:12-05:00 gitlab-ci: Pass -w to cabal update Due to cabal#8447, cabal-install 3.8.1.0 requires a compiler to run `cabal update`. - - - - - 1142f858 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump hsc2hs submodule - - - - - d4686729 by Cheng Shao at 2023-01-13T11:04:00+00:00 Bump process submodule - - - - - 84ae6573 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: Bump DOCKER_REV - - - - - d53598c5 by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: enable xz parallel compression for x64 jobs - - - - - d31fcbca by Cheng Shao at 2023-01-13T11:06:58+00:00 ci: use in-image emsdk for js jobs - - - - - 93b9bbc1 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: improve nix-shell for gen_ci.hs and fix some ghc/hlint warnings - Add a ghc environment including prebuilt dependencies to the nix-shell. Get rid of the ad hoc cabal cache and all dependencies are now downloaded from the nixos binary cache. - Make gen_ci.hs a cabal package with HLS integration, to make future hacking of gen_ci.hs easier. - Fix some ghc/hlint warnings after I got HLS to work. - For the lint-ci-config job, do a shallow clone to save a few minutes of unnecessary git checkout time. - - - - - 8acc56c7 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: source the toolchain env file in wasm jobs - - - - - 87194df0 by Cheng Shao at 2023-01-13T11:47:17+00:00 ci: add wasm ci jobs via gen_ci.hs - There is one regular wasm job run in validate pipelines - Additionally, int-native/unreg wasm jobs run in nightly/release pipelines Also, remove the legacy handwritten wasm ci jobs in .gitlab-ci.yml. - - - - - b6eb9bcc by Matthew Pickering at 2023-01-13T11:52:16+00:00 wasm ci: Remove wasm release jobs This removes the wasm release jobs, as we do not yet intend to distribute these binaries. - - - - - 496607fd by Simon Peyton Jones at 2023-01-13T16:52:07-05:00 Add a missing checkEscapingKind Ticket #22743 pointed out that there is a missing check, for type-inferred bindings, that the inferred type doesn't have an escaping kind. The fix is easy. - - - - - 7a9a1042 by Andreas Klebinger at 2023-01-16T20:48:19-05:00 Separate core inlining logic from `Unfolding` type. This seems like a good idea either way, but is mostly motivated by a patch where this avoids a module loop. - - - - - 33b58f77 by sheaf at 2023-01-16T20:48:57-05:00 Hadrian: generalise &%> to avoid warnings This patch introduces a more general version of &%> that works with general traversable shapes, instead of lists. This allows us to pass along the information that the length of the list of filepaths passed to the function exactly matches the length of the input list of filepath patterns, avoiding pattern match warnings. Fixes #22430 - - - - - 8c7a991c by Andreas Klebinger at 2023-01-16T20:49:34-05:00 Add regression test for #22611. A case were a function used to fail to specialize, but now does. - - - - - 6abea760 by Andreas Klebinger at 2023-01-16T20:50:10-05:00 Mark maximumBy/minimumBy as INLINE. The RHS was too large to inline which often prevented the overhead of the Maybe from being optimized away. By marking it as INLINE we can eliminate the overhead of both the maybe and are able to unpack the accumulator when possible. Fixes #22609 - - - - - 99d151bb by Matthew Pickering at 2023-01-16T20:50:50-05:00 ci: Bump CACHE_REV so that ghc-9.6 branch and HEAD have different caches Having the same CACHE_REV on both branches leads to issues where the darwin toolchain is different on ghc-9.6 and HEAD which leads to long darwin build times. In general we should ensure that each branch has a different CACHE_REV. - - - - - 6a5845fb by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in source-tarball job This fixes errors of the form: ``` fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc inferred 9.7.20230113 checking for GHC Git commit id... fatal: detected dubious ownership in repository at '/builds/ghc/ghc' To add an exception for this directory, call: git config --global --add safe.directory /builds/ghc/ghc ``` - - - - - 4afb952c by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't build aarch64-deb10-llvm job on release pipelines Closes #22721 - - - - - 8039feb9 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Change owner of files in test-bootstrap job - - - - - 0b358d0c by Matthew Pickering at 2023-01-16T20:51:25-05:00 rel_eng: Add release engineering scripts into ghc tree It is better to keep these scripts in the tree as they depend on the CI configuration and so on. By keeping them in tree we can keep them up-to-date as the CI config changes and also makes it easier to backport changes to the release script between release branches in future. The final motivation is that it makes generating GHCUp metadata possible. - - - - - 28cb2ed0 by Matthew Pickering at 2023-01-16T20:51:25-05:00 ci: Don't use complicated image or clone in not-interruptible job This job exists only for the meta-reason of not allowing nightly pipelines to be cancelled. It was taking two minutes to run as in order to run "true" we would also clone the whole GHC repo. - - - - - eeea59bb by Matthew Pickering at 2023-01-16T20:51:26-05:00 Add scripts to generate ghcup metadata on nightly and release pipelines 1. A python script in .gitlab/rel_eng/mk-ghcup-metadata which generates suitable metadata for consumption by GHCUp for the relevant pipelines. - The script generates the metadata just as the ghcup maintainers want, without taking into account platform/library combinations. It is updated manually when the mapping changes. - The script downloads the bindists which ghcup wants to distribute, calculates the hash and generates the yaml in the correct structure. - The script is documented in the .gitlab/rel_eng/mk-ghcup-metadata/README.mk file 1a. The script requires us to understand the mapping from platform -> job. To choose the preferred bindist for each platform the .gitlab/gen_ci.hs script is modified to allow outputting a metadata file which answers the question about which job produces the bindist which we want to distribute to users for a specific platform. 2. Pipelines to run on nightly and release jobs to generate metadata - ghcup-metadata-nightly: Generates metadata which points directly to artifacts in the nightly job. - ghcup-metadata-release: Generates metadata suitable for inclusion directly in ghcup by pointing to the downloads folder where the bindist will be uploaded to. 2a. Trigger jobs which test the generated metadata in the downstream `ghccup-ci` repo. See that repo for documentation about what is tested and how but essentially we test in a variety of clean images that ghcup can download and install the bindists we say exist in our metadata. - - - - - 97bd4d8c by Bodigrim at 2023-01-16T20:52:04-05:00 Bump submodule parsec to 3.1.16.1 - - - - - 97ac8230 by Alan Zimmerman at 2023-01-16T20:52:39-05:00 EPA: Add annotation for 'type' in DataDecl Closes #22765 - - - - - dbbab95d by Ben Gamari at 2023-01-17T06:36:06-05:00 compiler: Small optimisation of assertM In #22739 @AndreasK noticed that assertM performed the action to compute the asserted predicate regardless of whether DEBUG is enabled. This is inconsistent with the other assertion operations and general convention. Fix this. Closes #22739. - - - - - fc02f3bb by Viktor Dukhovni at 2023-01-17T06:36:47-05:00 Avoid unnecessary printf warnings in EventLog.c Fixes #22778 - - - - - 003b6d44 by Simon Peyton Jones at 2023-01-17T16:33:05-05:00 Document the semantics of pattern bindings a bit better This MR is in response to the discussion on #22719 - - - - - f4d50baf by Vladislav Zavialov at 2023-01-17T16:33:41-05:00 Hadrian: fix warnings (#22783) This change fixes the following warnings when building Hadrian: src/Hadrian/Expression.hs:38:10: warning: [-Wredundant-constraints] src/Hadrian/Expression.hs:84:13: warning: [-Wtype-equality-requires-operators] src/Hadrian/Expression.hs:84:21: warning: [-Wtype-equality-requires-operators] src/Hadrian/Haskell/Cabal/Parse.hs:67:1: warning: [-Wunused-imports] - - - - - 06036d93 by Sylvain Henry at 2023-01-18T01:55:10-05:00 testsuite: req_smp --> req_target_smp, req_ghc_smp See #22630 and !9552 This commit: - splits req_smp into req_target_smp and req_ghc_smp - changes the testsuite driver to calculate req_ghc_smp - changes a handful of tests to use req_target_smp instead of req_smp - changes a handful of tests to use req_host_smp when needed The problem: - the problem this solves is the ambiguity surrounding req_smp - on master req_smp was used to express the constraint that the program being compiled supports smp _and_ that the host RTS (i.e., the RTS used to compile the program) supported smp. Normally that is fine, but in cross compilation this is not always the case as was discovered in #22630. The solution: - Differentiate the two constraints: - use req_target_smp to say the RTS the compiled program is linked with (and the platform) supports smp - use req_host_smp to say the RTS the host is linked with supports smp WIP: fix req_smp (target vs ghc) add flag to separate bootstrapper split req_smp -> req_target_smp and req_ghc_smp update tests smp flags cleanup and add some docstrings only set ghc_with_smp to bootstrapper on S1 or CC Only set ghc_with_smp to bootstrapperWithSMP of when testing stage 1 and cross compiling test the RTS in config/ghc not hadrian re-add ghc_with_smp fix and align req names fix T11760 to use req_host_smp test the rts directly, avoid python 3.5 limitation test the compiler in a try block align out of tree and in tree withSMP flags mark failing tests as host req smp testsuite: req_host_smp --> req_ghc_smp Fix ghc vs host, fix ghc_with_smp leftover - - - - - ee9b78aa by Krzysztof Gogolewski at 2023-01-18T01:55:45-05:00 Use -Wdefault when running Python testdriver (#22727) - - - - - e9c0537c by Vladislav Zavialov at 2023-01-18T01:56:22-05:00 Enable -Wstar-is-type by default (#22759) Following the plan in GHC Proposal #143 "Remove the * kind syntax", which states: In the next release (or 3 years in), enable -fwarn-star-is-type by default. The "next release" happens to be 9.6.1 I also moved the T21583 test case from should_fail to should_compile, because the only reason it was failing was -Werror=compat in our test suite configuration. - - - - - 4efee43d by Ryan Scott at 2023-01-18T01:56:59-05:00 Add missing parenthesizeHsType in cvtSigTypeKind We need to ensure that the output of `cvtSigTypeKind` is parenthesized (at precedence `sigPrec`) so that any type signatures with an outermost, explicit kind signature can parse correctly. Fixes #22784. - - - - - f891a442 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump ghc-tarballs to fix #22497 It turns out that gmp 6.2.1 uses the platform-reserved `x18` register on AArch64/Darwin. This was fixed in upstream changeset 18164:5f32dbc41afc, which was merged in 2020. Here I backport this patch although I do hope that a new release is forthcoming soon. Bumps gmp-tarballs submodule. Fixes #22497. - - - - - b13c6ea5 by Ben Gamari at 2023-01-18T07:28:00-05:00 Bump gmp-tarballs submodule This backports the upstream fix for CVE-2021-43618, fixing #22789. - - - - - c45a5fff by Cheng Shao at 2023-01-18T07:28:37-05:00 Fix typo in recent darwin tests fix Corrects a typo in !9647. Otherwise T18623 will still fail on darwin and stall other people's work. - - - - - b4c14c4b by Luite Stegeman at 2023-01-18T14:21:42-05:00 Add PrimCallConv support to GHCi This adds support for calling Cmm code from bytecode using the native calling convention, allowing modules that use `foreign import prim` to be loaded and debugged in GHCi. This patch introduces a new `PRIMCALL` bytecode instruction and a helper stack frame `stg_primcall`. The code is based on the existing functionality for dealing with unboxed tuples in bytecode, which has been generalised to handle arbitrary calls. Fixes #22051 - - - - - d0a63ef8 by Adam Gundry at 2023-01-18T14:22:26-05:00 Refactor warning flag parsing to add missing flags This adds `-Werror=<group>` and `-fwarn-<group>` flags for warning groups as well as individual warnings. Previously these were defined on an ad hoc basis so for example we had `-Werror=compat` but not `-Werror=unused-binds`, whereas we had `-fwarn-unused-binds` but not `-fwarn-compat`. Fixes #22182. - - - - - 7ed1b8ef by Adam Gundry at 2023-01-18T14:22:26-05:00 Minor corrections to comments - - - - - 5389681e by Adam Gundry at 2023-01-18T14:22:26-05:00 Revise warnings documentation in user's guide - - - - - ab0d5cda by Adam Gundry at 2023-01-18T14:22:26-05:00 Move documentation of deferred type error flags out of warnings section - - - - - eb5a6b91 by John Ericson at 2023-01-18T22:24:10-05:00 Give the RTS it's own configure script Currently it doesn't do much anything, we are just trying to introduce it without breaking the build. Later, we will move functionality from the top-level configure script over to it. We need to bump Cabal for https://github.com/haskell/cabal/pull/8649; to facilitate and existing hack of skipping some configure checks for the RTS we now need to skip just *part* not *all* of the "post configure" hook, as running the configure script (which we definitely want to do) is also implemented as part of the "post configure" hook. But doing this requires exposing functionality that wasn't exposed before. - - - - - 32ab07bf by Bodigrim at 2023-01-18T22:24:51-05:00 ghc package does not have to depend on terminfo - - - - - 981ff7c4 by Bodigrim at 2023-01-18T22:24:51-05:00 ghc-pkg does not have to depend on terminfo - - - - - f058e367 by Ben Gamari at 2023-01-18T22:25:27-05:00 nativeGen/X86: MFENCE is unnecessary for release semantics In #22764 a user noticed that a program implementing a simple atomic counter via an STRef regressed significantly due to the introduction of necessary atomic operations in the MutVar# primops (#22468). This regression was caused by a bug in the NCG, which emitted an unnecessary MFENCE instruction for a release-ordered atomic write. MFENCE is rather only needed to achieve sequentially consistent ordering. Fixes #22764. - - - - - 154889db by Ryan Scott at 2023-01-18T22:26:03-05:00 Add regression test for #22151 Issue #22151 was coincidentally fixed in commit aed1974e92366ab8e117734f308505684f70cddf (`Refactor the treatment of loopy superclass dicts`). This adds a regression test to ensure that the issue remains fixed. Fixes #22151. - - - - - 14b5982a by Andrei Borzenkov at 2023-01-18T22:26:43-05:00 Fix printing of promoted MkSolo datacon (#22785) Problem: In 2463df2f, the Solo data constructor was renamed to MkSolo, and Solo was turned into a pattern synonym for backwards compatibility. Since pattern synonyms can not be promoted, the old code that pretty-printed promoted single-element tuples started producing ill-typed code: t :: Proxy ('Solo Int) This fails with "Pattern synonym ‘Solo’ used as a type" The solution is to track the distinction between type constructors and data constructors more carefully when printing single-element tuples. - - - - - 1fe806d3 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add hi_core flavour transformer The hi_core flavour transformer enables -fwrite-if-simplified-core for stage1 libraries, which emit core into interface files to make it possible to restart code generation. Building boot libs with it makes it easier to use GHC API to prototype experimental backends that needs core/stg at link time. - - - - - 317cad26 by Cheng Shao at 2023-01-23T04:48:47-05:00 hadrian: add missing docs for recently added flavour transformers - - - - - 658f4446 by Ben Gamari at 2023-01-23T04:49:23-05:00 gitlab-ci: Add Rocky8 jobs Addresses #22268. - - - - - a83ec778 by Vladislav Zavialov at 2023-01-23T04:49:58-05:00 Set "since: 9.8" for TypeAbstractions and -Wterm-variable-capture These flags did not make it into the 9.6 release series, so the "since" annotations must be corrected. - - - - - fec7c2ea by Alan Zimmerman at 2023-01-23T04:50:33-05:00 EPA: Add SourceText to HsOverLabel To be able to capture string literals with possible escape codes as labels. Close #22771 - - - - - 3efd1e99 by Ben Gamari at 2023-01-23T04:51:08-05:00 template-haskell: Bump version to 2.20.0.0 Updates `text` and `exceptions` submodules for bounds bumps. Addresses #22767. - - - - - 0900b584 by Cheng Shao at 2023-01-23T04:51:45-05:00 hadrian: disable alloca for in-tree GMP on wasm32 When building in-tree GMP for wasm32, disable its alloca usage, since it may potentially cause stack overflow (e.g. #22602). - - - - - db0f1bfd by Cheng Shao at 2023-01-23T04:52:21-05:00 Bump process submodule Includes a critical fix for wasm32, see https://github.com/haskell/process/pull/272 for details. Also changes the existing cross test to include process stuff and avoid future regression here. - - - - - 9222b167 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Fix subdir for windows bindist - - - - - 9a9bec57 by Matthew Pickering at 2023-01-23T04:52:57-05:00 ghcup metadata: Remove viPostRemove field from generated metadata This has been removed from the downstream metadata. - - - - - 82884ce0 by Simon Peyton Jones at 2023-01-23T04:53:32-05:00 Fix #22742 runtimeRepLevity_maybe was panicing unnecessarily; and the error printing code made use of the case when it should return Nothing rather than panicing. For some bizarre reason perf/compiler/T21839r shows a 10% bump in runtime peak-megagbytes-used, on a single architecture (alpine). See !9753 for commentary, but I'm going to accept it. Metric Increase: T21839r - - - - - 2c6deb18 by Bryan Richter at 2023-01-23T14:12:22+02:00 codeowners: Add Ben, Matt, and Bryan to CI - - - - - eee3bf05 by Matthew Craven at 2023-01-23T21:46:41-05:00 Do not collect compile-time metrics for T21839r ...the testsuite doesn't handle this properly since it also collects run-time metrics. Compile-time metrics for this test are already tracked via T21839c. Metric Decrease: T21839r - - - - - 1d1dd3fb by Matthew Pickering at 2023-01-24T05:37:52-05:00 Fix recompilation checking for multiple home units The key part of this change is to store a UnitId in the `UsageHomeModule` and `UsageHomeModuleInterface`. * Fine-grained dependency tracking is used if the dependency comes from any home unit. * We actually look up the right module when checking whether we need to recompile in the `UsageHomeModuleInterface` case. These scenarios are both checked by the new tests ( multipleHomeUnits_recomp and multipleHomeUnits_recomp_th ) Fixes #22675 - - - - - 7bfb30f9 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Augment target filepath by working directory when checking if module satisfies target This fixes a spurious warning in -Wmissing-home-modules. This is a simple oversight where when looking for the target in the first place we augment the search by the -working-directory flag but then fail to do so when checking this warning. Fixes #22676 - - - - - 69500dd4 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Use NodeKey rather than ModuleName in pruneCache The `pruneCache` function assumes that the list of `CachedInfo` all have unique `ModuleName`, this is not true: * In normal compilation, the same module name can appear for a file and it's boot file. * In multiple home unit compilation the same ModuleName can appear in different units The fix is to use a `NodeKey` as the actual key for the interfaces which includes `ModuleName`, `IsBoot` and `UnitId`. Fixes #22677 - - - - - 336b2b1c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Recompilation checking: Don't try to find artefacts for Interactive & hs-boot combo In interactive mode we don't produce any linkables for hs-boot files. So we also need to not going looking for them when we check to see if we have all the right objects needed for recompilation. Ticket #22669 - - - - - 6469fea7 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Don't write o-boot files in Interactive mode We should not be producing object files when in interactive mode but we still produced the dummy o-boot files. These never made it into a `Linkable` but then confused the recompilation checker. Fixes #22669 - - - - - 06cc0a95 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Improve driver diagnostic messages by including UnitId in message Currently the driver diagnostics don't give any indication about which unit they correspond to. For example `-Wmissing-home-modules` can fire multiple times for each different home unit and gives no indication about which unit it's actually reporting about. Perhaps a longer term fix is to generalise the providence information away from a SrcSpan so that these kind of whole project errors can be reported with an accurate provenance. For now we can just include the `UnitId` in the error message. Fixes #22678 - - - - - 4fe9eaff by Matthew Pickering at 2023-01-24T05:37:52-05:00 Key ModSummary cache by UnitId as well as FilePath Multiple units can refer to the same files without any problem. Just another assumption which needs to be updated when we may have multiple home units. However, there is the invariant that within each unit each file only maps to one module, so as long as we also key the cache by UnitId then we are all good. This led to some confusing behaviour in GHCi when reloading, multipleHomeUnits_shared distils the essence of what can go wrong. Fixes #22679 - - - - - ada29f5c by Matthew Pickering at 2023-01-24T05:37:52-05:00 Finder: Look in current unit before looking in any home package dependencies In order to preserve existing behaviour it's important to look within the current component before consideirng a module might come from an external component. This already happened by accident in `downsweep`, (because roots are used to repopulated the cache) but in the `Finder` the logic was the wrong way around. Fixes #22680 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp -------------------------p - - - - - be701cc6 by Matthew Pickering at 2023-01-24T05:37:52-05:00 Debug: Print full NodeKey when pretty printing ModuleGraphNode This is helpful when debugging multiple component issues. - - - - - 34d2d463 by Krzysztof Gogolewski at 2023-01-24T05:38:32-05:00 Fix Lint check for duplicate external names Lint was checking for duplicate external names by calling removeDups, which needs a comparison function that is passed to Data.List.sortBy. But the comparison was not a valid ordering - it returned LT if one of the names was not external. For example, the previous implementation won't find a duplicate in [M.x, y, M.x]. Instead, we filter out non-external names before looking for duplicates. - - - - - 1c050ed2 by Matthew Pickering at 2023-01-24T05:39:08-05:00 Add test for T22671 This was fixed by b13c6ea5 Closes #22671 - - - - - 05e6a2d9 by Tom Ellis at 2023-01-24T12:10:52-05:00 Clarify where `f` is defined - - - - - d151546e by Cheng Shao at 2023-01-24T12:11:29-05:00 CmmToC: fix CmmRegOff for 64-bit register on a 32-bit target We used to print the offset value to a platform word sized integer. This is incorrect when the offset is negative (e.g. output of cmm constant folding) and the register is 64-bit but on a 32-bit target, and may lead to incorrect runtime result (e.g. #22607). The fix is simple: just treat it as a proper MO_Add, with the correct width info inferred from the register itself. Metric Increase: T12707 T13379 T4801 T5321FD T5321Fun - - - - - e5383a29 by Wander Hillen at 2023-01-24T20:02:26-05:00 Allow waiting for timerfd to be interrupted during rts shutdown - - - - - 1957eda1 by Ryan Scott at 2023-01-24T20:03:01-05:00 Restore Compose's Read/Show behavior to match Read1/Show1 instances Fixes #22816. - - - - - 30972827 by Matthew Pickering at 2023-01-25T03:54:14-05:00 docs: Update INSTALL.md Removes references to make. Fixes #22480 - - - - - bc038c3b by Cheng Shao at 2023-01-25T03:54:50-05:00 compiler: fix handling of MO_F_Neg in wasm NCG In the wasm NCG, we used to compile MO_F_Neg to 0.0-x. It was an oversight, there actually exists f32.neg/f64.neg opcodes in the wasm spec and those should be used instead! The old behavior almost works, expect when GHC compiles the -0.0 literal, which will incorrectly become 0.0. - - - - - e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: correctly detect AR at-file support Stage0's ar may not support at-files. Take it into account. Found while cross-compiling from Darwin to Windows. - - - - - 48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Hadrian: fix Windows cross-compilation Decision to build either unix or Win32 package must be stage specific for cross-compilation to be supported. - - - - - 288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00 Fix RTS build on Windows This change fixes a cross-compilation issue from ArchLinux to Windows because these symbols weren't found. - - - - - 2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00 configure: support "windows" as an OS - - - - - 13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00 Fix in-scope set in specImports Nothing deep here; I had failed to bring some floated dictionary binders into scope. Exposed by -fspecialise-aggressively Fixes #22715. - - - - - b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00 ci: Disable HLint job due to excessive runtime The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91 Now the CI job will build the stage0 compiler before it generates the necessary RTS headers. We either need to: * Fix the linting rules so they take much less time * Revert the commit * Remove the linting of base from the hlint job * Remove the hlint job This is highest priority as it is affecting all CI pipelines. For now I am just disabling the job because there are many more pressing matters at hand. Ticket #22830 - - - - - 1bd32a35 by Sylvain Henry at 2023-01-26T12:34:21-05:00 Factorize hptModulesBelow Create and use moduleGraphModulesBelow in GHC.Unit.Module.Graph that doesn't need anything from the driver to be used. - - - - - 1262d3f8 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Store dehydrated data structures in CgModBreaks This fixes a tricky leak in GHCi where we were retaining old copies of HscEnvs when reloading. If not all modules were recompiled then these hydrated fields in break points would retain a reference to the old HscEnv which could double memory usage. Fixes #22530 - - - - - e27eb80c by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force more in NFData Name instance Doesn't force the lazy `OccName` field (#19619) which is already known as a really bad source of leaks. When we slam the hammer storing Names on disk (in interface files or the like), all this should be forced as otherwise a `Name` can easily retain an `Id` and hence the entire world. Fixes #22833 - - - - - 3d004d5a by Matthew Pickering at 2023-01-26T12:34:56-05:00 Force OccName in tidyTopName This occname has just been derived from an `Id`, so need to force it promptly so we can release the Id back to the world. Another symptom of the bug caused by #19619 - - - - - f2a0fea0 by Matthew Pickering at 2023-01-26T12:34:56-05:00 Strict fields in ModNodeKey (otherwise retains HomeModInfo) Towards #22530 - - - - - 5640cb1d by Sylvain Henry at 2023-01-26T12:35:36-05:00 Hadrian: fix doc generation Was missing dependencies on files generated by templates (e.g. ghc.cabal) - - - - - 3e827c3f by Richard Eisenberg at 2023-01-26T20:06:53-05:00 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. Close #22519. - - - - - b3ef5c89 by doyougnu at 2023-01-26T20:07:48-05:00 tryFillBuffer: strictify more speculative bangs - - - - - d0d7ba0f by Vladislav Zavialov at 2023-01-26T20:08:25-05:00 base: NoImplicitPrelude in Data.Void and Data.Kind This change removes an unnecessary dependency on Prelude from two modules in the base package. - - - - - fa1db923 by Matthew Pickering at 2023-01-26T20:09:00-05:00 ci: Add ubuntu18_04 nightly and release jobs This adds release jobs for ubuntu18_04 which uses glibc 2.27 which is older than the 2.28 which is used by Rocky8 bindists. Ticket #22268 - - - - - 807310a1 by Matthew Pickering at 2023-01-26T20:09:00-05:00 rel-eng: Add missing rocky8 bindist We intend to release rocky8 bindist so the fetching script needs to know about them. - - - - - c7116b10 by Ben Gamari at 2023-01-26T20:09:35-05:00 base: Make changelog proposal references more consistent Addresses #22773. - - - - - 6932cfc7 by Sylvain Henry at 2023-01-26T20:10:27-05:00 Fix spurious change from !9568 - - - - - e480fbc2 by Ben Gamari at 2023-01-27T05:01:24-05:00 rts: Use C11-compliant static assertion syntax Previously we used `static_assert` which is only available in C23. By contrast, C11 only provides `_Static_assert`. Fixes #22777 - - - - - 2648c09c by Andrei Borzenkov at 2023-01-27T05:02:07-05:00 Replace errors from badOrigBinding with new one (#22839) Problem: in 02279a9c the type-level [] syntax was changed from a built-in name to an alias for the GHC.Types.List constructor. badOrigBinding assumes that if a name is not built-in then it must have come from TH quotation, but this is not necessarily the case with []. The outdated assumption in badOrigBinding leads to incorrect error messages. This code: data [] Fails with "Cannot redefine a Name retrieved by a Template Haskell quote: []" Unfortunately, there is not enough information in RdrName to directly determine if the name was constructed via TH or by the parser, so this patch changes the error message instead. It unifies TcRnIllegalBindingOfBuiltIn and TcRnNameByTemplateHaskellQuote into a new error TcRnBindingOfExistingName and changes its wording to avoid guessing the origin of the name. - - - - - 545bf8cf by Matthew Pickering at 2023-01-27T14:58:53+00:00 Revert "base: NoImplicitPrelude in Data.Void and Data.Kind" Fixes CI errors of the form. ``` ===> Command failed with error code: 1 ghc: panic! (the 'impossible' happened) GHC version 9.7.20230127: lookupGlobal Failed to load interface for ‘GHC.Num.BigNat’ There are files missing in the ‘ghc-bignum’ package, try running 'ghc-pkg check'. Use -v (or `:set -v` in ghci) to see a list of the files searched for. Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:189:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Tc/Utils/Env.hs:154:32 in ghc:GHC.Tc.Utils.Env CallStack (from HasCallStack): panic, called at compiler/GHC/Utils/Error.hs:454:29 in ghc:GHC.Utils.Error Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` This reverts commit d0d7ba0fb053ebe7f919a5932066fbc776301ccd. The module now lacks a dependency on GHC.Num.BigNat which it implicitly depends on. It is causing all CI jobs to fail so we revert without haste whilst the patch can be fixed. Fixes #22848 - - - - - 638277ba by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Detect family instance orphans correctly We were treating a type-family instance as a non-orphan if there was a type constructor on its /right-hand side/ that was local. Boo! Utterly wrong. With this patch, we correctly check the /left-hand side/ instead! Fixes #22717 - - - - - 46a53bb2 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Report family instance orphans correctly This fixes the fact that we were not reporting orphan family instances at all. The fix here is easy, but touches a bit of code. I refactored the code to be much more similar to the way that class instances are done: - Add a fi_orphan field to FamInst, like the is_orphan field in ClsInst - Make newFamInst initialise this field, just like newClsInst - And make newFamInst report a warning for an orphan, just like newClsInst - I moved newFamInst from GHC.Tc.Instance.Family to GHC.Tc.Utils.Instantiate, just like newClsInst. - I added mkLocalFamInst to FamInstEnv, just like mkLocalClsInst in InstEnv - TcRnOrphanInstance and SuggestFixOrphanInstance are now parametrised over class instances vs type/data family instances. Fixes #19773 - - - - - faa300fb by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in STG This patch removes some orphan instances in the STG namespace by introducing the GHC.Stg.Lift.Types module, which allows various type family instances to be moved to GHC.Stg.Syntax, avoiding orphan instances. - - - - - 0f25a13b by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Avoid orphans in the parser This moves Anno instances for PatBuilder from GHC.Parser.PostProcess to GHC.Parser.Types to avoid orphans. - - - - - 15750d33 by Simon Peyton Jones at 2023-01-27T23:54:55-05:00 Accept an orphan declaration (sadly) This accepts the orphan type family instance type instance DsForeignHook = ... in GHC.HsToCore.Types. See Note [The Decoupling Abstract Data Hack] in GHC.Driver.Hooks - - - - - c9967d13 by Zubin Duggal at 2023-01-27T23:55:31-05:00 bindist configure: Fail if find not found (#22691) - - - - - ad8cfed4 by John Ericson at 2023-01-27T23:56:06-05:00 Put hadrian bootstrap plans through `jq` This makes it possible to review changes with conventional diffing tools. - - - - - d0ddc01b by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Introduce threaded2_sanity way Incredibly, we previously did not have a single way which would test the threaded RTS with multiple capabilities and the sanity-checker enabled. - - - - - 38ad8351 by Ben Gamari at 2023-01-27T23:56:42-05:00 rts: Relax Messages assertion `doneWithMsgThrowTo` was previously too strict in asserting that the `Message` is locked. Specifically, it failed to consider that the `Message` may not be locked if we are deleting all threads during RTS shutdown. - - - - - a9fe81af by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Fix race in UnliftedTVar2 Previously UnliftedTVar2 would fail when run with multiple capabilities (and possibly even with one capability) as it would assume that `killThread#` would immediately kill the "increment" thread. Also, refactor the the executable to now succeed with no output and fails with an exit code. - - - - - 8519af60 by Ben Gamari at 2023-01-27T23:56:42-05:00 testsuite: Make listThreads more robust Previously it was sensitive to the labels of threads which it did not create (e.g. the IO manager event loop threads). Fix this. - - - - - 55a81995 by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix non-atomic mutation of enabled_capabilities - - - - - b5c75f1d by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix C++ compilation issues Make the RTS compilable with a C++ compiler by inserting necessary casts. - - - - - c261b62f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Fix typo "tracingAddCapabilities" was mis-named - - - - - 77fdbd3f by Ben Gamari at 2023-01-27T23:56:43-05:00 rts: Drop long-dead fallback definitions for INFINITY & NAN These are no longer necessary since we now compile as C99. - - - - - 56c1bd98 by Ben Gamari at 2023-01-28T02:57:59-05:00 Revert "CApiFFI: add ConstPtr for encoding const-qualified pointer return types (#22043)" This reverts commit 99aca26b652603bc62953157a48e419f737d352d. - - - - - b3a3534b by nineonine at 2023-01-28T02:57:59-05:00 CApiFFI: add ConstPtr for encoding const-qualified pointer return types Previously, when using `capi` calling convention in foreign declarations, code generator failed to handle const-cualified pointer return types. This resulted in CC toolchain throwing `-Wincompatible-pointer-types-discards-qualifiers` warning. `Foreign.C.Types.ConstPtr` newtype was introduced to handle these cases - special treatment was put in place to generate appropritetly qualified C wrapper that no longer triggers the above mentioned warning. Fixes #22043. - - - - - 082b7d43 by Oleg Grenrus at 2023-01-28T02:58:38-05:00 Add Foldable1 Solo instance - - - - - 50b1e2e8 by Andrei Borzenkov at 2023-01-28T02:59:18-05:00 Convert diagnostics in GHC.Rename.Bind to proper TcRnMessage (#20115) I removed all occurrences of TcRnUnknownMessage in GHC.Rename.Bind module. Instead, these TcRnMessage messages were introduced: TcRnMultipleFixityDecls TcRnIllegalPatternSynonymDecl TcRnIllegalClassBiding TcRnOrphanCompletePragma TcRnEmptyCase TcRnNonStdGuards TcRnDuplicateSigDecl TcRnMisplacedSigDecl TcRnUnexpectedDefaultSig TcRnBindInBootFile TcRnDuplicateMinimalSig - - - - - 3330b819 by Matthew Pickering at 2023-01-28T02:59:54-05:00 hadrian: Fix library-dirs, dynamic-library-dirs and static-library-dirs in inplace .conf files Previously we were just throwing away the contents of the library-dirs fields but really we have to do the same thing as for include-dirs, relativise the paths into the current working directory and maintain any extra libraries the user has specified. Now the relevant section of the rts.conf file looks like: ``` library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib library-dirs-static: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib dynamic-library-dirs: ${pkgroot}/../rts/build ${pkgroot}/../../..//_build/stage1/rts/build /nix/store/av4c0fib4rkmb6sa1074z0rb1ciria5b-gperftools-2.10/lib /nix/store/2infxahfp9lj084xn3q9ib5ajks8447i-libffi-3.4.4/lib ``` Fixes #22209 - - - - - c9ad8852 by Bodigrim at 2023-01-28T03:00:33-05:00 Document differences between Data.{Monoid,Semigroup}.{First,Last} - - - - - 7e11c6dc by Cheng Shao at 2023-01-28T03:01:09-05:00 compiler: fix subword literal narrowing logic in the wasm NCG This patch fixes the W8/W16 literal narrowing logic in the wasm NCG, which used to lower it to something like i32.const -1, without properly zeroing-out the unused higher bits. Fixes #22608. - - - - - 6ea2aa02 by Cheng Shao at 2023-01-28T03:01:46-05:00 compiler: fix lowering of CmmBlock in the wasm NCG The CmmBlock datacon was not handled in lower_CmmLit, since I thought it would have been eliminated after proc-point splitting. Turns out it still occurs in very rare occasions, and this patch is needed to fix T9329 for wasm. - - - - - 2b62739d by Bodigrim at 2023-01-28T17:16:11-05:00 Assorted changes to avoid Data.List.{head,tail} - - - - - 78c07219 by Cheng Shao at 2023-01-28T17:16:48-05:00 compiler: properly handle ForeignHints in the wasm NCG Properly handle ForeignHints of ccall arguments/return value, insert sign extends and truncations when handling signed subwords. Fixes #22852. - - - - - 8bed166b by Ben Gamari at 2023-01-30T05:06:26-05:00 nativeGen: Disable asm-shortcutting on Darwin Asm-shortcutting may produce relative references to symbols defined in other compilation units. This is not something that MachO relocations support (see #21972). For this reason we disable the optimisation on Darwin. We do so without a warning since this flag is enabled by `-O2`. Another way to address this issue would be to rather implement a PLT-relocatable jump-table strategy. However, this would only benefit Darwin and does not seem worth the effort. Closes #21972. - - - - - da468391 by Cheng Shao at 2023-01-30T05:07:03-05:00 compiler: fix data section alignment in the wasm NCG Previously we tried to lower the alignment requirement as far as possible, based on the section kind inferred from the CLabel. For info tables, .p2align 1 was applied given the GC should only need the lowest bit to tag forwarding pointers. But this would lead to unaligned loads/stores, which has a performance penalty even if the wasm spec permits it. Furthermore, the test suite has shown memory corruption in a few cases when compacting gc is used. This patch takes a more conservative approach: all data sections except C strings align to word size. - - - - - 08ba8720 by Andreas Klebinger at 2023-01-30T21:18:45-05:00 ghc-the-library: Retain cafs in both static in dynamic builds. We use keepCAFsForGHCi.c to force -fkeep-cafs behaviour by using a __attribute__((constructor)) function. This broke for static builds where the linker discarded the object file since it was not reverenced from any exported code. We fix this by asserting that the flag is enabled using a function in the same module as the constructor. Which causes the object file to be retained by the linker, which in turn causes the constructor the be run in static builds. This changes nothing for dynamic builds using the ghc library. But causes static to also retain CAFs (as we expect them to). Fixes #22417. ------------------------- Metric Decrease: T21839r ------------------------- - - - - - 20598ef6 by Ryan Scott at 2023-01-30T21:19:20-05:00 Handle `type data` properly in tyThingParent_maybe Unlike most other data constructors, data constructors declared with `type data` are represented in `TyThing`s as `ATyCon` rather than `ADataCon`. The `ATyCon` case in `tyThingParent_maybe` previously did not consider the possibility of the underlying `TyCon` being a promoted data constructor, which led to the oddities observed in #22817. This patch adds a dedicated special case in `tyThingParent_maybe`'s `ATyCon` case for `type data` data constructors to fix these oddities. Fixes #22817. - - - - - 2f145052 by Ryan Scott at 2023-01-30T21:19:56-05:00 Fix two bugs in TypeData TH reification This patch fixes two issues in the way that `type data` declarations were reified with Template Haskell: * `type data` data constructors are now properly reified using `DataConI`. This is accomplished with a special case in `reifyTyCon`. Fixes #22818. * `type data` type constructors are now reified in `reifyTyCon` using `TypeDataD` instead of `DataD`. Fixes #22819. - - - - - d0f34f25 by Simon Peyton Jones at 2023-01-30T21:20:35-05:00 Take account of loop breakers in specLookupRule The key change is that in GHC.Core.Opt.Specialise.specLookupRule we were using realIdUnfolding, which ignores the loop-breaker flag. When given a loop breaker, rule matching therefore looped infinitely -- #22802. In fixing this I refactored a bit. * Define GHC.Core.InScopeEnv as a data type, and use it. (Previously it was a pair: hard to grep for.) * Put several functions returning an IdUnfoldingFun into GHC.Types.Id, namely idUnfolding alwaysActiveUnfoldingFun, whenActiveUnfoldingFun, noUnfoldingFun and use them. (The are all loop-breaker aware.) - - - - - de963cb6 by Matthew Pickering at 2023-01-30T21:21:11-05:00 ci: Remove FreeBSD job from release pipelines We no longer attempt to build or distribute this release - - - - - f26d27ec by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Add check to make sure that release jobs are downloaded by fetch-gitlab This check makes sure that if a job is a prefixed by "release-" then the script downloads it and understands how to map the job name to the platform. - - - - - 7619c0b4 by Matthew Pickering at 2023-01-30T21:21:11-05:00 rel_eng: Fix the name of the ubuntu-* jobs These were not uploaded for alpha1 Fixes #22844 - - - - - 68eb8877 by Matthew Pickering at 2023-01-30T21:21:11-05:00 gen_ci: Only consider release jobs for job metadata In particular we do not have a release job for FreeBSD so the generation of the platform mapping was failing. - - - - - b69461a0 by Jason Shipman at 2023-01-30T21:21:50-05:00 User's guide: Clarify overlapping instance candidate elimination This commit updates the user's guide section on overlapping instance candidate elimination to use "or" verbiage instead of "either/or" in regards to the current pair of candidates' being overlappable or overlapping. "Either IX is overlappable, or IY is overlapping" can cause confusion as it suggests "Either IX is overlappable, or IY is overlapping, but not both". This was initially discussed on this Discourse topic: https://discourse.haskell.org/t/clarification-on-overlapping-instance-candidate-elimination/5677 - - - - - 7cbdaad0 by Matthew Pickering at 2023-01-31T07:53:53-05:00 Fixes for cabal-reinstall CI job * Allow filepath to be reinstalled * Bump some version bounds to allow newer versions of libraries * Rework testing logic to avoid "install --lib" and package env files Fixes #22344 - - - - - fd8f32bf by Cheng Shao at 2023-01-31T07:54:29-05:00 rts: prevent potential divide-by-zero when tickInterval=0 This patch fixes a few places in RtsFlags.c that may result in divide-by-zero error when tickInterval=0, which is the default on wasm. Fixes #22603. - - - - - 085a6db6 by Joachim Breitner at 2023-01-31T07:55:05-05:00 Update note at beginning of GHC.Builtin.NAmes some things have been renamed since it was written, it seems. - - - - - 7716cbe6 by Cheng Shao at 2023-01-31T07:55:41-05:00 testsuite: use tgamma for cg007 gamma is a glibc-only deprecated function, use tgamma instead. It's required for fixing cg007 when testing the wasm unregisterised codegen. - - - - - 19c1fbcd by doyougnu at 2023-01-31T13:08:03-05:00 InfoTableProv: ShortText --> ShortByteString - - - - - 765fab98 by doyougnu at 2023-01-31T13:08:03-05:00 FastString: add fastStringToShorText - - - - - a83c810d by Simon Peyton Jones at 2023-01-31T13:08:38-05:00 Improve exprOkForSpeculation for classops This patch fixes #22745 and #15205, which are about GHC's failure to discard unnecessary superclass selections that yield coercions. See GHC.Core.Utils Note [exprOkForSpeculation and type classes] The main changes are: * Write new Note [NON-BOTTOM_DICTS invariant] in GHC.Core, and refer to it * Define new function isTerminatingType, to identify those guaranteed-terminating dictionary types. * exprOkForSpeculation has a new (very simple) case for ClassOpId * ClassOpId has a new field that says if the return type is an unlifted type, or a terminating type. This was surprisingly tricky to get right. In particular note that unlifted types are not terminating types; you can write an expression of unlifted type, that diverges. Not so for dictionaries (or, more precisely, for the dictionaries that GHC constructs). Metric Decrease: LargeRecord - - - - - f83374f8 by Krzysztof Gogolewski at 2023-01-31T13:09:14-05:00 Support "unusable UNPACK pragma" warning with -O0 Fixes #11270 - - - - - a2d814dc by Ben Gamari at 2023-01-31T13:09:50-05:00 configure: Always create the VERSION file Teach the `configure` script to create the `VERSION` file. This will serve as the stable interface to allow the user to determine the version number of a working tree. Fixes #22322. - - - - - 5618fc21 by sheaf at 2023-01-31T15:51:06-05:00 Cmm: track the type of global registers This patch tracks the type of Cmm global registers. This is needed in order to lint uses of polymorphic registers, such as SIMD vector registers that can be used both for floating-point and integer values. This changes allows us to refactor VanillaReg to not store VGcPtr, as that information is instead stored in the type of the usage of the register. Fixes #22297 - - - - - 78b99430 by sheaf at 2023-01-31T15:51:06-05:00 Revert "Cmm Lint: relax SIMD register assignment check" This reverts commit 3be48877, which weakened a Cmm Lint check involving SIMD vectors. Now that we keep track of the type a global register is used at, we can restore the original stronger check. - - - - - be417a47 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix debugging output Previously various panics would rely on a half-written Show instance, leading to very unhelpful errors. Fix this. See #22798. - - - - - 30989d13 by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen: Teach graph-colouring allocator that x18 is unusable Previously trivColourable for AArch64 claimed that at 18 registers were trivially-colourable. This is incorrect as x18 is reserved by the platform on AArch64/Darwin. See #22798. - - - - - 7566fd9d by Ben Gamari at 2023-01-31T15:51:45-05:00 nativeGen/AArch64: Fix graph-colouring allocator Previously various `Instr` queries used by the graph-colouring allocator failed to handle a few pseudo-instructions. This manifested in compiler panicks while compiling `SHA`, which uses `-fregs-graph`. Fixes #22798. - - - - - 2cb500a5 by Ben Gamari at 2023-01-31T15:51:45-05:00 testsuite: Add regression test for #22798 - - - - - 03d693b2 by Ben Gamari at 2023-01-31T15:52:32-05:00 Revert "Hadrian: fix doc generation" This is too large of a hammer. This reverts commit 5640cb1d84d3cce4ce0a9e90d29b2b20d2b38c2f. - - - - - f838815c by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Sphinx docs require templated cabal files The package-version discovery logic in `doc/users_guide/package_versions.py` uses packages' cabal files to determine package versions. Teach Sphinx about these dependencies in cases where the cabal files are generated by templates. - - - - - 2e48c19a by Ben Gamari at 2023-01-31T15:52:32-05:00 hadrian: Refactor templating logic This refactors Hadrian's autoconf-style templating logic to be explicit about which interpolation variables should be substituted in which files. This clears the way to fix #22714 without incurring rule cycles. - - - - - 93f0e3c4 by Ben Gamari at 2023-01-31T15:52:33-05:00 hadrian: Substitute LIBRARY_*_VERSION variables This teaches Hadrian to substitute the `LIBRARY_*_VERSION` variables in `libraries/prologue.txt`, fixing #22714. Fixes #22714. - - - - - 22089f69 by Ben Gamari at 2023-01-31T20:46:27-05:00 Bump transformers submodule to 0.6.0.6 Fixes #22862. - - - - - f0eefa3c by Cheng Shao at 2023-01-31T20:47:03-05:00 compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCG Currently, the wasm NCG has an implicit assumption: all CmmSwitch scrutinees are 32-bit integers. This is not always true; #22864 is one counter-example with a 64-bit scrutinee. This patch fixes the logic by explicitly converting the scrutinee to a word that can be used as a br_table operand. Fixes #22871. Also includes a regression test. - - - - - 9f95db54 by Simon Peyton Jones at 2023-02-01T08:55:08+00:00 Improve treatment of type applications in patterns This patch fixes a subtle bug in the typechecking of type applications in patterns, e.g. f (MkT @Int @a x y) = ... See Note [Type applications in patterns] in GHC.Tc.Gen.Pat. This fixes #19847, #22383, #19577, #21501 - - - - - 955a99ea by Simon Peyton Jones at 2023-02-01T12:31:23-05:00 Treat existentials correctly in dubiousDataConInstArgTys Consider (#22849) data T a where MkT :: forall k (t::k->*) (ix::k). t ix -> T @k a Then dubiousDataConInstArgTys MkT [Type, Foo] should return [Foo (ix::Type)] NOT [Foo (ix::k)] A bit of an obscure case, but it's an outright bug, and the fix is easy. - - - - - 0cc16aaf by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump supported LLVM range from 10 through 15 to 11 through 16 LLVM 15 turns on the new pass manager by default, which we have yet to migrate to so for new we pass the `-enable-new-pm-0` flag in our llvm-passes flag. LLVM 11 was the first version to support the `-enable-new-pm` flag so we bump the lowest supported version to 11. Our CI jobs are using LLVM 12 so they should continue to work despite this bump to the lower bound. Fixes #21936 - - - - - f94f1450 by Matthew Pickering at 2023-02-01T12:31:58-05:00 Bump DOCKER_REV to use alpine image without LLVM installed alpine_3_12 only supports LLVM 10, which is now outside the supported version range. - - - - - 083e26ed by Matthew Pickering at 2023-02-01T17:43:21-05:00 Remove tracing OPTIONS_GHC These were accidentally left over from !9542 - - - - - 354aa47d by Teo Camarasu at 2023-02-01T17:44:00-05:00 doc: fix gcdetails_block_fragmentation_bytes since annotation - - - - - 61ce5bf6 by Jaro Reinders at 2023-02-02T00:15:30-05:00 compiler: Implement higher order patterns in the rule matcher This implements proposal 555 and closes ticket #22465. See the proposal and ticket for motivation. The core changes of this patch are in the GHC.Core.Rules.match function and they are explained in the Note [Matching higher order patterns]. - - - - - 394b91ce by doyougnu at 2023-02-02T00:16:10-05:00 CI: JavaScript backend runs testsuite This MR runs the testsuite for the JS backend. Note that this is a temporary solution until !9515 is merged. Key point: The CI runs hadrian on the built cross compiler _but not_ on the bindist. Other Highlights: - stm submodule gets a bump to mark tests as broken - several tests are marked as broken or are fixed by adding more - conditions to their test runner instance. List of working commit messages: CI: test cross target _and_ emulator CI: JS: Try run testsuite with hadrian JS.CI: cleanup and simplify hadrian invocation use single bracket, print info JS CI: remove call to test_compiler from hadrian don't build haddock JS: mark more tests as broken Tracked in https://gitlab.haskell.org/ghc/ghc/-/issues/22576 JS testsuite: don't skip sum_mod test Its expected to fail, yet we skipped it which automatically makes it succeed leading to an unexpected success, JS testsuite: don't mark T12035j as skip leads to an unexpected pass JS testsuite: remove broken on T14075 leads to unexpected pass JS testsuite: mark more tests as broken JS testsuite: mark T11760 in base as broken JS testsuite: mark ManyUnbSums broken submodules: bump process and hpc for JS tests Both submodules has needed tests skipped or marked broken for th JS backend. This commit now adds these changes to GHC. See: HPC: https://gitlab.haskell.org/hpc/hpc/-/merge_requests/21 Process: https://github.com/haskell/process/pull/268 remove js_broken on now passing tests separate wasm and js backend ci test: T11760: add threaded, non-moving only_ways test: T10296a add req_c T13894: skip for JS backend tests: jspace, T22333: mark as js_broken(22573) test: T22513i mark as req_th stm submodule: mark stm055, T16707 broken for JS tests: js_broken(22374) on unpack_sums_6, T12010 dont run diff on JS CI, cleanup fixup: More CI cleanup fix: align text to master fix: align exceptions submodule to master CI: Bump DOCKER_REV Bump to ci-images commit that has a deb11 build with node. Required for !9552 testsuite: mark T22669 as js_skip See #22669 This test tests that .o-boot files aren't created when run in using the interpreter backend. Thus this is not relevant for the JS backend. testsuite: mark T22671 as broken on JS See #22835 base.testsuite: mark Chan002 fragile for JS see #22836 revert: submodule process bump bump stm submodule New hash includes skips for the JS backend. testsuite: mark RnPatternSynonymFail broken on JS Requires TH: - see !9779 - and #22261 compiler: GHC.hs ifdef import Utils.Panic.Plain - - - - - 1ffe770c by Cheng Shao at 2023-02-02T09:40:38+00:00 docs: 9.6 release notes for wasm backend - - - - - 0ada4547 by Matthew Pickering at 2023-02-02T11:39:44-05:00 Disable unfolding sharing for interface files with core definitions Ticket #22807 pointed out that the RHS sharing was not compatible with -fignore-interface-pragmas because the flag would remove unfoldings from identifiers before the `extra-decls` field was populated. For the 9.6 timescale the only solution is to disable this sharing, which will make interface files bigger but this is acceptable for the first release of `-fwrite-if-simplified-core`. For 9.8 it would be good to fix this by implementing #20056 due to the large number of other bugs that would fix. I also improved the error message in tc_iface_binding to avoid the "no match in record selector" error but it should never happen now as the entire sharing logic is disabled. Also added the currently broken test for #22807 which could be fixed by !6080 Fixes #22807 - - - - - 7e2d3eb5 by lrzlin at 2023-02-03T05:23:27-05:00 Enable tables next to code for LoongArch64 - - - - - 2931712a by Wander Hillen at 2023-02-03T05:24:06-05:00 Move pthread and timerfd ticker implementations to separate files - - - - - 41c4baf8 by Ben Gamari at 2023-02-03T05:24:44-05:00 base: Fix Note references in GHC.IO.Handle.Types - - - - - 31358198 by Bodigrim at 2023-02-03T05:25:22-05:00 Bump submodule containers to 0.6.7 Metric Decrease: ManyConstructors T10421 T12425 T12707 T13035 T13379 T15164 T1969 T783 T9198 T9961 WWRec - - - - - 8feb9301 by Ben Gamari at 2023-02-03T05:25:59-05:00 gitlab-ci: Eliminate redundant ghc --info output Previously ci.sh would emit the output of `ghc --info` every time it ran when using the nix toolchain. This produced a significant amount of noise. See #22861. - - - - - de1d1512 by Ryan Scott at 2023-02-03T14:07:30-05:00 Windows: Remove mingwex dependency The clang based toolchain uses ucrt as its math library and so mingwex is no longer needed. In fact using mingwex will cause incompatibilities as the default routines in both have differing ULPs and string formatting modifiers. ``` $ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe [1 of 2] Compiling Main ( Bug.hs, Bug.o ) ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info' ghc.exe: | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info' ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above. <no location info>: error: GHC.ByteCode.Linker.lookupCE During interactive linking, GHCi couldn't find the following symbol: templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` - - - - - 48e39195 by Tamar Christina at 2023-02-03T14:07:30-05:00 linker: Fix BFD import libraries This commit fixes the BFD style import library support in the runtime linker. This was accidentally broken during the refactoring to clang and went unnoticed because clang itself is unable to generate the BFD style import libraries. With this change we can not link against both GCC or Clang produced libraries again and intermix code produced by both compilers. - - - - - b2bb3e62 by Ben Gamari at 2023-02-03T14:07:30-05:00 Bump Windows toolchain Updates to LLVM 14, hopefully fixing #21964. - - - - - bf3f88a1 by Andreas Klebinger at 2023-02-03T14:08:07-05:00 Fix CallerCC potentially shadowing other cost centres. Add a CallerCC cost centre flavour for cost centres added by the CallerCC pass. This avoids potential accidental shadowing between CCs added by user annotations and ones added by CallerCC. - - - - - faea4bcd by j at 2023-02-03T14:08:47-05:00 Disable several ignore-warning flags in genapply. - - - - - 25537dfd by Ben Gamari at 2023-02-04T04:12:57-05:00 Revert "Use fix-sized bit-fiddling primops for fixed size boxed types" This reverts commit 4512ad2d6a8e65ea43c86c816411cb13b822f674. This was never applied to master/9.6 originally. (cherry picked from commit a44bdc2720015c03d57f470b759ece7fab29a57a) - - - - - 7612dc71 by Krzysztof Gogolewski at 2023-02-04T04:13:34-05:00 Minor refactor * Introduce refactorDupsOn f = refactorDups (comparing f) * Make mkBigTupleCase and coreCaseTuple monadic. Every call to those functions was preceded by calling newUniqueSupply. * Use mkUserLocalOrCoVar, which is equivalent to combining mkLocalIdOrCoVar with mkInternalName. - - - - - 5a54ac0b by Bodigrim at 2023-02-04T18:48:32-05:00 Fix colors in emacs terminal - - - - - 3c0f0c6d by Bodigrim at 2023-02-04T18:49:11-05:00 base changelog: move entries which were not backported to ghc-9.6 to base-4.19 section - - - - - b18fbf52 by Josh Meredith at 2023-02-06T07:47:57+00:00 Update JavaScript fileStat to match Emscripten layout - - - - - 6636b670 by Sylvain Henry at 2023-02-06T09:43:21-05:00 JS: replace "js" architecture with "javascript" Despite Cabal supporting any architecture name, `cabal --check` only supports a few built-in ones. Sadly `cabal --check` is used by Hackage hence using any non built-in name in a package (e.g. `arch(js)`) is rejected and the package is prevented from being uploaded on Hackage. Luckily built-in support for the `javascript` architecture was added for GHCJS a while ago. In order to allow newer `base` to be uploaded on Hackage we make the switch from `js` to `javascript` architecture. Fixes #22740. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 77a8234c by Luite Stegeman at 2023-02-06T09:43:59-05:00 Fix marking async exceptions in the JS backend Async exceptions are posted as a pair of the exception and the thread object. This fixes the marking pass to correctly follow the two elements of the pair. Potentially fixes #22836 - - - - - 3e09cf82 by Jan Hrček at 2023-02-06T09:44:38-05:00 Remove extraneous word in Roles user guide - - - - - b17fb3d9 by sheaf at 2023-02-07T10:51:33-05:00 Don't allow . in overloaded labels This patch removes . from the list of allowed characters in a non-quoted overloaded label, as it was realised this steals syntax, e.g. (#.). Users who want this functionality will have to add quotes around the label, e.g. `#"17.28"`. Fixes #22821 - - - - - 5dce04ee by romes at 2023-02-07T10:52:10-05:00 Update kinds in comments in GHC.Core.TyCon Use `Type` instead of star kind (*) Fix comment with incorrect kind * to have kind `Constraint` - - - - - 92916194 by Ben Gamari at 2023-02-07T10:52:48-05:00 Revert "Use fix-sized equality primops for fixed size boxed types" This reverts commit 024020c38126f3ce326ff56906d53525bc71690c. This was never applied to master/9.6 originally. See #20405 for why using these primops is a bad idea. (cherry picked from commit b1d109ad542e4c37ae5af6ace71baf2cb509d865) - - - - - c1670c6b by Sylvain Henry at 2023-02-07T21:25:18-05:00 JS: avoid head/tail and unpackFS - - - - - a9912de7 by Krzysztof Gogolewski at 2023-02-07T21:25:53-05:00 testsuite: Fix Python warnings (#22856) - - - - - 9ee761bf by sheaf at 2023-02-08T14:40:40-05:00 Fix tyvar scoping within class SPECIALISE pragmas Type variables from class/instance headers scope over class/instance method type signatures, but DO NOT scope over the type signatures in SPECIALISE and SPECIALISE instance pragmas. The logic in GHC.Rename.Bind.rnMethodBinds correctly accounted for SPECIALISE inline pragmas, but forgot to apply the same treatment to method SPECIALISE pragmas, which lead to a Core Lint failure with an out-of-scope type variable. This patch makes sure we apply the same logic for both cases. Fixes #22913 - - - - - 7eac2468 by Matthew Pickering at 2023-02-08T14:41:17-05:00 Revert "Don't keep exit join points so much" This reverts commit caced75765472a1a94453f2e5a439dba0d04a265. It seems the patch "Don't keep exit join points so much" is causing wide-spread regressions in the bytestring library benchmarks. If I revert it then the 9.6 numbers are better on average than 9.4. See https://gitlab.haskell.org/ghc/ghc/-/issues/22893#note_479525 ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp MultiLayerModules MultiLayerModulesRecomp MultiLayerModulesTH_Make T12150 T13386 T13719 T21839c T3294 parsing001 ------------------------- - - - - - 633f2799 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: remove config.use_threads This patch simplifies the testsuite driver by removing the use_threads config field. It's just a degenerate case of threads=1. - - - - - ca6673e3 by Cheng Shao at 2023-02-08T18:42:16-05:00 testsuite: use concurrent.futures.ThreadPoolExecutor in the driver The testsuite driver used to create one thread per test case, and explicitly use semaphore and locks for rate limiting and synchronization. This is a bad practice in any language, and occasionally may result in livelock conditions (e.g. #22889). This patch uses concurrent.futures.ThreadPoolExecutor for scheduling test case runs, which is simpler and more robust. - - - - - f22cce70 by Alan Zimmerman at 2023-02-08T18:42:51-05:00 EPA: Comment between module and where should be in header comments Do not apply the heuristic to associate a comment with a prior declaration for the first declaration in the file. Closes #22919 - - - - - d69ecac2 by Josh Meredith at 2023-02-09T03:24:05-05:00 JS generated refs: update testsuite conditions - - - - - 2ea1a6bc by sheaf at 2023-02-09T03:24:44-05:00 Bump transformers to 0.6.1.0 This allows us to avoid orphans for Foldable1 instances, fixing #22898. Updates transformers submodule. - - - - - d9d0c28d by konsumlamm at 2023-02-09T14:07:48-05:00 Update `Data.List.singleton` doc comment - - - - - fe9cd6ef by Ben Gamari at 2023-02-09T14:08:23-05:00 gitlab-template: Emphasize `user facing` label My sense is that the current mention of the ~"user facing" label is overlooked by many MR authors. Let's move this point up in the list to make it more likely that it is seen. Also rephrase some of the points. - - - - - e45eb828 by Simon Peyton Jones at 2023-02-10T06:51:28-05:00 Refactor the simplifier a bit to fix #22761 The core change in this commit, which fixes #22761, is that * In a Core rule, ru_rhs is always occ-analysed. This means adding a couple of calls to occurAnalyseExpr when building a Rule, in * GHC.Core.Rules.mkRule * GHC.Core.Opt.Simplify.Iteration.simplRules But diagosing the bug made me stare carefully at the code of the Simplifier, and I ended up doing some only-loosely-related refactoring. * I think that RULES could be lost because not every code path did addBndrRules * The code around lambdas was very convoluted It's mainly moving deck chairs around, but I like it more now. - - - - - 11e0cacb by Rebecca Turner at 2023-02-10T06:52:09-05:00 Detect the `mold` linker Enables support for the `mold` linker by rui314. - - - - - 59556235 by parsonsmatt at 2023-02-10T09:53:11-05:00 Add Lift instance for Fixed - - - - - c44e5f30 by Sylvain Henry at 2023-02-10T09:53:51-05:00 Testsuite: decrease length001 timeout for JS (#22921) - - - - - 133516af by Zubin Duggal at 2023-02-10T09:54:27-05:00 compiler: Use NamedFieldPuns for `ModIface_` and `ModIfaceBackend` `NFData` instances This is a minor refactor that makes it easy to add and remove fields from `ModIface_` and `ModIfaceBackend`. Also change the formatting to make it clear exactly which fields are fully forced with `rnf` - - - - - 1e9eac1c by Matthew Pickering at 2023-02-13T11:36:41+01:00 Refresh profiling docs I went through the whole of the profiling docs and tried to amend them to reflect current best practices and tooling. In particular I removed some old references to tools such as hp2any and replaced them with references to eventlog2html. - - - - - da208b9a by Matthew Pickering at 2023-02-13T11:36:41+01:00 docs: Add section about profiling and foreign calls Previously there was no documentation for how foreign calls interacted with the profiler. This can be quite confusing for users so getting it into the user guide is the first step to a potentially better solution. See the ticket for more insightful discussion. Fixes #21764 - - - - - 081640f1 by Bodigrim at 2023-02-13T12:51:52-05:00 Document that -fproc-alignment was introduced only in GHC 8.6 - - - - - 16adc349 by Sven Tennie at 2023-02-14T11:26:31-05:00 Add clangd flag to include generated header files This enables clangd to correctly check C files that import Rts.h. (The added include directory contains ghcautoconf.h et. al.) - - - - - c399ccd9 by amesgen at 2023-02-14T11:27:14-05:00 Mention new `Foreign.Marshal.Pool` implementation in User's Guide - - - - - b9282cf7 by Ben Gamari at 2023-02-14T11:27:50-05:00 upload_ghc_libs: More control over which packages to operate on Here we add a `--skip` flag to `upload_ghc_libs`, making it easier to limit which packages to upload. This is often necessary when one package is not uploadable (e.g. see #22740). - - - - - aa3a262d by PHO at 2023-02-14T11:28:29-05:00 Assume platforms support rpaths if they use either ELF or Mach-O Not only Linux, Darwin, and FreeBSD support rpaths. Determine the usability of rpaths based on the object format, not on OS. - - - - - 47716024 by PHO at 2023-02-14T11:29:09-05:00 RTS linker: Improve compatibility with NetBSD 1. Hint address to NetBSD mmap(2) has a different semantics from that of Linux. When a hint address is provided, mmap(2) searches for a free region at or below the hint but *never* above it. This means we can't reliably search for free regions incrementally on the userland, especially when ASLR is enabled. Let the kernel do it for us if we don't care where the mapped address is going to be. 2. NetBSD not only hates to map pages as rwx, but also disallows to switch pages from rw- to r-x unless the intention is declared when pages are initially requested. This means we need a new MemoryAccess mode for pages that are going to be changed to r-x. - - - - - 11de324a by Li-yao Xia at 2023-02-14T11:29:49-05:00 base: Move changelog entry to its place - - - - - 75930424 by Ben Gamari at 2023-02-14T11:30:27-05:00 nativeGen/AArch64: Emit Atomic{Read,Write} inline Previously the AtomicRead and AtomicWrite operations were emitted as out-of-line calls. However, these tend to be very important for performance, especially the RELAXED case (which only exists for ThreadSanitizer checking). Fixes #22115. - - - - - d6411d6c by Andreas Klebinger at 2023-02-14T11:31:04-05:00 Fix some correctness issues around tag inference when targeting the bytecode generator. * Let binders are now always assumed untagged for bytecode. * Imported referenced are now always assumed to be untagged for bytecode. Fixes #22840 - - - - - 9fb4ca89 by sheaf at 2023-02-14T11:31:49-05:00 Introduce warning for loopy superclass solve Commit aed1974e completely re-engineered the treatment of loopy superclass dictionaries in instance declarations. Unfortunately, it has the potential to break (albeit in a rather minor way) user code. To alleviate migration concerns, this commit re-introduces the old behaviour. Any reliance on this old behaviour triggers a warning, controlled by `-Wloopy-superclass-solve`. The warning text explains that GHC might produce bottoming evidence, and provides a migration strategy. This allows us to provide a graceful migration period, alerting users when they are relying on this unsound behaviour. Fixes #22912 #22891 #20666 #22894 #22905 - - - - - 1928c7f3 by Cheng Shao at 2023-02-14T11:32:26-05:00 rts: make it possible to change mblock size on 32-bit targets The MBLOCK_SHIFT macro must be the single source of truth for defining the mblock size, and changing it should only affect performance, not correctness. This patch makes it truly possible to reconfigure mblock size, at least on 32-bit targets, by fixing places which implicitly relied on the previous MBLOCK_SHIFT constant. Fixes #22901. - - - - - 78aa3b39 by Simon Hengel at 2023-02-14T11:33:06-05:00 Update outdated references to notes - - - - - e8baecd2 by meooow25 at 2023-02-14T11:33:49-05:00 Documentation: Improve Foldable1 documentation * Explain foldrMap1, foldlMap1, foldlMap1', and foldrMap1' in greater detail, the text is mostly adapted from documentation of Foldable. * Describe foldr1, foldl1, foldl1' and foldr1' in terms of the above functions instead of redoing the full explanation. * Small updates to documentation of fold1, foldMap1 and toNonEmpty, again adapting from Foldable. * Update the foldMap1 example to lists instead of Sum since this is recommended for lazy right-associative folds. Fixes #22847 - - - - - 85a1a575 by romes at 2023-02-14T11:34:25-05:00 fix: Mark ghci Prelude import as implicit Fixes #22829 In GHCi, we were creating an import declaration for Prelude but we were not setting it as an implicit declaration. Therefore, ghci's import of Prelude triggered -Wmissing-import-lists. Adds regression test T22829 to testsuite - - - - - 3b019a7a by Cheng Shao at 2023-02-14T11:35:03-05:00 compiler: fix generateCgIPEStub for no-tables-next-to-code builds generateCgIPEStub already correctly implements the CmmTick finding logic for when tables-next-to-code is on/off, but it used the wrong predicate to decide when to switch between the two. Previously it switches based on whether the codegen is unregisterised, but there do exist registerised builds that disable tables-next-to-code! This patch corrects that problem. Fixes #22896. - - - - - 08c0822c by doyougnu at 2023-02-15T00:16:39-05:00 docs: release notes, user guide: add js backend Follow up from #21078 - - - - - 79d8fd65 by Bryan Richter at 2023-02-15T00:17:15-05:00 Allow failure in nightly-x86_64-linux-deb10-no_tntc-validate See #22343 - - - - - 9ca51f9e by Cheng Shao at 2023-02-15T00:17:53-05:00 rts: add the rts_clearMemory function This patch adds the rts_clearMemory function that does its best to zero out unused RTS memory for a wasm backend use case. See the comment above rts_clearMemory() prototype declaration for more detailed explanation. Closes #22920. - - - - - 26df73fb by Oleg Grenrus at 2023-02-15T22:20:57-05:00 Add -single-threaded flag to force single threaded rts This is the small part of implementing https://github.com/ghc-proposals/ghc-proposals/pull/240 - - - - - 631c6c72 by Cheng Shao at 2023-02-16T06:43:09-05:00 docs: add a section for the wasm backend Fixes #22658 - - - - - 1878e0bd by Bryan Richter at 2023-02-16T06:43:47-05:00 tests: Mark T12903 fragile everywhere See #21184 - - - - - b9420eac by Bryan Richter at 2023-02-16T06:43:47-05:00 Mark all T5435 variants as fragile See #22970. - - - - - df3d94bd by Sylvain Henry at 2023-02-16T06:44:33-05:00 Testsuite: mark T13167 as fragile for JS (#22921) - - - - - 324e925b by Sylvain Henry at 2023-02-16T06:45:15-05:00 JS: disable debugging info for heap objects - - - - - 518af814 by Josh Meredith at 2023-02-16T10:16:32-05:00 Factor JS Rts generation for h$c{_,0,1,2} into h$c{n} and improve name caching - - - - - 34cd308e by Ben Gamari at 2023-02-16T10:17:08-05:00 base: Note move of GHC.Stack.CCS.whereFrom to GHC.InfoProv in changelog Fixes #22883. - - - - - 12965aba by Simon Peyton Jones at 2023-02-16T10:17:46-05:00 Narrow the dont-decompose-newtype test Following #22924 this patch narrows the test that stops us decomposing newtypes. The key change is the use of noGivenNewtypeReprEqs in GHC.Tc.Solver.Canonical.canTyConApp. We went to and fro on the solution, as you can see in #22924. The result is carefully documented in Note [Decomoposing newtype equalities] On the way I had revert most of commit 3e827c3f74ef76d90d79ab6c4e71aa954a1a6b90 Author: Richard Eisenberg <rae at cs.brynmawr.edu> Date: Mon Dec 5 10:14:02 2022 -0500 Do newtype unwrapping in the canonicaliser and rewriter See Note [Unwrap newtypes first], which has the details. It turns out that (a) 3e827c3f makes GHC behave worse on some recursive newtypes (see one of the tests on this commit) (b) the finer-grained test (namely noGivenNewtypeReprEqs) renders 3e827c3f unnecessary - - - - - 5b038888 by Bodigrim at 2023-02-16T10:18:24-05:00 Documentation: add an example of SPEC usage - - - - - 681e0e8c by sheaf at 2023-02-16T14:09:56-05:00 No default finalizer exception handler Commit cfc8e2e2 introduced a mechanism for handling of exceptions that occur during Handle finalization, and 372cf730 set the default handler to print out the error to stderr. However, #21680 pointed out we might not want to set this by default, as it might pollute users' terminals with unwanted information. So, for the time being, the default handler discards the exception. Fixes #21680 - - - - - b3ac17ad by Matthew Pickering at 2023-02-16T14:10:31-05:00 unicode: Don't inline bitmap in generalCategory generalCategory contains a huge literal string but is marked INLINE, this will duplicate the string into any use site of generalCategory. In particular generalCategory is used in functions like isSpace and the literal gets inlined into this function which makes it massive. https://github.com/haskell/core-libraries-committee/issues/130 Fixes #22949 ------------------------- Metric Decrease: T4029 T18304 ------------------------- - - - - - 8988eeef by sheaf at 2023-02-16T20:32:27-05:00 Expand synonyms in RoughMap We were failing to expand type synonyms in the function GHC.Core.RoughMap.typeToRoughMatchLookupTc, even though the RoughMap infrastructure crucially relies on type synonym expansion to work. This patch adds the missing type-synonym expansion. Fixes #22985 - - - - - 3dd50e2f by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Add test artifact Add the released testsuite tarball to the generated ghcup metadata. - - - - - c6a967d9 by Matthew Pickering at 2023-02-16T20:33:03-05:00 ghcup-metadata: Use Ubuntu and Rocky bindists Prefer to use the Ubuntu 20.04 and 18.04 binary distributions on Ubuntu and Linux Mint. Prefer to use the Rocky 8 binary distribution on unknown distributions. - - - - - be0b7209 by Matthew Pickering at 2023-02-17T09:37:16+00:00 Add INLINABLE pragmas to `generic*` functions in Data.OldList These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129 - - - - - a203ad85 by Sylvain Henry at 2023-02-17T15:59:16-05:00 Merge libiserv with ghci `libiserv` serves no purpose. As it depends on `ghci` and doesn't have more dependencies than the `ghci` package, its code could live in the `ghci` package too. This commit also moves most of the code from the `iserv` program into the `ghci` package as well so that it can be reused. This is especially useful for the implementation of TH for the JS backend (#22261, !9779). - - - - - 7080a93f by Simon Peyton Jones at 2023-02-20T12:06:32+01:00 Improve GHC.Tc.Gen.App.tcInstFun It wasn't behaving right when inst_final=False, and the function had no type variables f :: Foo => Int Rather a corner case, but we might as well do it right. Fixes #22908 Unexpectedly, three test cases (all using :type in GHCi) got slightly better output as a result: T17403, T14796, T12447 - - - - - 2592ab69 by Cheng Shao at 2023-02-20T10:35:30-05:00 compiler: fix cost centre profiling breakage in wasm NCG due to incorrect register mapping The wasm NCG used to map CCCS to a wasm global, based on the observation that CCCS is a transient register that's already handled by thread state load/store logic, so it doesn't need to be backed by the rCCCS field in the register table. Unfortunately, this is wrong, since even when Cmm execution hasn't yielded back to the scheduler, the Cmm code may call enterFunCCS, which does use rCCCS. This breaks cost centre profiling in a subtle way, resulting in inaccurate stack traces in some test cases. The fix is simple though: just remove the CCCS mapping. - - - - - 26243de1 by Alexis King at 2023-02-20T15:27:17-05:00 Handle top-level Addr# literals in the bytecode compiler Fixes #22376. - - - - - 0196cc2b by romes at 2023-02-20T15:27:52-05:00 fix: Explicitly flush stdout on plugin Because of #20791, the plugins tests often fail. This is a temporary fix to stop the tests from failing due to unflushed outputs on windows and the explicit flush should be removed when #20791 is fixed. - - - - - 4327d635 by Ryan Scott at 2023-02-20T20:44:34-05:00 Don't generate datacon wrappers for `type data` declarations Data constructor wrappers only make sense for _value_-level data constructors, but data constructors for `type data` declarations only exist at the _type_ level. This patch does the following: * The criteria in `GHC.Types.Id.Make.mkDataConRep` for whether a data constructor receives a wrapper now consider whether or not its parent data type was declared with `type data`, omitting a wrapper if this is the case. * Now that `type data` data constructors no longer receive wrappers, there is a spot of code in `refineDefaultAlt` that panics when it encounters a value headed by a `type data` type constructor. I've fixed this with a special case in `refineDefaultAlt` and expanded `Note [Refine DEFAULT case alternatives]` to explain why we do this. Fixes #22948. - - - - - 96dc58b9 by Ryan Scott at 2023-02-20T20:44:35-05:00 Treat type data declarations as empty when checking pattern-matching coverage The data constructors for a `type data` declaration don't exist at the value level, so we don't want GHC to warn users to match on them. Fixes #22964. - - - - - ff8e99f6 by Ryan Scott at 2023-02-20T20:44:35-05:00 Disallow `tagToEnum#` on `type data` types We don't want to allow users to conjure up values of a `type data` type using `tagToEnum#`, as these simply don't exist at the value level. - - - - - 8e765aff by Bodigrim at 2023-02-21T12:03:24-05:00 Bump submodule text to 2.0.2 - - - - - 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Bodigrim at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - b7a29da7 by Ben Gamari at 2023-04-25T12:58:02-04:00 ghc-toolchain: Initial commit - - - - - b6c8fde3 by Ben Gamari at 2023-04-25T12:59:42-04:00 configure: Rip out Solaris dyld check Solaris 11 was released over a decade ago and, moreover, I doubt we have any Solaris users - - - - - e556bebf by Ben Gamari at 2023-04-25T12:59:44-04:00 Move via-C flags into GHC - - - - - bc7342c3 by Ben Gamari at 2023-04-25T13:08:35-04:00 Rip out runtime linker/compiler checks - - - - - 5b191abd by Ben Gamari at 2023-04-25T13:08:35-04:00 configure: Rip out toolchain selection logic - - - - - 1035f226 by Ben Gamari at 2023-04-25T13:30:25-04:00 Fixes - - - - - 17 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/darwin/toolchain.nix - + .gitlab/gen-ci.cabal - .gitlab/gen_ci.hs - + .gitlab/generate_job_metadata - .gitlab/generate_jobs - + .gitlab/hello.hs - + .gitlab/hie.yaml - .gitlab/jobs.yaml - .gitlab/merge_request_templates/merge-request.md - + .gitlab/rel_eng/default.nix - + .gitlab/rel_eng/fetch-gitlab-artifacts/.gitignore - + .gitlab/rel_eng/fetch-gitlab-artifacts/README.mkd - + .gitlab/rel_eng/fetch-gitlab-artifacts/default.nix The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/93aa45cdc2271e5476ea3fad43c3a42f711811a2...1035f226e7297e1f51d0c0c89e280bfec6b4cb27 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/93aa45cdc2271e5476ea3fad43c3a42f711811a2...1035f226e7297e1f51d0c0c89e280bfec6b4cb27 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 18:32:19 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Tue, 25 Apr 2023 14:32:19 -0400 Subject: [Git][ghc/ghc][wip/T23208] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <64481cb3399ef_178e74c84fb7a81477786@gitlab.mail> Sebastian Graf pushed to branch wip/T23208 at Glasgow Haskell Compiler / GHC Commits: 235f907a by Sebastian Graf at 2023-04-25T20:32:01+02:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 14 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs - testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr - testsuite/tests/stranal/should_compile/T18894.stderr - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -110,6 +110,6 @@ test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) -test('T19969', normal, compile, ['-ddump-simpl -dsuppress-uniques']) +test('T19969', [grep_errmsg('LoopBreaker')], compile, ['-ddump-simpl -dsuppress-uniques']) # f should become loopbreaker test('T19883', normal, compile, ['']) test('T22719', normal, compile, ['-ddump-simpl -dsuppress-uniques -dno-typeable-binds']) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -228,7 +228,6 @@ test('T13027', normal, compile, ['']) test('T13025', normal, makefile_test, ['T13025']) -test('T13143', only_ways(['optasm']), compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-ticks']) test('T13156', normal, makefile_test, ['T13156']) test('T11444', normal, compile, ['']) test('str-rules', @@ -414,7 +413,8 @@ test('T17966', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) # We expect to see a SPEC rule for $cm test('T19644', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) test('T21391', normal, compile, ['-O -dcore-lint']) -test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddump-simpl']) +# T22112: Simply test that dumping the Core doesn't loop becuse of the unfolding and ignore the dump output +test('T22112', [ grep_errmsg('never matches') ], compile, ['-O -dsuppress-uniques -dno-typeable-binds -fexpose-all-unfoldings -ddump-simpl']) test('T21391a', normal, compile, ['-O -dcore-lint']) # We don't want to see a thunk allocation for the insertBy expression after CorePrep. test('T21392', [ grep_errmsg(r'sat.* :: \[\(.*Unique, .*Int\)\]'), expect_broken(21392) ], compile, ['-O -ddump-prep -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr ===================================== @@ -7,21 +7,22 @@ Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. (# #) -> a -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] -T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) +[GblId, Arity=1, Str=b{sBp->S}, Cpr=b, Unf=OtherCon []] +T13143.$wf + = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) end Rec } -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} f [InlPrag=NOINLINE[final]] :: forall a. Int -> a [GblId, Arity=1, - Str=b, + Str=b{sBp->S}, Cpr=b, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) - Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)}] -f = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) + Tmpl= \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##)}] +f = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T13143.$trModule4 :: GHC.Prim.Addr# @@ -65,9 +66,9 @@ T13143.$trModule = GHC.Types.Module T13143.$trModule3 T13143.$trModule1 -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} -lvl :: Int -[GblId, Str=b, Cpr=b] -lvl = T13143.$wf @Int GHC.Prim.(##) +lvl_rBN :: Int +[GblId, Str=b{sBp->S}, Cpr=b] +lvl_rBN = T13143.$wf @Int GHC.Prim.(##) Rec { -- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0} @@ -78,17 +79,17 @@ T13143.$wg [InlPrag=[2], Occ=LoopBreaker] Str=<1L><1L>, Unf=OtherCon []] T13143.$wg - = \ (ds :: Bool) (ds1 :: Bool) (ww :: GHC.Prim.Int#) -> - case ds of { + = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (ww_sBv :: GHC.Prim.Int#) -> + case ds_sBr of { False -> - case ds1 of { - False -> T13143.$wg GHC.Types.False GHC.Types.True ww; - True -> GHC.Prim.+# ww 1# + case ds1_sBs of { + False -> T13143.$wg GHC.Types.False GHC.Types.True ww_sBv; + True -> GHC.Prim.+# ww_sBv 1# }; True -> - case ds1 of { - False -> T13143.$wg GHC.Types.True GHC.Types.True ww; - True -> case lvl of wild2 { } + case ds1_sBs of { + False -> T13143.$wg GHC.Types.True GHC.Types.True ww_sBv; + True -> case lvl_rBN of wild2_00 { } } } end Rec } @@ -102,17 +103,20 @@ g [InlPrag=[2]] :: Bool -> Bool -> Int -> Int Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) - Tmpl= \ (ds [Occ=Once1] :: Bool) - (ds1 [Occ=Once1] :: Bool) - (p [Occ=Once1!] :: Int) -> - case p of { GHC.Types.I# ww [Occ=Once1] -> - case T13143.$wg ds ds1 ww of ww1 [Occ=Once1] { __DEFAULT -> - GHC.Types.I# ww1 + Tmpl= \ (ds_sBr [Occ=Once1] :: Bool) + (ds1_sBs [Occ=Once1] :: Bool) + (p_sBt [Occ=Once1!] :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv [Occ=Once1] -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA [Occ=Once1] + { __DEFAULT -> + GHC.Types.I# ww1_sBA } }}] -g = \ (ds :: Bool) (ds1 :: Bool) (p :: Int) -> - case p of { GHC.Types.I# ww -> - case T13143.$wg ds ds1 ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } +g = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (p_sBt :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA { __DEFAULT -> + GHC.Types.I# ww1_sBA + } } ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -42,6 +42,9 @@ test('T13031', normal, makefile_test, []) test('T13077', normal, compile, ['']) test('T13077a', normal, compile, ['']) +# T13143: WW for NOINLINE function f +test('T13143', [ grep_errmsg(r'^T13143\.\$wf') ], compile, ['-ddump-simpl']) + # T15627 # Absent bindings of unlifted types should be WW'ed away. # The idea is to check that both $wmutVar and $warray ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/235f907a3a982fefff6e27f5564d0d1ba355c161 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/235f907a3a982fefff6e27f5564d0d1ba355c161 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 19:52:39 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 15:52:39 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: JS: Fix h$base_access implementation (issue 22576) Message-ID: <64482f87ad581_178e74c983f95414917a9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ba9a456a by Josh Meredith at 2023-04-25T15:52:28-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 743cd728 by Andrei Borzenkov at 2023-04-25T15:52:33-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - 9 changed files: - docs/users_guide/exts/implicit_parameters.rst - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/jsbits/base.js - testsuite/tests/ado/all.T - testsuite/tests/rep-poly/all.T - + testsuite/tests/simplCore/should_run/T23289.hs - + testsuite/tests/simplCore/should_run/T23289.stdout - testsuite/tests/simplCore/should_run/all.T - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== docs/users_guide/exts/implicit_parameters.rst ===================================== @@ -180,6 +180,27 @@ parameter. So we get the following results in GHCi: Adding a type signature dramatically changes the result! This is a rather counter-intuitive phenomenon, worth watching out for. +Implicit parameters scoping guarantees +------------------------------------- + +GHC always takes the most nested implicit parameter binding from the +context to find the value. Consider the following code:: + + let ?f = 1 in let ?f = 2 in ?f + +This expression will always return 2. + +Another example of this rule is matching over constructors with constraints. +For example:: + + data T where + MkT :: (?f :: Int) => T + + f :: T -> T -> Int + f MkT MkT = ?f + +Here GHC will always take ``?f`` from the last match. + Implicit parameters and monomorphism ------------------------------------ @@ -199,5 +220,3 @@ a type signature for ``y``, then ``y`` will get type ``(?x::Int) => Int``, so the occurrence of ``y`` in the body of the ``let`` will see the inner binding of ``?x``, so ``(f 9)`` will return ``14``. - - ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -105,7 +105,11 @@ inTreeCompilerArgs stg = do tables_next_to_code <- flag TablesNextToCode targetWithSMP <- targetSupportsSMP - let ghcStage = succStage stg + cross <- flag CrossCompiling + + let ghcStage + | cross, Stage1 <- stg = Stage1 + | otherwise = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage ===================================== libraries/base/jsbits/base.js ===================================== @@ -14,11 +14,11 @@ function h$base_access(file, file_off, mode, c) { TRACE_IO("base_access") #ifndef GHCJS_BROWSER if(h$isNode()) { - h$fs.stat(fd, function(err, fs) { - if(err) { + h$fs.access(h$decodeUtf8z(file, file_off), mode, function(err) { + if (err) { h$handleErrnoC(err, -1, 0, c); } else { - c(mode & fs.mode); // fixme is this ok? + c(0); } }); } else ===================================== testsuite/tests/ado/all.T ===================================== @@ -20,5 +20,5 @@ test('T15344', normal, compile_and_run, ['']) test('T16628', normal, compile_fail, ['']) test('T17835', normal, compile, ['']) test('T20540', normal, compile, ['']) -test('T16135', [when(compiler_debugged(),expect_broken(16135)), js_broken(22576)], compile_fail, ['']) +test('T16135', [when(compiler_debugged(),expect_broken(16135))], compile_fail, ['']) test('T22483', normal, compile, ['-Wall']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', js_broken(22576), compile, ['']) +test('RepPolyWrappedVar2', js_broken(23280), compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) ===================================== testsuite/tests/simplCore/should_run/T23289.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE ImplicitParams, GADTs #-} +module Main where + +data T where + MkT :: (?f :: Int) => T + +f :: T -> T -> Int +f MkT MkT = ?f + +main :: IO () +main = do + print (let ?g = 1 in let ?g = 2 in ?g) + print $ f (let ?f = 3 in MkT) (let ?f = 4 in MkT) ===================================== testsuite/tests/simplCore/should_run/T23289.stdout ===================================== @@ -0,0 +1,2 @@ +2 +4 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -111,3 +111,4 @@ test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) +test('T23289', normal, compile_and_run, ['']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -328,7 +328,7 @@ test('T8262', normal, compile_fail, ['']) # TcCoercibleFail times out with the compiler is compiled with -DDEBUG. # This is expected (see comment in source file). -test('TcCoercibleFail', [when(compiler_debugged(), skip), js_broken(22576)], compile_fail, ['']) +test('TcCoercibleFail', [when(compiler_debugged(), skip)], compile_fail, ['']) test('TcCoercibleFail2', [], compile_fail, ['']) test('TcCoercibleFail3', [], compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8139a1666277d880c3a3fa57f503fae3f19e5a88...743cd728239f8775fab8d6f7d5638247a32d1031 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8139a1666277d880c3a3fa57f503fae3f19e5a88...743cd728239f8775fab8d6f7d5638247a32d1031 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 22:12:55 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 18:12:55 -0400 Subject: [Git][ghc/ghc][master] JS: Fix h$base_access implementation (issue 22576) Message-ID: <64485067ee872_178e74cc0003e4151426d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 5 changed files: - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/jsbits/base.js - testsuite/tests/ado/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -105,7 +105,11 @@ inTreeCompilerArgs stg = do tables_next_to_code <- flag TablesNextToCode targetWithSMP <- targetSupportsSMP - let ghcStage = succStage stg + cross <- flag CrossCompiling + + let ghcStage + | cross, Stage1 <- stg = Stage1 + | otherwise = succStage stg debugAssertions <- ghcDebugAssertions <$> flavour <*> pure ghcStage debugged <- ghcDebugged <$> flavour <*> pure ghcStage profiled <- ghcProfiled <$> flavour <*> pure ghcStage ===================================== libraries/base/jsbits/base.js ===================================== @@ -14,11 +14,11 @@ function h$base_access(file, file_off, mode, c) { TRACE_IO("base_access") #ifndef GHCJS_BROWSER if(h$isNode()) { - h$fs.stat(fd, function(err, fs) { - if(err) { + h$fs.access(h$decodeUtf8z(file, file_off), mode, function(err) { + if (err) { h$handleErrnoC(err, -1, 0, c); } else { - c(mode & fs.mode); // fixme is this ok? + c(0); } }); } else ===================================== testsuite/tests/ado/all.T ===================================== @@ -20,5 +20,5 @@ test('T15344', normal, compile_and_run, ['']) test('T16628', normal, compile_fail, ['']) test('T17835', normal, compile, ['']) test('T20540', normal, compile, ['']) -test('T16135', [when(compiler_debugged(),expect_broken(16135)), js_broken(22576)], compile_fail, ['']) +test('T16135', [when(compiler_debugged(),expect_broken(16135))], compile_fail, ['']) test('T22483', normal, compile, ['-Wall']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', js_broken(22576), compile, ['']) +test('RepPolyWrappedVar2', js_broken(23280), compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -328,7 +328,7 @@ test('T8262', normal, compile_fail, ['']) # TcCoercibleFail times out with the compiler is compiled with -DDEBUG. # This is expected (see comment in source file). -test('TcCoercibleFail', [when(compiler_debugged(), skip), js_broken(22576)], compile_fail, ['']) +test('TcCoercibleFail', [when(compiler_debugged(), skip)], compile_fail, ['']) test('TcCoercibleFail2', [], compile_fail, ['']) test('TcCoercibleFail3', [], compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f656188e271fc55b31a50a1c2f3cf6ff9bbeeea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f656188e271fc55b31a50a1c2f3cf6ff9bbeeea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 22:13:36 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 25 Apr 2023 18:13:36 -0400 Subject: [Git][ghc/ghc][master] Give more guarntees about ImplicitParams (#23289) Message-ID: <6448509074b66_178e74cc3477001517980@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - 4 changed files: - docs/users_guide/exts/implicit_parameters.rst - + testsuite/tests/simplCore/should_run/T23289.hs - + testsuite/tests/simplCore/should_run/T23289.stdout - testsuite/tests/simplCore/should_run/all.T Changes: ===================================== docs/users_guide/exts/implicit_parameters.rst ===================================== @@ -180,6 +180,27 @@ parameter. So we get the following results in GHCi: Adding a type signature dramatically changes the result! This is a rather counter-intuitive phenomenon, worth watching out for. +Implicit parameters scoping guarantees +------------------------------------- + +GHC always takes the most nested implicit parameter binding from the +context to find the value. Consider the following code:: + + let ?f = 1 in let ?f = 2 in ?f + +This expression will always return 2. + +Another example of this rule is matching over constructors with constraints. +For example:: + + data T where + MkT :: (?f :: Int) => T + + f :: T -> T -> Int + f MkT MkT = ?f + +Here GHC will always take ``?f`` from the last match. + Implicit parameters and monomorphism ------------------------------------ @@ -199,5 +220,3 @@ a type signature for ``y``, then ``y`` will get type ``(?x::Int) => Int``, so the occurrence of ``y`` in the body of the ``let`` will see the inner binding of ``?x``, so ``(f 9)`` will return ``14``. - - ===================================== testsuite/tests/simplCore/should_run/T23289.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE ImplicitParams, GADTs #-} +module Main where + +data T where + MkT :: (?f :: Int) => T + +f :: T -> T -> Int +f MkT MkT = ?f + +main :: IO () +main = do + print (let ?g = 1 in let ?g = 2 in ?g) + print $ f (let ?f = 3 in MkT) (let ?f = 4 in MkT) ===================================== testsuite/tests/simplCore/should_run/T23289.stdout ===================================== @@ -0,0 +1,2 @@ +2 +4 ===================================== testsuite/tests/simplCore/should_run/all.T ===================================== @@ -111,3 +111,4 @@ test('T22448', normal, compile_and_run, ['-O1']) test('T22998', normal, compile_and_run, ['-O0 -fspecialise -dcore-lint']) test('T23184', normal, compile_and_run, ['-O']) test('T23134', normal, compile_and_run, ['-O0 -fcatch-nonexhaustive-cases']) +test('T23289', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74c557121fbcae32abd3b4a69513f8aa7d536073 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74c557121fbcae32abd3b4a69513f8aa7d536073 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Apr 25 22:27:02 2023 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Tue, 25 Apr 2023 18:27:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/epa-fix-explicitbraces Message-ID: <644853b652a6c_178e74cc784b74152108b@gitlab.mail> Alan Zimmerman pushed new branch wip/az/epa-fix-explicitbraces at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/epa-fix-explicitbraces You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 04:05:08 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 00:05:08 -0400 Subject: [Git][ghc/ghc][wip/unitidset] lint Message-ID: <6448a2f448e94_178e74d242e6b81541833@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: 9d972155 by Josh Meredith at 2023-04-26T04:04:56+00:00 lint - - - - - 2 changed files: - compiler/GHC/Linker/Types.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -53,7 +53,6 @@ import Control.Concurrent.MVar import Data.Time ( UTCTime ) import Data.Maybe import GHC.Unit.Module.Env -import GHC.Types.Unique.DSet import GHC.Types.Unique.DFM import GHC.Unit.Module.WholeCoreBindings ===================================== ghc/GHCi/UI.hs ===================================== @@ -563,7 +563,7 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let in_multi = sizeUniqDSet (hsc_all_home_unit_ids hsc_env) > 1 empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, @@ -2576,7 +2576,7 @@ isSafeModule m = do case msafe && isEmptyUniqDSet bad of True -> liftIO $ putStrLn $ mname ++ " is trusted!" False -> do - when (not $ null bad) + when (not $ emptyUniqDSet bad) (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): " ++ (intercalate ", " $ map (showPpr dflags) (uniqDSetToList bad))) liftIO $ putStrLn $ mname ++ " is NOT trusted!" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d972155c4a768defc2763bc594215d1da474cd4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d972155c4a768defc2763bc594215d1da474cd4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 04:13:56 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 00:13:56 -0400 Subject: [Git][ghc/ghc][wip/unitidset] lint Message-ID: <6448a5045fdf8_178e74d24b8c3c1544184@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: e84c74de by Josh Meredith at 2023-04-26T04:13:47+00:00 lint - - - - - 1 changed file: - ghc/GHCi/UI.hs Changes: ===================================== ghc/GHCi/UI.hs ===================================== @@ -2576,7 +2576,7 @@ isSafeModule m = do case msafe && isEmptyUniqDSet bad of True -> liftIO $ putStrLn $ mname ++ " is trusted!" False -> do - when (not $ emptyUniqDSet bad) + when (not $ isEmptyUniqDSet bad) (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): " ++ (intercalate ", " $ map (showPpr dflags) (uniqDSetToList bad))) liftIO $ putStrLn $ mname ++ " is NOT trusted!" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e84c74de6c2637a8c5f3b71a08e1dc4f225a25a3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e84c74de6c2637a8c5f3b71a08e1dc4f225a25a3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 04:50:22 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 00:50:22 -0400 Subject: [Git][ghc/ghc][wip/unitidset] lint Message-ID: <6448ad8e1668b_178e74d2eef2b415452c7@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: f8b551d1 by Josh Meredith at 2023-04-26T04:50:09+00:00 lint - - - - - 1 changed file: - compiler/GHC/Unit/Module/ModGuts.hs Changes: ===================================== compiler/GHC/Unit/Module/ModGuts.hs ===================================== @@ -37,8 +37,6 @@ import GHC.Types.SourceFile ( HscSource(..), hscSourceToIsBoot ) import GHC.Types.SrcLoc import GHC.Types.CostCentre -import Data.Set (Set) - -- | A ModGuts is carried through the compiler, accumulating stuff as it goes -- There is only one ModGuts at any time, the one for the module View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8b551d1e751df42274467a29a5cd97755e00b01 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f8b551d1e751df42274467a29a5cd97755e00b01 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 06:22:24 2023 From: gitlab at gitlab.haskell.org (Joachim Breitner (@nomeata)) Date: Wed, 26 Apr 2023 02:22:24 -0400 Subject: [Git][ghc/ghc][joachim/wip/ghc-all-in-one] More stuff Message-ID: <6448c320d8aae_178e74d499738c154815c@gitlab.mail> Joachim Breitner pushed to branch joachim/wip/ghc-all-in-one at Glasgow Haskell Compiler / GHC Commits: 64fe295f by Joachim Breitner at 2023-04-25T20:02:53+02:00 More stuff - - - - - 1 changed file: - compiler/GHC/Cmm/CLabel.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1444,7 +1444,6 @@ pprCLabel platform lbl = pprCLabelStyle platform CStyle lbl {-# SPECIALIZE pprCLabel :: Platform -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable instance OutputableP Platform CLabel where - {-# INLINE pdoc #-} -- see Note [Bangs in CLabel] pdoc !platform lbl = getPprStyle $ \pp_sty -> case pp_sty of PprDump{} -> pprCLabel platform lbl View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64fe295fdf62f7de543a6ea17b69149c582e5d3e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/64fe295fdf62f7de543a6ea17b69149c582e5d3e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 06:43:28 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 02:43:28 -0400 Subject: [Git][ghc/ghc][wip/unitidset] lint Message-ID: <6448c810192cb_178e74d4effff41552331@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: b38e78aa by Josh Meredith at 2023-04-26T06:43:16+00:00 lint - - - - - 1 changed file: - ghc/GHCi/UI.hs Changes: ===================================== ghc/GHCi/UI.hs ===================================== @@ -126,7 +126,6 @@ import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef ) import Data.List ( elemIndices, find, intercalate, intersperse, minimumBy, isPrefixOf, isSuffixOf, nub, partition, sort, sortBy, (\\) ) import qualified Data.List.NonEmpty as NE -import qualified Data.Set as S import Data.Maybe import qualified Data.Map as M import Data.IntMap.Strict (IntMap) @@ -170,7 +169,6 @@ import GHC.TopHandler ( topHandler ) import GHCi.Leak import qualified GHC.Unit.Module.Graph as GHC -import GHC.Types.Unique.DSet (isEmptyUniqDSet) ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b38e78aa03090ace093fa4026e7edc6cbb88df03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b38e78aa03090ace093fa4026e7edc6cbb88df03 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 09:38:15 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 05:38:15 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <6448f107c6518_178e74d7e426f415713b@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 87a2a4b0 by Rodrigo Mesquita at 2023-04-26T10:29:44+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 15 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -586,12 +586,22 @@ Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~ -dcSourceArity does not take constraints into account, -but dcRepArity does. For example: +A `DataCon`'s source arity and core representation arity may differ: +`dcSourceArity` does not take constraints into account, but `dcRepArity` does. + +The additional arguments taken into account by `dcRepArity` include quantified +dictionaries and coercion arguments, lifted and unlifted (despite the unlifted +coercion arguments having a zero-width runtime representation). +For example: MkT :: Ord a => a -> T a dcSourceArity = 1 dcRepArity = 2 + MkU :: (b ~ '[]) => U b + dcSourceArity = 0 + dcRepArity = 1 + + Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A DataCon has two different sets of type variables: @@ -981,7 +991,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1405,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of value arguments (including zero-width coercions) +-- stored by the given `DataCon`'s worker in its Core representation. This may +-- differ from the number of arguments that appear in the source code; see also +-- Note [DataCon arities] dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1417,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether this `DataCon`'s worker, in its Core representation, takes +-- any value arguments. +-- +-- In particular, remember that we include coercion arguments in the arity of +-- the Core representation of the `DataCon` -- both lifted and unlifted +-- coercions, despite the latter having zero-width runtime representation. +-- +-- See also Note [DataCon arities]. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,123 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id` +* For Ids defined in this module: is `Nothing` +* For imported Ids: + * is (Just lf_info) if the LFInfo was serialised into the interface file + (typically, when the exporting module was compiled with -O) + * is Nothing if it wasn't serialised + +However, when an interface doesn't have a LambdaFormInfo for some imported Id +(so that its `lfInfo` field is `Nothing`), we can conservatively create one +using `mkLFImported`. + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146). In particular, saturated data constructor applications *must* be +unambiguously given `LFCon`, and the invariant + + If the LFInfo (serialised or built with mkLFImported) says LFCon, then it + really is a static data constructor, and similar for LFReEntrant + +must be upheld. + +In `mkLFImported`, we make a conservative approximation to the real +LambdaFormInfo as follows: + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged (by `litIdInfo`) with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> Maybe a` is given `LFReEntrant` + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -71,12 +71,13 @@ moving parts are: -fomit-interface-pragmas or -fno-code; and we won't read it in if you have -fignore-interface-pragmas. (We could revisit this decision.) -Note [Imported nullary datacon wrappers must have correct LFInfo] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As described in `Note [Conveying CAF-info and LFInfo between modules]`, -imported nullary datacons must have their LambdaFormInfo set to reflect the -fact that they are evaluated . This is necessary are otherwise references -to them may be passed untagged to code that expects tagged references. +imported unlifted nullary datacons must have their LambdaFormInfo set to +reflect the fact that they are evaluated . This is necessary as otherwise +references to them may be passed untagged to code that expects tagged +references. What may be less obvious is that this must be done for not only datacon workers but also *wrappers*. The reason is found in this program @@ -113,6 +114,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +164,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,8 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | This function counts all arguments post-unarisation, which includes +-- arguments with no runtime representation -- see Note [Unarisation and arity] idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -374,6 +374,7 @@ data IdInfo -- -- See documentation of the getters for what these packed fields mean. lfInfo :: !(Maybe LambdaFormInfo), + -- ^ See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure -- See documentation of the getters for what these packed fields mean. tagSig :: !(Maybe TagSig) @@ -439,7 +440,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87a2a4b0efdc4fb561a56ca29f0adda1ad156262 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87a2a4b0efdc4fb561a56ca29f0adda1ad156262 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 10:32:46 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 06:32:46 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Message-ID: <6448fdce1372e_178e74d8d9b8f81583190@gitlab.mail> Josh Meredith pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: 49fc7a85 by Josh Meredith at 2023-04-26T10:32:06+00:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 27 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Sinker.hs - compiler/GHC/StgToJS/StgUtils.hs - testsuite/tests/dependent/should_compile/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_run/all.T Changes: ===================================== compiler/GHC/ByteCode/Instr.hs ===================================== @@ -252,7 +252,7 @@ pprStgAltShort opts GenStgAlt{alt_con=con, alt_bndrs=args, alt_rhs=expr} = ppr con <+> sep (map ppr args) <+> text "->" <+> pprStgExprShort opts expr pprStgRhsShort :: OutputablePass pass => StgPprOpts -> GenStgRhs pass -> SDoc -pprStgRhsShort opts (StgRhsClosure _ext _cc upd_flag args body) = +pprStgRhsShort opts (StgRhsClosure _ext _cc upd_flag args body _typ) = hang (hsep [ char '\\' <> ppr upd_flag, brackets (interppSP args) ]) 4 (pprStgExprShort opts body) pprStgRhsShort opts rhs = pprStgRhs opts rhs ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -691,7 +691,7 @@ coreToStgRhs (bndr, rhs) = do return (mkStgRhs bndr new_rhs) -- Represents the RHS of a binding for use with mk(Top)StgRhs. -data PreStgRhs = PreStgRhs [Id] StgExpr -- The [Id] is empty for thunks +data PreStgRhs = PreStgRhs [Id] StgExpr Type -- The [Id] is empty for thunks -- Convert the RHS of a binding from Core to STG. This is a wrapper around -- coreToStgExpr that can handle value lambdas. @@ -699,7 +699,7 @@ coreToPreStgRhs :: HasDebugCallStack => CoreExpr -> CtsM PreStgRhs coreToPreStgRhs expr = extendVarEnvCts [ (a, LambdaBound) | a <- args' ] $ do { body' <- coreToStgExpr body - ; return (PreStgRhs args' body') } + ; return (PreStgRhs args' body' (exprType body)) } where (args, body) = myCollectBinders expr args' = filterStgBinders args @@ -713,13 +713,13 @@ mkTopStgRhs CoreToStgOpts { coreToStg_platform = platform , coreToStg_ExternalDynamicRefs = opt_ExternalDynamicRefs , coreToStg_AutoSccsOnIndividualCafs = opt_AutoSccsOnIndividualCafs - } this_mod ccs bndr (PreStgRhs bndrs rhs) + } this_mod ccs bndr (PreStgRhs bndrs rhs typ) | not (null bndrs) = -- The list of arguments is non-empty, so not CAF ( StgRhsClosure noExtFieldSilent dontCareCCS ReEntrant - bndrs rhs + bndrs rhs typ , ccs ) -- After this point we know that `bndrs` is empty, @@ -730,19 +730,19 @@ mkTopStgRhs CoreToStgOpts = -- CorePrep does this right, but just to make sure assertPpr (not (isUnboxedTupleDataCon con || isUnboxedSumDataCon con)) (ppr bndr $$ ppr con $$ ppr args) - ( StgRhsCon dontCareCCS con mn ticks args, ccs ) + ( StgRhsCon dontCareCCS con mn ticks args typ, ccs ) -- Otherwise it's a CAF, see Note [Cost-centre initialization plan]. | opt_AutoSccsOnIndividualCafs = ( StgRhsClosure noExtFieldSilent caf_ccs - upd_flag [] rhs + upd_flag [] rhs typ , collectCC caf_cc caf_ccs ccs ) | otherwise = ( StgRhsClosure noExtFieldSilent all_cafs_ccs - upd_flag [] rhs + upd_flag [] rhs typ , ccs ) where @@ -766,12 +766,12 @@ mkTopStgRhs CoreToStgOpts -- Generate a non-top-level RHS. Cost-centre is always currentCCS, -- see Note [Cost-centre initialization plan]. mkStgRhs :: Id -> PreStgRhs -> StgRhs -mkStgRhs bndr (PreStgRhs bndrs rhs) +mkStgRhs bndr (PreStgRhs bndrs rhs typ) | not (null bndrs) = StgRhsClosure noExtFieldSilent currentCCS ReEntrant - bndrs rhs + bndrs rhs typ -- After this point we know that `bndrs` is empty, -- so this is not a function binding @@ -782,15 +782,15 @@ mkStgRhs bndr (PreStgRhs bndrs rhs) StgRhsClosure noExtFieldSilent currentCCS ReEntrant -- ignored for LNE - [] rhs + [] rhs typ | StgConApp con mn args _ <- unticked_rhs - = StgRhsCon currentCCS con mn ticks args + = StgRhsCon currentCCS con mn ticks args typ | otherwise = StgRhsClosure noExtFieldSilent currentCCS - upd_flag [] rhs + upd_flag [] rhs typ where (ticks, unticked_rhs) = stripStgTicksTop (not . tickishIsCode) rhs ===================================== compiler/GHC/Stg/BcPrep.hs ===================================== @@ -37,14 +37,14 @@ type BcPrepM a = State BcPrepM_State a bcPrepRHS :: StgRhs -> BcPrepM StgRhs -- explicitly match all constructors so we get a warning if we miss any -bcPrepRHS (StgRhsClosure fvs cc upd args (StgTick bp at Breakpoint{} expr)) = do +bcPrepRHS (StgRhsClosure fvs cc upd args (StgTick bp at Breakpoint{} expr) typ) = do {- If we have a breakpoint directly under an StgRhsClosure we don't need to introduce a new binding for it. -} expr' <- bcPrepExpr expr - pure (StgRhsClosure fvs cc upd args (StgTick bp expr')) -bcPrepRHS (StgRhsClosure fvs cc upd args expr) = - StgRhsClosure fvs cc upd args <$> bcPrepExpr expr + pure (StgRhsClosure fvs cc upd args (StgTick bp expr') typ) +bcPrepRHS (StgRhsClosure fvs cc upd args expr typ) = + StgRhsClosure fvs cc upd args <$> bcPrepExpr expr <*> pure typ bcPrepRHS con at StgRhsCon{} = pure con bcPrepExpr :: StgExpr -> BcPrepM StgExpr @@ -59,6 +59,7 @@ bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _) rhs) ReEntrant [] expr' + tick_ty ) letExp = StgLet noExtFieldSilent bnd (StgApp id []) pure letExp @@ -71,6 +72,7 @@ bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _) rhs) ReEntrant [voidArgId] expr' + tick_ty ) pure $ StgLet noExtFieldSilent bnd (StgApp id [StgVarArg realWorldPrimId]) bcPrepExpr (StgTick tick rhs) = @@ -110,10 +112,10 @@ bcPrepBind (StgRec bnds) = bcPrepSingleBind :: (Id, StgRhs) -> (Id, StgRhs) -- If necessary, modify this Id and body to protect not-necessarily-lifted join points. -- See Note [Not-necessarily-lifted join points], step 2. -bcPrepSingleBind (x, StgRhsClosure ext cc upd_flag args body) +bcPrepSingleBind (x, StgRhsClosure ext cc upd_flag args body typ) | isNNLJoinPoint x = ( protectNNLJoinPointId x - , StgRhsClosure ext cc upd_flag (args ++ [voidArgId]) body) + , StgRhsClosure ext cc upd_flag (args ++ [voidArgId]) body typ) bcPrepSingleBind bnd = bnd bcPrepTopLvl :: StgTopBinding -> BcPrepM StgTopBinding ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -319,11 +319,11 @@ stgCseTopLvl in_scope (StgTopLifted (StgRec eqs)) where in_scope' = in_scope `extendInScopeSetList` [ bndr | (bndr, _) <- eqs ] stgCseTopLvlRhs :: InScopeSet -> InStgRhs -> OutStgRhs -stgCseTopLvlRhs in_scope (StgRhsClosure ext ccs upd args body) +stgCseTopLvlRhs in_scope (StgRhsClosure ext ccs upd args body typ) = let body' = stgCseExpr (initEnv in_scope) body - in StgRhsClosure ext ccs upd args body' -stgCseTopLvlRhs _ (StgRhsCon ccs dataCon mu ticks args) - = StgRhsCon ccs dataCon mu ticks args + in StgRhsClosure ext ccs upd args body' typ +stgCseTopLvlRhs _ (StgRhsCon ccs dataCon mu ticks args typ) + = StgRhsCon ccs dataCon mu ticks args typ ------------------------------ -- The actual AST traversal -- @@ -427,7 +427,7 @@ stgCsePairs env0 ((b,e):pairs) -- The RHS of a binding. -- If it is a constructor application, either short-cut it or extend the environment stgCseRhs :: CseEnv -> OutId -> InStgRhs -> (Maybe (OutId, OutStgRhs), CseEnv) -stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args) +stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args typ) | Just other_bndr <- envLookup dataCon args' env , not (isWeakLoopBreaker (idOccInfo bndr)) -- See Note [Care with loop breakers] = let env' = addSubst bndr other_bndr env @@ -435,15 +435,15 @@ stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args) | otherwise = let env' = addDataCon bndr dataCon args' env -- see Note [Case 1: CSEing allocated closures] - pair = (bndr, StgRhsCon ccs dataCon mu ticks args') + pair = (bndr, StgRhsCon ccs dataCon mu ticks args' typ) in (Just pair, env') where args' = substArgs env args -stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) +stgCseRhs env bndr (StgRhsClosure ext ccs upd args body typ) = let (env1, args') = substBndrs env args env2 = forgetCse env1 -- See Note [Free variables of an StgClosure] body' = stgCseExpr env2 body - in (Just (substVar env bndr, StgRhsClosure ext ccs upd args' body'), env) + in (Just (substVar env bndr, StgRhsClosure ext ccs upd args' body' typ), env) mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr ===================================== compiler/GHC/Stg/Debug.hs ===================================== @@ -68,7 +68,7 @@ collectStgBind (StgRec pairs) = do return (StgRec es) collectStgRhs :: Id -> StgRhs -> M StgRhs -collectStgRhs bndr (StgRhsClosure ext cc us bs e)= do +collectStgRhs bndr (StgRhsClosure ext cc us bs e t) = do let name = idName bndr -- If the name has a span, use that initially as the source position in-case @@ -78,10 +78,10 @@ collectStgRhs bndr (StgRhsClosure ext cc us bs e)= do _ -> id e' <- with_span $ collectExpr e recordInfo bndr e' - return $ StgRhsClosure ext cc us bs e' -collectStgRhs _bndr (StgRhsCon cc dc _mn ticks args) = do + return $ StgRhsClosure ext cc us bs e' t +collectStgRhs _bndr (StgRhsCon cc dc _mn ticks args typ) = do n' <- numberDataCon dc ticks - return (StgRhsCon cc dc n' ticks args) + return (StgRhsCon cc dc n' ticks args typ) recordInfo :: Id -> StgExpr -> M () ===================================== compiler/GHC/Stg/FVs.hs ===================================== @@ -255,13 +255,13 @@ exprFVs env = go rhsFVs :: Env -> StgRhs -> (CgStgRhs, TopFVs, LocalFVs) -rhsFVs env (StgRhsClosure _ ccs uf bs body) +rhsFVs env (StgRhsClosure _ ccs uf bs body typ) | (body', top_fvs, lcl_fvs) <- exprFVs (addLocals bs env) body , let lcl_fvs' = delDVarSetList lcl_fvs bs - = (StgRhsClosure lcl_fvs' ccs uf bs body', top_fvs, lcl_fvs') -rhsFVs env (StgRhsCon ccs dc mu ts bs) + = (StgRhsClosure lcl_fvs' ccs uf bs body' typ, top_fvs, lcl_fvs') +rhsFVs env (StgRhsCon ccs dc mu ts bs typ) | (top_fvs, lcl_fvs) <- argsFVs env bs - = (StgRhsCon ccs dc mu ts bs, top_fvs, lcl_fvs) + = (StgRhsCon ccs dc mu ts bs typ, top_fvs, lcl_fvs) argsFVs :: Env -> [StgArg] -> (TopFVs, LocalFVs) argsFVs env = foldl' f (emptyVarSet, emptyDVarSet) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -481,7 +481,7 @@ inferTagBind in_env (StgRec pairs) initSig :: forall p. (Id, GenStgRhs p) -> TagSig -- Initial signature for the fixpoint loop initSig (_bndr, StgRhsCon {}) = TagSig TagTagged -initSig (bndr, StgRhsClosure _ _ _ _ _) = +initSig (bndr, StgRhsClosure _ _ _ _ _ _) = fromMaybe defaultSig (idTagSig_maybe bndr) where defaultSig = (TagSig TagTagged) @@ -516,13 +516,13 @@ inferTagRhs :: forall p. -> TagEnv p -- ^ -> GenStgRhs p -- ^ -> (TagSig, GenStgRhs 'InferTaggedBinders) -inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body) +inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body typ) | isDeadEndId bnd_id && (notNull) bndrs -- See Note [Bottom functions are TagTagged] - = (TagSig TagTagged, StgRhsClosure ext cc upd out_bndrs body') + = (TagSig TagTagged, StgRhsClosure ext cc upd out_bndrs body' typ) | otherwise = --pprTrace "inferTagRhsClosure" (ppr (_top, _grp_ids, env,info')) $ - (TagSig info', StgRhsClosure ext cc upd out_bndrs body') + (TagSig info', StgRhsClosure ext cc upd out_bndrs body' typ) where out_bndrs | Just marks <- idCbvMarks_maybe bnd_id @@ -553,11 +553,11 @@ inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body) | otherwise -> TagDunno in (id, TagSig tag) -inferTagRhs _ env _rhs@(StgRhsCon cc con cn ticks args) +inferTagRhs _ env _rhs@(StgRhsCon cc con cn ticks args typ) -- Constructors, which have untagged arguments to strict fields -- become thunks. We encode this by giving changing RhsCon nodes the info TagDunno = --pprTrace "inferTagRhsCon" (ppr grp_ids) $ - (TagSig (inferConTag env con args), StgRhsCon cc con cn ticks args) + (TagSig (inferConTag env con args), StgRhsCon cc con cn ticks args typ) -- Adjust let semantics to the targeted backend. -- See Note [Tag inference for interpreted code] ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -1,4 +1,4 @@ --- + -- Copyright (c) 2019 Andreas Klebinger -- @@ -343,7 +343,7 @@ rewriteBinds top_flag b@(StgRec binds) = -- Rewrite a RHS rewriteRhs :: (Id,TagSig) -> InferStgRhs -> RM (TgStgRhs) -rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs_ #-} do +rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args typ) = {-# SCC rewriteRhs_ #-} do -- pprTraceM "rewriteRhs" (ppr _id) -- Look up the nodes representing the constructor arguments. @@ -359,7 +359,7 @@ rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs let evalArgs = [v | StgVarArg v <- needsEval] :: [Id] if (null evalArgs) - then return $! (StgRhsCon ccs con cn ticks args) + then return $! (StgRhsCon ccs con cn ticks args typ) else do --assert not (isTaggedSig tagSig) -- pprTraceM "CreatingSeqs for " $ ppr _id <+> ppr node_id @@ -373,11 +373,11 @@ rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs fvs <- fvArgs args -- lcls <- getFVs -- pprTraceM "RhsClosureConversion" (ppr (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) $$ text "lcls:" <> ppr lcls) - return $! (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) -rewriteRhs _binding (StgRhsClosure fvs ccs flag args body) = do + return $! (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) typ +rewriteRhs _binding (StgRhsClosure fvs ccs flag args body typ) = do withBinders NotTopLevel args $ withClosureLcls fvs $ - StgRhsClosure fvs ccs flag (map fst args) <$> rewriteExpr body + StgRhsClosure fvs ccs flag (map fst args) <$> rewriteExpr body <*> pure typ -- return (closure) fvArgs :: [StgArg] -> RM DVarSet ===================================== compiler/GHC/Stg/Lift.hs ===================================== @@ -198,20 +198,20 @@ liftRhs -- as lambda binders, discarding all free vars. -> LlStgRhs -> LiftM OutStgRhs -liftRhs mb_former_fvs rhs@(StgRhsCon ccs con mn ts args) +liftRhs mb_former_fvs rhs@(StgRhsCon ccs con mn ts args typ) = assertPpr (isNothing mb_former_fvs) (text "Should never lift a constructor" $$ pprStgRhs panicStgPprOpts rhs) $ - StgRhsCon ccs con mn ts <$> traverse liftArgs args -liftRhs Nothing (StgRhsClosure _ ccs upd infos body) = + StgRhsCon ccs con mn ts <$> traverse liftArgs args <*> pure typ +liftRhs Nothing (StgRhsClosure _ ccs upd infos body typ) = -- This RHS wasn't lifted. withSubstBndrs (map binderInfoBndr infos) $ \bndrs' -> - StgRhsClosure noExtFieldSilent ccs upd bndrs' <$> liftExpr body -liftRhs (Just former_fvs) (StgRhsClosure _ ccs upd infos body) = + StgRhsClosure noExtFieldSilent ccs upd bndrs' <$> liftExpr body <*> pure typ +liftRhs (Just former_fvs) (StgRhsClosure _ ccs upd infos body typ) = -- This RHS was lifted. Insert extra binders for @former_fvs at . withSubstBndrs (map binderInfoBndr infos) $ \bndrs' -> do let bndrs'' = dVarSetElems former_fvs ++ bndrs' - StgRhsClosure noExtFieldSilent ccs upd bndrs'' <$> liftExpr body + StgRhsClosure noExtFieldSilent ccs upd bndrs'' <$> liftExpr body <*> pure typ liftArgs :: InStgArg -> LiftM OutStgArg liftArgs a@(StgLitArg _) = pure a ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -241,10 +241,10 @@ tagSkeletonBinding is_lne body_skel body_arg_occs (StgRec pairs) bndr' = BindsClosure bndr (bndr `elemVarSet` scope_occs) tagSkeletonRhs :: Id -> CgStgRhs -> (Skeleton, IdSet, LlStgRhs) -tagSkeletonRhs _ (StgRhsCon ccs dc mn ts args) - = (NilSk, mkArgOccs args, StgRhsCon ccs dc mn ts args) -tagSkeletonRhs bndr (StgRhsClosure fvs ccs upd bndrs body) - = (rhs_skel, body_arg_occs, StgRhsClosure fvs ccs upd bndrs' body') +tagSkeletonRhs _ (StgRhsCon ccs dc mn ts args typ) + = (NilSk, mkArgOccs args, StgRhsCon ccs dc mn ts args typ) +tagSkeletonRhs bndr (StgRhsClosure fvs ccs upd bndrs body typ) + = (rhs_skel, body_arg_occs, StgRhsClosure fvs ccs upd bndrs' body' typ) where bndrs' = map BoringBinder bndrs (body_skel, body_arg_occs, body') = tagSkeletonExpr body @@ -330,7 +330,7 @@ goodToLift cfg top_lvl rec_flag expander pairs scope = decide -- We don't lift updatable thunks or constructors any_memoized = any is_memoized_rhs rhss is_memoized_rhs StgRhsCon{} = True - is_memoized_rhs (StgRhsClosure _ _ upd _ _) = isUpdatable upd + is_memoized_rhs (StgRhsClosure _ _ upd _ _ _) = isUpdatable upd -- Don't lift binders occurring as arguments. This would result in complex -- argument expressions which would have to be given a name, reintroducing @@ -399,7 +399,7 @@ goodToLift cfg top_lvl rec_flag expander pairs scope = decide rhsLambdaBndrs :: LlStgRhs -> [Id] rhsLambdaBndrs StgRhsCon{} = [] -rhsLambdaBndrs (StgRhsClosure _ _ _ bndrs _) = map binderInfoBndr bndrs +rhsLambdaBndrs (StgRhsClosure _ _ _ bndrs _ _) = map binderInfoBndr bndrs -- | The size in words of a function closure closing over the given 'Id's, -- including the header. ===================================== compiler/GHC/Stg/Lift/Monad.hs ===================================== @@ -197,12 +197,12 @@ collectFloats = go (0 :: Int) [] -- | Omitting this makes for strange closure allocation schemes that crash the -- GC. removeRhsCCCS :: GenStgRhs pass -> GenStgRhs pass -removeRhsCCCS (StgRhsClosure ext ccs upd bndrs body) +removeRhsCCCS (StgRhsClosure ext ccs upd bndrs body typ) | isCurrentCCS ccs - = StgRhsClosure ext dontCareCCS upd bndrs body -removeRhsCCCS (StgRhsCon ccs con mu ts args) + = StgRhsClosure ext dontCareCCS upd bndrs body typ +removeRhsCCCS (StgRhsCon ccs con mu ts args typ) | isCurrentCCS ccs - = StgRhsCon dontCareCCS con mu ts args + = StgRhsCon dontCareCCS con mu ts args typ removeRhsCCCS rhs = rhs -- | The analysis monad consists of the following 'RWST' components: ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -222,25 +222,25 @@ checkNoCurrentCCS rhs = do opts <- getStgPprOpts let rhs' = pprStgRhs opts rhs case rhs of - StgRhsClosure _ ccs _ _ _ + StgRhsClosure _ ccs _ _ _ _ | isCurrentCCS ccs -> addErrL (text "Top-level StgRhsClosure with CurrentCCS" $$ rhs') - StgRhsCon ccs _ _ _ _ + StgRhsCon ccs _ _ _ _ _ | isCurrentCCS ccs -> addErrL (text "Top-level StgRhsCon with CurrentCCS" $$ rhs') _ -> return () lintStgRhs :: (OutputablePass a, BinderP a ~ Id) => GenStgRhs a -> LintM () -lintStgRhs (StgRhsClosure _ _ _ [] expr) +lintStgRhs (StgRhsClosure _ _ _ [] expr _) = lintStgExpr expr -lintStgRhs (StgRhsClosure _ _ _ binders expr) +lintStgRhs (StgRhsClosure _ _ _ binders expr _) = addLoc (LambdaBodyOf binders) $ addInScopeVars binders $ lintStgExpr expr -lintStgRhs rhs@(StgRhsCon _ con _ _ args) = do +lintStgRhs rhs@(StgRhsCon _ con _ _ args _) = do opts <- getStgPprOpts when (isUnboxedTupleDataCon con || isUnboxedSumDataCon con) $ do addErrL (text "StgRhsCon is an unboxed tuple or sum application" $$ ===================================== compiler/GHC/Stg/Stats.hs ===================================== @@ -122,10 +122,10 @@ statBinding top (StgRec pairs) statRhs :: Bool -> (Id, StgRhs) -> StatEnv -statRhs top (_, StgRhsCon _ _ _ _ _) +statRhs top (_, StgRhsCon _ _ _ _ _ _) = countOne (ConstructorBinds top) -statRhs top (_, StgRhsClosure _ _ u _ body) +statRhs top (_, StgRhsClosure _ _ u _ body _) = statExpr body `combineSE` countOne ( case u of ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -393,6 +393,7 @@ data GenStgRhs pass [BinderP pass] -- ^ arguments; if empty, then not a function; -- as above, order is important. (GenStgExpr pass) -- ^ body + Type -- ^ result type {- An example may be in order. Consider: @@ -422,6 +423,7 @@ important): ConstructorNumber [StgTickish] [StgArg] -- Args + Type -- Type, for rewriting to an StgRhsClosure -- | Like 'GHC.Hs.Extension.NoExtField', but with an 'Outputable' instance that -- returns 'empty'. @@ -439,14 +441,14 @@ noExtFieldSilent = NoExtFieldSilent -- implications on build time... stgRhsArity :: StgRhs -> Int -stgRhsArity (StgRhsClosure _ _ _ bndrs _) +stgRhsArity (StgRhsClosure _ _ _ bndrs _ _) = assert (all isId bndrs) $ length bndrs -- The arity never includes type parameters, but they should have gone by now stgRhsArity (StgRhsCon {}) = 0 freeVarsOfRhs :: (XRhsClosure pass ~ DIdSet) => GenStgRhs pass -> DIdSet -freeVarsOfRhs (StgRhsCon _ _ _ _ args) = mkDVarSet [ id | StgVarArg id <- args ] -freeVarsOfRhs (StgRhsClosure fvs _ _ _ _) = fvs +freeVarsOfRhs (StgRhsCon _ _ _ _ args _) = mkDVarSet [ id | StgVarArg id <- args ] +freeVarsOfRhs (StgRhsClosure fvs _ _ _ _ _) = fvs {- ************************************************************************ @@ -892,14 +894,14 @@ instance Outputable AltType where pprStgRhs :: OutputablePass pass => StgPprOpts -> GenStgRhs pass -> SDoc pprStgRhs opts rhs = case rhs of - StgRhsClosure ext cc upd_flag args body + StgRhsClosure ext cc upd_flag args body _ -> hang (hsep [ if stgSccEnabled opts then ppr cc else empty , ppUnlessOption sdocSuppressStgExts (ppr ext) , char '\\' <> ppr upd_flag, brackets (interppSP args) ]) 4 (pprStgExpr opts body) - StgRhsCon cc con mid _ticks args + StgRhsCon cc con mid _ticks args _ -> hcat [ if stgSccEnabled opts then ppr cc <> space else empty , case mid of NoNumber -> empty ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -483,14 +483,14 @@ unariseBinding rho (StgRec xrhss) = StgRec <$> mapM (\(x, rhs) -> (x,) <$> unariseRhs rho rhs) xrhss unariseRhs :: UnariseEnv -> StgRhs -> UniqSM StgRhs -unariseRhs rho (StgRhsClosure ext ccs update_flag args expr) +unariseRhs rho (StgRhsClosure ext ccs update_flag args expr typ) = do (rho', args1) <- unariseFunArgBinders rho args expr' <- unariseExpr rho' expr - return (StgRhsClosure ext ccs update_flag args1 expr') + return (StgRhsClosure ext ccs update_flag args1 expr' typ) -unariseRhs rho (StgRhsCon ccs con mu ts args) +unariseRhs rho (StgRhsCon ccs con mu ts args typ) = assert (not (isUnboxedTupleDataCon con || isUnboxedSumDataCon con)) - return (StgRhsCon ccs con mu ts (unariseConArgs rho args)) + return (StgRhsCon ccs con mu ts (unariseConArgs rho args) typ) -------------------------------------------------------------------------------- ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -350,8 +350,8 @@ schemeR fvs (nm, rhs) -- underlying expression collect :: CgStgRhs -> ([Var], CgStgExpr) -collect (StgRhsClosure _ _ _ args body) = (args, body) -collect (StgRhsCon _cc dc cnum _ticks args) = ([], StgConApp dc cnum args []) +collect (StgRhsClosure _ _ _ args body _) = (args, body) +collect (StgRhsCon _cc dc cnum _ticks args _typ) = ([], StgConApp dc cnum args []) schemeR_wrk :: [Id] @@ -534,7 +534,7 @@ schemeE d s p e@(StgOpApp {}) = schemeT d s p e schemeE d s p (StgLetNoEscape xlet bnd body) = schemeE d s p (StgLet xlet bnd body) schemeE d s p (StgLet _xlet - (StgNonRec x (StgRhsCon _cc data_con _cnum _ticks args)) + (StgNonRec x (StgRhsCon _cc data_con _cnum _ticks args _typ)) body) = do -- Special case for a non-recursive let whose RHS is a -- saturated constructor application. ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -199,12 +199,12 @@ cgTopBinding logger tmpfs cfg = \case cgTopRhs :: StgToCmmConfig -> RecFlag -> Id -> CgStgRhs -> (CgIdInfo, FCode ()) -- The Id is passed along for setting up a binding... -cgTopRhs cfg _rec bndr (StgRhsCon _cc con mn _ts args) +cgTopRhs cfg _rec bndr (StgRhsCon _cc con mn _ts args _typ) = cgTopRhsCon cfg bndr con mn (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise -cgTopRhs cfg rec bndr (StgRhsClosure fvs cc upd_flag args body) +cgTopRhs cfg rec bndr (StgRhsClosure fvs cc upd_flag args body _typ) = assertPpr (isEmptyDVarSet fvs) (text "fvs:" <> ppr fvs) $ -- There should be no free variables cgTopRhsClosure (stgToCmmPlatform cfg) rec bndr cc upd_flag args body ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -250,14 +250,14 @@ cgRhs :: Id -- (see above) ) -cgRhs id (StgRhsCon cc con mn _ts args) +cgRhs id (StgRhsCon cc con mn _ts args _typ) = withNewTickyCounterCon id con mn $ buildDynCon id mn True cc con (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise {- See Note [GC recovery] in "GHC.StgToCmm.Closure" -} -cgRhs id (StgRhsClosure fvs cc upd_flag args body) +cgRhs id (StgRhsClosure fvs cc upd_flag args body _typ) = do profile <- getProfile check_tags <- stgToCmmDoTagCheck <$> getStgToCmmConfig ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -200,9 +200,9 @@ cgLetNoEscapeRhsBody -> Id -> CgStgRhs -> FCode (CgIdInfo, FCode ()) -cgLetNoEscapeRhsBody local_cc bndr (StgRhsClosure _ cc _upd args body) +cgLetNoEscapeRhsBody local_cc bndr (StgRhsClosure _ cc _upd args body _typ) = cgLetNoEscapeClosure bndr local_cc cc (nonVoidIds args) body -cgLetNoEscapeRhsBody local_cc bndr (StgRhsCon cc con mn _ts args) +cgLetNoEscapeRhsBody local_cc bndr (StgRhsCon cc con mn _ts args _typ) = cgLetNoEscapeClosure bndr local_cc cc [] (StgConApp con mn args (pprPanic "cgLetNoEscapeRhsBody" $ text "StgRhsCon doesn't have type args")) ===================================== compiler/GHC/StgToJS/CodeGen.hs ===================================== @@ -290,10 +290,10 @@ genToplevelDecl i rhs = do genToplevelConEntry :: Id -> CgStgRhs -> G JStat genToplevelConEntry i rhs = case rhs of - StgRhsCon _cc con _mu _ts _args + StgRhsCon _cc con _mu _ts _args _typ | isDataConWorkId i -> genSetConInfo i con (stgRhsLive rhs) -- NoSRT - StgRhsClosure _ _cc _upd_flag _args _body + StgRhsClosure _ _cc _upd_flag _args _body _typ | Just dc <- isDataConWorkId_maybe i -> genSetConInfo i dc (stgRhsLive rhs) -- srt _ -> pure mempty @@ -321,11 +321,11 @@ mkDataEntry = ValExpr $ JFunc [] returnStack genToplevelRhs :: Id -> CgStgRhs -> G JStat -- general cases: genToplevelRhs i rhs = case rhs of - StgRhsCon cc con _mu _tys args -> do + StgRhsCon cc con _mu _tys args _typ -> do ii <- identForId i allocConStatic ii cc con args return mempty - StgRhsClosure _ext cc _upd_flag {- srt -} args body -> do + StgRhsClosure _ext cc _upd_flag {- srt -} args body typ -> do {- algorithm: - collect all Id refs that are in the global id cache @@ -335,7 +335,7 @@ genToplevelRhs i rhs = case rhs of -} eid@(TxtI eidt) <- identForEntryId i (TxtI idt) <- identForId i - body <- genBody (initExprCtx i) i R2 args body + body <- genBody (initExprCtx i) R2 args body typ global_occs <- globalOccs (jsSaturate (Just "ghcjs_tmp_sat_") body) let lidents = map global_ident global_occs let lids = map global_id global_occs ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -74,7 +74,6 @@ import GHC.Core.Type hiding (typeSize) import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import GHC.Utils.Outputable (ppr, renderWithContext, defaultSDocContext) import qualified Control.Monad.Trans.State.Strict as State import GHC.Data.FastString @@ -148,7 +147,7 @@ genBind ctx bndr = ctx' = ctxClearLneFrame ctx assign :: Id -> CgStgRhs -> G (Maybe JStat) - assign b (StgRhsClosure _ _ccs {-[the_fv]-} _upd [] expr) + assign b (StgRhsClosure _ _ccs {-[the_fv]-} _upd [] expr _typ) | let strip = snd . stripStgTicksTop (not . tickishIsCode) , StgCase (StgApp scrutinee []) _ (AlgAlt _) [GenStgAlt (DataAlt _) params sel_expr] <- strip expr , StgApp selectee [] <- strip sel_expr @@ -168,7 +167,7 @@ genBind ctx bndr = ([tgt], [the_fvj]) -> return $ Just (tgt ||= ApplExpr (var ("h$c_sel_" <> mkFastString sel_tag)) [the_fvj]) _ -> panic "genBind.assign: invalid size" - assign b (StgRhsClosure _ext _ccs _upd [] expr) + assign b (StgRhsClosure _ext _ccs _upd [] expr _typ) | snd (isInlineExpr (ctxEvaluatedIds ctx) expr) = do d <- declVarsForId b tgt <- varsForId b @@ -180,9 +179,9 @@ genBind ctx bndr = addEvalRhs c [] = c addEvalRhs c ((b,r):xs) - | StgRhsCon{} <- r = addEvalRhs (ctxAssertEvaluated b c) xs - | (StgRhsClosure _ _ ReEntrant _ _) <- r = addEvalRhs (ctxAssertEvaluated b c) xs - | otherwise = addEvalRhs c xs + | StgRhsCon{} <- r = addEvalRhs (ctxAssertEvaluated b c) xs + | (StgRhsClosure _ _ ReEntrant _ _ _) <- r = addEvalRhs (ctxAssertEvaluated b c) xs + | otherwise = addEvalRhs c xs genBindLne :: HasDebugCallStack => ExprCtx @@ -223,7 +222,7 @@ genBindLne ctx bndr = do -- is initially set to null, changed to h$blackhole when the thunk is being evaluated. -- genEntryLne :: HasDebugCallStack => ExprCtx -> Id -> CgStgRhs -> G () -genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = +genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body typ) = resetSlots $ do let payloadSize = ctxLneFrameSize ctx vars = ctxLneFrameVars ctx @@ -238,7 +237,7 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = ]) | otherwise = mempty lvs <- popLneFrame True payloadSize ctx - body <- genBody ctx i R1 args body + body <- genBody ctx R1 args body typ ei@(TxtI eii) <- identForEntryId i sr <- genStaticRefsRhs rhs let f = JFunc [] (bh <> lvs <> body) @@ -251,7 +250,7 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = CIStackFrame sr emitToplevel (ei ||= toJExpr f) -genEntryLne ctx i (StgRhsCon cc con _mu _ticks args) = resetSlots $ do +genEntryLne ctx i (StgRhsCon cc con _mu _ticks args _typ) = resetSlots $ do let payloadSize = ctxLneFrameSize ctx ei@(TxtI _eii) <- identForEntryId i -- di <- varForDataConWorker con @@ -265,12 +264,12 @@ genEntryLne ctx i (StgRhsCon cc con _mu _ticks args) = resetSlots $ do -- | Generate the entry function for a local closure genEntry :: HasDebugCallStack => ExprCtx -> Id -> CgStgRhs -> G () genEntry _ _i StgRhsCon {} = return () -genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body) = resetSlots $ do +genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body typ) = resetSlots $ do let live = stgLneLiveExpr rhs -- error "fixme" -- probably find live vars in body ll <- loadLiveFun live llv <- verifyRuntimeReps live upd <- genUpdFrame upd_flag i - body <- genBody entryCtx i R2 args body + body <- genBody entryCtx R2 args body typ ei@(TxtI eii) <- identForEntryId i et <- genEntryType args setcc <- ifProfiling $ @@ -302,12 +301,12 @@ genEntryType args0 = do -- | Generate the body of an object genBody :: HasDebugCallStack => ExprCtx - -> Id -> StgReg -> [Id] -> CgStgExpr + -> Type -> G JStat -genBody ctx i startReg args e = do +genBody ctx startReg args e typ = do -- load arguments into local variables la <- do args' <- concatMapM genIdArgI args @@ -318,7 +317,7 @@ genBody ctx i startReg args e = do -- compute PrimReps and their number of slots required to return the result of -- i applied to args. - let res_vars = resultSize args i + let res_vars = resultSize typ -- compute typed expressions for each slot and assign registers let go_var regs = \case @@ -359,22 +358,12 @@ genBody ctx i startReg args e = do -- In case of failure to determine the type, we default to LiftedRep as it's -- probably what it is. -- -resultSize :: HasDebugCallStack => [Id] -> Id -> [(PrimRep, Int)] -resultSize args i = result +resultSize :: HasDebugCallStack => Type -> [(PrimRep, Int)] +resultSize ty = result where result = result_reps `zip` result_slots result_slots = fmap (slotCount . primRepSize) result_reps - result_reps = trim_args (unwrapType (idType i)) (length args) - - trim_args t 0 = typePrimRep t - trim_args t n - | Just (_af, _mult, arg, res) <- splitFunTy_maybe t - , nargs <- length (typePrimRepArgs arg) - , assert (n >= nargs) True - = trim_args (unwrapType res) (n - nargs) - | otherwise - = pprTrace "result_type: not a function type, assume LiftedRep" (ppr t) - [LiftedRep] + result_reps = typePrimRep ty -- | Ensure that the set of identifiers has valid 'RuntimeRep's. This function -- returns a no-op when 'csRuntimeAssert' in 'StgToJSConfig' is False. @@ -540,19 +529,19 @@ allocCls dynMiddle xs = do toCl (i, StgRhsCon cc con []) = do ii <- identForId i Left <$> (return (decl ii) <> allocCon ii con cc []) -} - toCl (i, StgRhsCon cc con _mui _ticjs [a]) | isUnboxableCon con = do + toCl (i, StgRhsCon cc con _mui _ticjs [a] _typ) | isUnboxableCon con = do ii <- identForId i ac <- allocCon ii con cc =<< genArg a pure (Left (decl ii <> ac)) -- dynamics - toCl (i, StgRhsCon cc con _mu _ticks ar) = + toCl (i, StgRhsCon cc con _mu _ticks ar _typ) = -- fixme do we need to handle unboxed? Right <$> ((,,,) <$> identForId i <*> varForDataConWorker con <*> concatMapM genArg ar <*> pure cc) - toCl (i, cl@(StgRhsClosure _ext cc _upd_flag _args _body)) = + toCl (i, cl@(StgRhsClosure _ext cc _upd_flag _args _body _typ)) = let live = stgLneLiveExpr cl in Right <$> ((,,,) <$> identForId i <*> varForEntryId i ===================================== compiler/GHC/StgToJS/Sinker.hs ===================================== @@ -64,11 +64,11 @@ sinkPgm' m pgm = alwaysSinkable :: CgStgBinding -> [(Id, CgStgExpr)] alwaysSinkable (StgRec {}) = [] alwaysSinkable (StgNonRec b rhs) = case rhs of - StgRhsClosure _ _ _ _ e@(StgLit l) + StgRhsClosure _ _ _ _ e@(StgLit l) _ | isSmallSinkableLit l , isLocal b -> [(b,e)] - StgRhsCon _ccs dc cnum _ticks as@[StgLitArg l] + StgRhsCon _ccs dc cnum _ticks as@[StgLitArg l] _typ | isSmallSinkableLit l , isLocal b , isUnboxableCon dc @@ -88,9 +88,9 @@ onceSinkable _m (StgNonRec b rhs) , isLocal b = [(b,e)] where getSinkable = \case - StgRhsCon _ccs dc cnum _ticks args -> Just (StgConApp dc cnum args []) - StgRhsClosure _ _ _ _ e@(StgLit{}) -> Just e - _ -> Nothing + StgRhsCon _ccs dc cnum _ticks args _typ -> Just (StgConApp dc cnum args []) + StgRhsClosure _ _ _ _ e@(StgLit{}) _typ -> Just e + _ -> Nothing onceSinkable _ _ = [] -- | collect all idents used only once in an argument at the top level @@ -115,8 +115,8 @@ collectArgsTop = \case collectArgsTopRhs :: CgStgRhs -> [Id] collectArgsTopRhs = \case - StgRhsCon _ccs _dc _mu _ticks args -> concatMap collectArgsA args - StgRhsClosure {} -> [] + StgRhsCon _ccs _dc _mu _ticks args _typ -> concatMap collectArgsA args + StgRhsClosure {} -> [] -- | fold over all Id in StgArg in the AST collectArgs :: CgStgBinding -> [Id] @@ -126,8 +126,8 @@ collectArgs = \case collectArgsR :: CgStgRhs -> [Id] collectArgsR = \case - StgRhsClosure _x0 _x1 _x2 _x3 e -> collectArgsE e - StgRhsCon _ccs _con _mu _ticks args -> concatMap collectArgsA args + StgRhsClosure _x0 _x1 _x2 _x3 e _typ -> collectArgsE e + StgRhsCon _ccs _con _mu _ticks args _typ -> concatMap collectArgsA args collectArgsAlt :: CgStgAlt -> [Id] collectArgsAlt alt = collectArgsE (alt_rhs alt) @@ -171,7 +171,7 @@ topSortDecls _m binds = rest ++ nr' keys = mkUniqSet (map node_key vs) getV e@(StgNonRec b _) = DigraphNode e b [] getV _ = error "topSortDecls: getV, unexpected binding" - collectDeps (StgNonRec b (StgRhsCon _cc _dc _cnum _ticks args)) = + collectDeps (StgNonRec b (StgRhsCon _cc _dc _cnum _ticks args _typ)) = [ (i, b) | StgVarArg i <- args, i `elementOfUniqSet` keys ] collectDeps _ = [] g = graphFromVerticesAndAdjacency vs (concatMap collectDeps nr) ===================================== compiler/GHC/StgToJS/StgUtils.hs ===================================== @@ -67,8 +67,8 @@ bindingRefs u = \case rhsRefs :: UniqFM Id CgStgExpr -> CgStgRhs -> Set Id rhsRefs u = \case - StgRhsClosure _ _ _ _ body -> exprRefs u body - StgRhsCon _ccs d _mu _ticks args -> l s [ i | AnId i <- dataConImplicitTyThings d] <> l (argRefs u) args + StgRhsClosure _ _ _ _ body _ -> exprRefs u body + StgRhsCon _ccs d _mu _ticks args _ -> l s [ i | AnId i <- dataConImplicitTyThings d] <> l (argRefs u) args exprRefs :: UniqFM Id CgStgExpr -> CgStgExpr -> Set Id exprRefs u = \case @@ -97,7 +97,7 @@ hasExport bnd = StgNonRec b e -> isExportedBind b e StgRec bs -> any (uncurry isExportedBind) bs where - isExportedBind _i (StgRhsCon _cc con _ _ _) = + isExportedBind _i (StgRhsCon _cc con _ _ _ _) = getUnique con == staticPtrDataConKey isExportedBind _ _ = False @@ -152,8 +152,8 @@ stgBindRhsLive b = stgRhsLive :: CgStgRhs -> LiveVars stgRhsLive = \case - StgRhsClosure _ _ _ args e -> delDVarSetList (stgExprLive True e) args - StgRhsCon _ _ _ _ args -> unionDVarSets (map stgArgLive args) + StgRhsClosure _ _ _ args e _ -> delDVarSetList (stgExprLive True e) args + StgRhsCon _ _ _ _ args _ -> unionDVarSets (map stgArgLive args) stgArgLive :: StgArg -> LiveVars stgArgLive = \case @@ -189,8 +189,8 @@ bindees = \case StgRec bs -> map fst bs isUpdatableRhs :: CgStgRhs -> Bool -isUpdatableRhs (StgRhsClosure _ _ u _ _) = isUpdatable u -isUpdatableRhs _ = False +isUpdatableRhs (StgRhsClosure _ _ u _ _ _) = isUpdatable u +isUpdatableRhs _ = False stgLneLive' :: CgStgBinding -> [Id] stgLneLive' b = filter (`notElem` bindees b) (stgLneLive b) @@ -241,9 +241,9 @@ inspectInlineBinding v = \case inspectInlineRhs :: UniqSet Id -> Id -> CgStgRhs -> UniqSet Id inspectInlineRhs v i = \case - StgRhsCon{} -> addOneToUniqSet v i - StgRhsClosure _ _ ReEntrant _ _ -> addOneToUniqSet v i - _ -> v + StgRhsCon{} -> addOneToUniqSet v i + StgRhsClosure _ _ ReEntrant _ _ _ -> addOneToUniqSet v i + _ -> v isInlineForeignCall :: ForeignCall -> Bool isInlineForeignCall (CCall (CCallSpec _ cconv safety)) = ===================================== testsuite/tests/dependent/should_compile/all.T ===================================== @@ -40,7 +40,7 @@ test('T13938', [req_th, extra_files(['T13938a.hs'])], makefile_test, ['T13938']) test('T14556', normal, compile, ['']) test('T14720', normal, compile, ['']) test('T14066a', normal, compile, ['']) -test('T14749', js_broken(22364), compile, ['']) +test('T14749', normal, compile, ['']) test('T14991', normal, compile, ['']) test('DkNameRes', normal, compile, ['']) test('T15346', normal, compile, ['']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', js_broken(22576), compile, ['']) +test('RepPolyWrappedVar2', normal, compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -587,7 +587,7 @@ test('T13651a', normal, compile, ['']) test('T13680', normal, compile, ['']) test('T13785', normal, compile, ['']) test('T13804', normal, compile, ['']) -test('T13822', js_broken(22364), compile, ['']) +test('T13822', normal, compile, ['']) test('T13848', normal, compile, ['']) test('T13879', normal, compile, ['']) test('T13881', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_run/all.T ===================================== @@ -126,7 +126,7 @@ test('KindInvariant', normal, ghci_script, ['KindInvariant.script']) # unboxed sums and ghci does not support those yet. test('StrictPats', omit_ways(['ghci']), compile_and_run, ['']) test('T12809', omit_ways(['ghci']), compile_and_run, ['']) -test('EtaExpandLevPoly', [omit_ways(['ghci']), js_broken(22576)], compile_and_run, ['']) +test('EtaExpandLevPoly', [omit_ways(['ghci'])], compile_and_run, ['']) test('TestTypeableBinary', normal, compile_and_run, ['']) test('Typeable1', normal, compile_fail, ['-Werror']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49fc7a856eb6070085da4d368045be16a9017a4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49fc7a856eb6070085da4d368045be16a9017a4b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 10:35:24 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 06:35:24 -0400 Subject: [Git][ghc/ghc][wip/js-stgrhsclosure] 3 commits: JS: Fix h$base_access implementation (issue 22576) Message-ID: <6448fe6c981a2_178e74d8e1fd881585343@gitlab.mail> Josh Meredith pushed to branch wip/js-stgrhsclosure at Glasgow Haskell Compiler / GHC Commits: 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - eba7b247 by Josh Meredith at 2023-04-26T10:35:06+00:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 30 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Sinker.hs - compiler/GHC/StgToJS/StgUtils.hs - docs/users_guide/exts/implicit_parameters.rst - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/jsbits/base.js - testsuite/tests/ado/all.T - testsuite/tests/dependent/should_compile/all.T - testsuite/tests/rep-poly/all.T - + testsuite/tests/simplCore/should_run/T23289.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/49fc7a856eb6070085da4d368045be16a9017a4b...eba7b247f31a420cae64d0ee87d7296bf434724e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/49fc7a856eb6070085da4d368045be16a9017a4b...eba7b247f31a420cae64d0ee87d7296bf434724e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 11:37:56 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 07:37:56 -0400 Subject: [Git][ghc/ghc][wip/romes/fix-docs] 297 commits: GHC proposal 496 - Nullary record wildcards Message-ID: <64490d14567f3_178e74da1ee29c16227b0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/fix-docs at Glasgow Haskell Compiler / GHC Commits: 172ff88f by Georgi Lyubenov at 2023-02-21T18:35:56-05:00 GHC proposal 496 - Nullary record wildcards This patch implements GHC proposal 496, which allows record wildcards to be used for nullary constructors, e.g. data A = MkA1 | MkA2 { fld1 :: Int } f :: A -> Int f (MkA1 {..}) = 0 f (MkA2 {..}) = fld1 To achieve this, we add arity information to the record field environment, so that we can accept a constructor which has no fields while continuing to reject non-record constructors with more than 1 field. See Note [Nullary constructors and empty record wildcards], as well as the more general overview in Note [Local constructor info in the renamer], both in the newly introduced GHC.Types.ConInfo module. Fixes #22161 - - - - - f70a0239 by sheaf at 2023-02-21T18:36:35-05:00 ghc-prim: levity-polymorphic array equality ops This patch changes the pointer-equality comparison operations in GHC.Prim.PtrEq to work with arrays of unlifted values, e.g. sameArray# :: forall {l} (a :: TYPE (BoxedRep l)). Array# a -> Array# a -> Int# Fixes #22976 - - - - - 9296660b by Andreas Klebinger at 2023-02-21T23:58:05-05:00 base: Correct @since annotation for FP<->Integral bit cast operations. Fixes #22708 - - - - - f11d9c27 by romes at 2023-02-21T23:58:42-05:00 fix: Update documentation links Closes #23008 Additionally batches some fixes to pointers to the Note [Wired-in units], and a typo in said note. - - - - - fb60339f by Bryan Richter at 2023-02-23T14:45:17+02:00 Propagate failure if unable to push notes - - - - - 8e170f86 by Alexis King at 2023-02-23T16:59:22-05:00 rts: Fix `prompt#` when profiling is enabled This commit also adds a new -Dk RTS option to the debug RTS to assist debugging continuation captures. Currently, the printed information is quite minimal, but more can be added in the future if it proves to be useful when debugging future issues. fixes #23001 - - - - - e9e7a00d by sheaf at 2023-02-23T17:00:01-05:00 Explicit migration timeline for loopy SC solving This patch updates the warning message introduced in commit 9fb4ca89bff9873e5f6a6849fa22a349c94deaae to specify an explicit migration timeline: GHC will no longer support this constraint solving mechanism starting from GHC 9.10. Fixes #22912 - - - - - 4eb9c234 by Sylvain Henry at 2023-02-24T17:27:45-05:00 JS: make some arithmetic primops faster (#22835) Don't use BigInt for wordAdd2, mulWord32, and timesInt32. Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - 92e76483 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump terminfo submodule to 0.4.1.6 - - - - - f229db14 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump unix submodule to 2.8.1.0 - - - - - 47bd48c1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump deepseq submodule to 1.4.8.1 - - - - - d2012594 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump directory submodule to 1.3.8.1 - - - - - df6f70d1 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump process submodule to v1.6.17.0 - - - - - 4c869e48 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump hsc2hs submodule to 0.68.8 - - - - - 81d96642 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump array submodule to 0.5.4.0 - - - - - 6361f771 by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump Cabal submodule to 3.9 pre-release - - - - - 4085fb6c by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump filepath submodule to 1.4.100.1 - - - - - 2bfad50f by Ben Gamari at 2023-02-24T17:28:20-05:00 Bump haskeline submodule to 0.8.2.1 - - - - - fdc89a8d by Ben Gamari at 2023-02-24T21:29:32-05:00 gitlab-ci: Run nix-build with -v0 This significantly cuts down on the amount of noise in the job log. Addresses #22861. - - - - - 69fb0b13 by Aaron Allen at 2023-02-24T21:30:10-05:00 Fix ParallelListComp out of scope suggestion This patch makes it so vars from one block of a parallel list comprehension are not in scope in a subsequent block during type checking. This was causing GHC to emit a faulty suggestion when an out of scope variable shared the occ name of a var from a different block. Fixes #22940 - - - - - ece092d0 by Simon Peyton Jones at 2023-02-24T21:30:45-05:00 Fix shadowing bug in prepareAlts As #23012 showed, GHC.Core.Opt.Simplify.Utils.prepareAlts was using an OutType to construct an InAlt. When shadowing is in play, this is outright wrong. See Note [Shadowing in prepareAlts]. - - - - - 7825fef9 by Sylvain Henry at 2023-02-24T21:31:25-05:00 JS: Store CI perf results (fix #22923) - - - - - b56025f4 by Gergő Érdi at 2023-02-27T13:34:22+00:00 Don't specialise incoherent instance applications Using incoherent instances, there can be situations where two occurrences of the same overloaded function at the same type use two different instances (see #22448). For incoherently resolved instances, we must mark them with `nospec` to avoid the specialiser rewriting one to the other. This marking is done during the desugaring of the `WpEvApp` wrapper. Fixes #22448 Metric Increase: T15304 - - - - - d0c7bbed by Tom Ellis at 2023-02-27T20:04:07-05:00 Fix SCC grouping example - - - - - f84a8cd4 by Bryan Richter at 2023-02-28T05:58:37-05:00 Mark setnumcapabilities001 fragile - - - - - 29a04d6e by Bryan Richter at 2023-02-28T05:58:37-05:00 Allow nightly-x86_64-linux-deb10-validate+thread_sanitizer to fail See #22520 - - - - - 9fa54572 by Cheng Shao at 2023-02-28T05:59:15-05:00 ghc-prim: fix hs_cmpxchg64 function prototype hs_cmpxchg64 must return a StgWord64, otherwise incorrect runtime results of 64-bit MO_Cmpxchg will appear in 32-bit unregisterised builds, which go unnoticed at compile-time due to C implicit casting in .hc files. - - - - - 0c200ab7 by Simon Peyton Jones at 2023-02-28T11:10:31-05:00 Account for local rules in specImports As #23024 showed, in GHC.Core.Opt.Specialise.specImports, we were generating specialisations (a locally-define function) for imported functions; and then generating specialisations for those locally-defined functions. The RULE for the latter should be attached to the local Id, not put in the rules-for-imported-ids set. Fix is easy; similar to what happens in GHC.HsToCore.addExportFlagsAndRules - - - - - 8b77f9bf by Sylvain Henry at 2023-02-28T11:11:21-05:00 JS: fix for overlap with copyMutableByteArray# (#23033) The code wasn't taking into account some kind of overlap. cgrun070 has been extended to test the missing case. - - - - - 239202a2 by Sylvain Henry at 2023-02-28T11:12:03-05:00 Testsuite: replace some js_skip with req_cmm req_cmm is more informative than js_skip - - - - - 7192ef91 by Simon Peyton Jones at 2023-02-28T18:54:59-05:00 Take more care with unlifted bindings in the specialiser As #22998 showed, we were floating an unlifted binding to top level, which breaks a Core invariant. The fix is easy, albeit a little bit conservative. See Note [Care with unlifted bindings] in GHC.Core.Opt.Specialise - - - - - bb500e2a by Simon Peyton Jones at 2023-02-28T18:55:35-05:00 Account for TYPE vs CONSTRAINT in mkSelCo As #23018 showed, in mkRuntimeRepCo we need to account for coercions between TYPE and COERCION. See Note [mkRuntimeRepCo] in GHC.Core.Coercion. - - - - - 79ffa170 by Ben Gamari at 2023-03-01T04:17:20-05:00 hadrian: Add dependency from lib/settings to mk/config.mk In 81975ef375de07a0ea5a69596b2077d7f5959182 we attempted to fix #20253 by adding logic to the bindist Makefile to regenerate the `settings` file from information gleaned by the bindist `configure` script. However, this fix had no effect as `lib/settings` is shipped in the binary distribution (to allow in-place use of the binary distribution). As `lib/settings` already existed and its rule declared no dependencies, `make` would fail to use the added rule to regenerate it. Fix this by explicitly declaring a dependency from `lib/settings` on `mk/config.mk`. Fixes #22982. - - - - - a2a1a1c0 by Sebastian Graf at 2023-03-01T04:17:56-05:00 Revert the main payload of "Make `drop` and `dropWhile` fuse (#18964)" This reverts the bits affecting fusion of `drop` and `dropWhile` of commit 0f7588b5df1fc7a58d8202761bf1501447e48914 and keeps just the small refactoring unifying `flipSeqTake` and `flipSeqScanl'` into `flipSeq`. It also adds a new test for #23021 (which was the reason for reverting) as well as adds a clarifying comment to T18964. Fixes #23021, unfixes #18964. Metric Increase: T18964 Metric Decrease: T18964 - - - - - cf118e2f by Simon Peyton Jones at 2023-03-01T04:18:33-05:00 Refine the test for naughty record selectors The test for naughtiness in record selectors is surprisingly subtle. See the revised Note [Naughty record selectors] in GHC.Tc.TyCl.Utils. Fixes #23038. - - - - - 86f240ca by romes at 2023-03-01T04:19:10-05:00 fix: Consider strictness annotation in rep_bind Fixes #23036 - - - - - 1ed573a5 by Richard Eisenberg at 2023-03-02T22:42:06-05:00 Don't suppress *all* Wanteds Code in GHC.Tc.Errors.reportWanteds suppresses a Wanted if its rewriters have unfilled coercion holes; see Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. But if we thereby suppress *all* errors that's really confusing, and as #22707 shows, GHC goes on without even realising that the program is broken. Disaster. This MR arranges to un-suppress them all if they all get suppressed. Close #22707 - - - - - 8919f341 by Luite Stegeman at 2023-03-02T22:42:45-05:00 Check for platform support for JavaScript foreign imports GHC was accepting `foreign import javascript` declarations on non-JavaScript platforms. This adds a check so that these are only supported on an platform that supports the JavaScript calling convention. Fixes #22774 - - - - - db83f8bb by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Statically assert alignment of Capability In #22965 we noticed that changes in the size of `Capability` can result in unsound behavior due to the `align` pragma claiming an alignment which we don't in practice observe. Avoid this by statically asserting that the size is a multiple of the alignment. - - - - - 5f7a4a6d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Introduce stgMallocAlignedBytes - - - - - 8a6f745d by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Correctly align Capability allocations Previously we failed to tell the C allocator that `Capability`s needed to be aligned, resulting in #22965. Fixes #22965. Fixes #22975. - - - - - 5464c73f by Ben Gamari at 2023-03-02T22:43:22-05:00 rts: Drop no-alignment special case for Windows For reasons that aren't clear, we were previously not giving Capability the same favorable alignment on Windows that we provided on other platforms. Fix this. - - - - - a86aae8b by Matthew Pickering at 2023-03-02T22:43:59-05:00 constant folding: Correct type of decodeDouble_Int64 rule The first argument is Int64# unconditionally, so we better produce something of that type. This fixes a core lint error found in the ad package. Fixes #23019 - - - - - 68dd64ff by Zubin Duggal at 2023-03-02T22:44:35-05:00 ncg/aarch64: Handle MULTILINE_COMMENT identically as COMMENTs Commit 7566fd9de38c67360c090f828923d41587af519c with the fix for #22798 was incomplete as it failed to handle MULTILINE_COMMENT pseudo-instructions, and didn't completly fix the compiler panics when compiling with `-fregs-graph`. Fixes #23002 - - - - - 2f97c861 by Simon Peyton Jones at 2023-03-02T22:45:11-05:00 Get the right in-scope set in etaBodyForJoinPoint Fixes #23026 - - - - - 45af8482 by David Feuer at 2023-03-03T11:40:47-05:00 Export getSolo from Data.Tuple Proposed in [CLC proposal #113](https://github.com/haskell/core-libraries-committee/issues/113) and [approved by the CLC](https://github.com/haskell/core-libraries-committee/issues/113#issuecomment-1452452191) - - - - - 0c694895 by David Feuer at 2023-03-03T11:40:47-05:00 Document getSolo - - - - - bd0536af by Simon Peyton Jones at 2023-03-03T11:41:23-05:00 More fixes for `type data` declarations This MR fixes #23022 and #23023. Specifically * Beef up Note [Type data declarations] in GHC.Rename.Module, to make invariant (I1) explicit, and to name the several wrinkles. And add references to these specific wrinkles. * Add a Lint check for invariant (I1) above. See GHC.Core.Lint.checkTypeDataConOcc * Disable the `caseRules` for dataToTag# for `type data` values. See Wrinkle (W2c) in the Note above. Fixes #23023. * Refine the assertion in dataConRepArgTys, so that it does not complain about the absence of a wrapper for a `type data` constructor Fixes #23022. Acked-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 858f34d5 by Oleg Grenrus at 2023-03-04T01:13:55+02:00 Add decideSymbol, decideChar, decideNat, decTypeRep, decT and hdecT These all type-level equality decision procedures. Implementes a CLC proposal https://github.com/haskell/core-libraries-committee/issues/98 - - - - - bf43ba92 by Simon Peyton Jones at 2023-03-04T01:18:23-05:00 Add test for T22793 - - - - - c6e1f3cd by Chris Wendt at 2023-03-04T03:35:18-07:00 Fix typo in docs referring to threadLabel - - - - - 232cfc24 by Simon Peyton Jones at 2023-03-05T19:57:30-05:00 Add regression test for #22328 - - - - - 5ed77deb by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Enable response files for linker if supported - - - - - 1e0f6c89 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Synchronize `configure.ac` and `distrib/configure.ac.in` - - - - - 70560952 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix `hadrian/bindist/config.mk.in` … as suggested by @bgamari - - - - - b042b125 by sheaf at 2023-03-06T17:06:50-05:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 674b6b81 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Try to create somewhat portable `ld` command I cannot figure out a good way to generate an `ld` command that works on both Linux and macOS. Normally you'd use something like `AC_LINK_IFELSE` for this purpose (I think), but that won't let us test response file support. - - - - - 83b0177e by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Quote variables … as suggested by @bgamari - - - - - 845f404d by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Fix configure failure on alpine linux - - - - - c56a3ae6 by Gabriella Gonzalez at 2023-03-06T17:06:50-05:00 Small fixes to configure script - - - - - cad5c576 by Andrei Borzenkov at 2023-03-06T17:07:33-05:00 Convert diagnostics in GHC.Rename.Module to proper TcRnMessage (#20115) I've turned almost all occurrences of TcRnUnknownMessage in GHC.Rename.Module module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnIllegalInstanceHeadDecl TcRnUnexpectedStandaloneDerivingDecl TcRnUnusedVariableInRuleDecl TcRnUnexpectedStandaloneKindSig TcRnIllegalRuleLhs TcRnBadAssocRhs TcRnDuplicateRoleAnnot TcRnDuplicateKindSig TcRnIllegalDerivStrategy TcRnIllegalMultipleDerivClauses TcRnNoDerivStratSpecified TcRnStupidThetaInGadt TcRnBadImplicitSplice TcRnShadowedTyVarNameInFamResult TcRnIncorrectTyVarOnLhsOfInjCond TcRnUnknownTyVarsOnRhsOfInjCond Was introduced one helper type: RuleLhsErrReason - - - - - c6432eac by Apoorv Ingle at 2023-03-06T23:26:12+00:00 Constraint simplification loop now depends on `ExpansionFuel` instead of a boolean flag for `CDictCan.cc_pend_sc`. Pending givens get a fuel of 3 while Wanted and quantified constraints get a fuel of 1. This helps pending given constraints to keep up with pending wanted constraints in case of `UndecidableSuperClasses` and superclass expansions while simplifying the infered type. Adds 3 dynamic flags for controlling the fuels for each type of constraints `-fgivens-expansion-fuel` for givens `-fwanteds-expansion-fuel` for wanteds and `-fqcs-expansion-fuel` for quantified constraints Fixes #21909 Added Tests T21909, T21909b Added Note [Expanding Recursive Superclasses and ExpansionFuel] - - - - - a5afc8ab by Bodigrim at 2023-03-06T22:51:01-05:00 Documentation: describe laziness of several function from Data.List - - - - - fa559c28 by Ollie Charles at 2023-03-07T20:56:21+00:00 Add `Data.Functor.unzip` This function is currently present in `Data.List.NonEmpty`, but `Data.Functor` is a better home for it. This change was discussed and approved by the CLC at https://github.com/haskell/core-libraries-committee/issues/88. - - - - - 2aa07708 by MorrowM at 2023-03-07T21:22:22-05:00 Fix documentation for traceWith and friends - - - - - f3ff7cb1 by David Binder at 2023-03-08T01:24:17-05:00 Remove utils/hpc subdirectory and its contents - - - - - cf98e286 by David Binder at 2023-03-08T01:24:17-05:00 Add git submodule for utils/hpc - - - - - 605fbbb2 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 606793d4 by David Binder at 2023-03-08T01:24:18-05:00 Update commit for utils/hpc git submodule - - - - - 4158722a by Sylvain Henry at 2023-03-08T01:24:58-05:00 linker: fix linking with aligned sections (#23066) Take section alignment into account instead of assuming 16 bytes (which is wrong when the section requires 32 bytes, cf #23066). - - - - - 1e0d8fdb by Greg Steuck at 2023-03-08T08:59:05-05:00 Change hostSupportsRPaths to report False on OpenBSD OpenBSD does support -rpath but ghc build process relies on some related features that don't work there. See ghc/ghc#23011 - - - - - bed3a292 by Alexis King at 2023-03-08T08:59:53-05:00 bytecode: Fix bitmaps for BCOs used to tag tuples and prim call args fixes #23068 - - - - - 321d46d9 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Drop redundant prototype - - - - - abb6070f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix style - - - - - be278901 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Deduplicate assertion - - - - - b9034639 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Fix type issues in Sparks.h Adds explicit casts to satisfy a C++ compiler. - - - - - da7b2b94 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts: Use release ordering when storing thread labels Since this makes the ByteArray# visible from other cores. - - - - - 5b7f6576 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/BlockAlloc: Allow disabling of internal assertions These can be quite expensive and it is sometimes useful to compile a DEBUG RTS without them. - - - - - 6283144f by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Mark pinned_object_blocks - - - - - 9b528404 by Ben Gamari at 2023-03-08T15:02:30-05:00 rts/Sanity: Look at nonmoving saved_filled lists - - - - - 0edc5438 by Ben Gamari at 2023-03-08T15:02:30-05:00 Evac: Squash data race in eval_selector_chain - - - - - 7eab831a by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify implementation This makes the intent of this implementation a bit clearer. - - - - - 532262b9 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Clarify comment - - - - - bd9cd84b by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing no-op in busy-wait loop - - - - - c4e6bfc8 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't push empty arrays to update remembered set Previously the write barrier of resizeSmallArray# incorrectly handled resizing of zero-sized arrays, pushing an invalid pointer to the update remembered set. Fixes #22931. - - - - - 92227b60 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix handling of weak pointers This fixes an interaction between aging and weak pointer handling which prevented the finalization of some weak pointers. In particular, weak pointers could have their keys incorrectly marked by the preparatory collector, preventing their finalization by the subsequent concurrent collection. While in the area, we also significantly improve the assertions regarding weak pointers. Fixes #22327. - - - - - ba7e7972 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check nonmoving large objects and compacts - - - - - 71b038a1 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Sanity check mutable list Assert that entries in the nonmoving generation's generational remembered set (a.k.a. mutable list) live in nonmoving generation. - - - - - 99d144d5 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't show occupancy if we didn't collect live words - - - - - 81d6cc55 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Fix tracking of FILLED_SWEEPING segments Previously we only updated the state of the segment at the head of each allocator's filled list. - - - - - 58e53bc4 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Assert state of swept segments - - - - - 2db92e01 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Handle new closures in nonmovingIsNowAlive We must conservatively assume that new closures are reachable since we are not guaranteed to mark such blocks. - - - - - e4c3249f by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Don't clobber update rem sets of old capabilities Previously `storageAddCapabilities` (called by `setNumCapabilities`) would clobber the update remembered sets of existing capabilities when increasing the capability count. Fix this by only initializing the update remembered sets of the newly-created capabilities. Fixes #22927. - - - - - 1b069671 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Add missing write barriers in selector optimisation This fixes the selector optimisation, adding a few write barriers which are necessary for soundness. See the inline comments for details. Fixes #22930. - - - - - d4032690 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Post-sweep sanity checking - - - - - 0baa8752 by Ben Gamari at 2023-03-08T15:02:30-05:00 nonmoving: Avoid n_caps race - - - - - 5d3232ba by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't push if nonmoving collector isn't enabled - - - - - 0a7eb0aa by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Be more paranoid in segment tracking Previously we left various segment link pointers dangling. None of this wrong per se, but it did make it harder than necessary to debug. - - - - - 7c817c0a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Sync-phase mark budgeting Here we significantly improve the bound on sync phase pause times by imposing a limit on the amount of work that we can perform during the sync. If we find that we have exceeded our marking budget then we allow the mutators to resume, return to concurrent marking, and try synchronizing again later. Fixes #22929. - - - - - ce22a3e2 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Allow pinned gen0 objects to be WEAK keys - - - - - 78746906 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Reenable assertion - - - - - b500867a by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move current segment array into Capability The current segments are conceptually owned by the mutator, not the collector. Consequently, it was quite tricky to prove that the mutator would not race with the collect due to this shared state. It turns out that such races are possible: when resizing the current segment array we may concurrently try to take a heap census. This will attempt to walk the current segment array, causing a data race. Fix this by moving the current segment array into `Capability`, where it belongs. Fixes #22926. - - - - - 56e669c1 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix Note references Some references to Note [Deadlock detection under the non-moving collector] were missing an article. - - - - - 4a7650d7 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts/Sanity: Fix block count assertion with non-moving collector The nonmoving collector does not use `oldest_gen->blocks` to track its block list. However, it nevertheless updates `oldest_gen->n_blocks` to ensure that its size is accounted for by the storage manager. Consequently, we must not attempt to assert consistency between the two. - - - - - 96a5aaed by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Don't call prepareUnloadCheck When the nonmoving GC is in use we do not call `checkUnload` (since we don't unload code) and therefore should not call `prepareUnloadCheck`, lest we run into assertions. - - - - - 6c6674ca by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Encapsulate block allocator spinlock This makes it a bit easier to add instrumentation on this spinlock while debugging. - - - - - e84f7167 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip some tests when sanity checking is enabled - - - - - 3ae0f368 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Fix unregisterised build - - - - - 4eb9d06b by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Ensure that sanity checker accounts for saved_filled segments - - - - - f0cf384d by Ben Gamari at 2023-03-08T15:02:31-05:00 hadrian: Add +boot_nonmoving_gc flavour transformer For using GHC bootstrapping to validate the non-moving GC. - - - - - 581e58ac by Ben Gamari at 2023-03-08T15:02:31-05:00 gitlab-ci: Add job bootstrapping with nonmoving GC - - - - - 487a8b58 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Move allocator into new source file - - - - - 8f374139 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Split out nonmovingAllocateGC - - - - - 662b6166 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Only run T22795* in the normal way It doesn't make sense to run these in multiple ways as they merely test whether `-threaded`/`-single-threaded` flags. - - - - - 0af21dfa by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Rename clear_segment(_free_blocks)? To reflect the fact that these are to do with the nonmoving collector, now since they are exposed no longer static. - - - - - 7bcb192b by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Fix incorrect STATIC_INLINE This should be INLINE_HEADER lest we get unused declaration warnings. - - - - - f1fd3ffb by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Mark ffi023 as broken due to #23089 - - - - - a57f12b3 by Ben Gamari at 2023-03-08T15:02:31-05:00 testsuite: Skip T7160 in the nonmoving way Finalization order is different under the nonmoving collector. - - - - - f6f12a36 by Ben Gamari at 2023-03-08T15:02:31-05:00 rts: Capture GC configuration in a struct The number of distinct arguments passed to GarbageCollect was getting a bit out of hand. - - - - - ba73a807 by Ben Gamari at 2023-03-08T15:02:31-05:00 nonmoving: Non-concurrent collection - - - - - 7c813d06 by Alexis King at 2023-03-08T15:03:10-05:00 hadrian: Fix flavour compiler stage options off-by-one error !9193 pointed out that ghcDebugAssertions was supposed to be a predicate on the stage of the built compiler, but in practice it was a predicate on the stage of the compiler used to build. Unfortunately, while it fixed that issue for ghcDebugAssertions, it documented every other similar option as behaving the same way when in fact they all used the old behavior. The new behavior of ghcDebugAssertions seems more intuitive, so this commit changes the interpretation of every other option to match. It also improves the enableProfiledGhc and debugGhc flavour transformers by making them more selective about which stages in which they build additional library/RTS ways. - - - - - f97c7f6d by Luite Stegeman at 2023-03-09T09:52:09-05:00 Delete created temporary subdirectories at end of session. This patch adds temporary subdirectories to the list of paths do clean up at the end of the GHC session. This fixes warnings about non-empty temporary directories. Fixes #22952 - - - - - 9ea719f2 by Apoorv Ingle at 2023-03-09T09:52:45-05:00 Fixes #19627. Previously the solver failed with an unhelpful "solver reached too may iterations" error. With the fix for #21909 in place we no longer have the possibility of generating such an error if we have `-fconstraint-solver-iteration` > `-fgivens-fuel > `-fwanteds-fuel`. This is true by default, and the said fix also gives programmers a knob to control how hard the solver should try before giving up. This commit adds: * Reference to ticket #19627 in the Note [Expanding Recursive Superclasses and ExpansionFuel] * Test `typecheck/should_fail/T19627.hs` for regression purposes - - - - - ec2d93eb by Sebastian Graf at 2023-03-10T10:18:54-05:00 DmdAnal: Fix a panic on OPAQUE and trivial/PAP RHS (#22997) We should not panic in `add_demands` (now `set_lam_dmds`), because that code path is legimitely taken for OPAQUE PAP bindings, as in T22997. Fixes #22997. - - - - - 5b4628ae by Sylvain Henry at 2023-03-10T10:19:34-05:00 JS: remove dead code for old integer-gmp - - - - - bab23279 by Josh Meredith at 2023-03-10T23:24:49-05:00 JS: Fix implementation of MK_JSVAL - - - - - ec263a59 by Sebastian Graf at 2023-03-10T23:25:25-05:00 Simplify: Move `wantEtaExpansion` before expensive `do_eta_expand` check There is no need to run arity analysis and what not if we are not in a Simplifier phase that eta-expands or if we don't want to eta-expand the expression in the first place. Purely a refactoring with the goal of improving compiler perf. - - - - - 047e9d4f by Josh Meredith at 2023-03-13T03:56:03+00:00 JS: fix implementation of forceBool to use JS backend syntax - - - - - 559a4804 by Sebastian Graf at 2023-03-13T07:31:23-04:00 Simplifier: `countValArgs` should not count Type args (#23102) I observed miscompilations while working on !10088 caused by this. Fixes #23102. Metric Decrease: T10421 - - - - - 536d1f90 by Matthew Pickering at 2023-03-13T14:04:49+00:00 Bump Win32 to 2.13.4.0 Updates Win32 submodule - - - - - ee17001e by Ben Gamari at 2023-03-13T21:18:24-04:00 ghc-bignum: Drop redundant include-dirs field - - - - - c9c26cd6 by Teo Camarasu at 2023-03-16T12:17:50-04:00 Fix BCO creation setting caps when -j > -N * Remove calls to 'setNumCapabilities' in 'createBCOs' These calls exist to ensure that 'createBCOs' can benefit from parallelism. But this is not the right place to call `setNumCapabilities`. Furthermore the logic differs from that in the driver causing the capability count to be raised and lowered at each TH call if -j > -N. * Remove 'BCOOpts' No longer needed as it was only used to thread the job count down to `createBCOs` Resolves #23049 - - - - - 5ddbf5ed by Teo Camarasu at 2023-03-16T12:17:50-04:00 Add changelog entry for #23049 - - - - - 6e3ce9a4 by Ben Gamari at 2023-03-16T12:18:26-04:00 configure: Fix FIND_CXX_STD_LIB test on Darwin Annoyingly, Darwin's <cstddef> includes <version> and APFS is case-insensitive. Consequently, it will end up #including the `VERSION` file generated by the `configure` script on the second and subsequent runs of the `configure` script. See #23116. - - - - - 19d6d039 by sheaf at 2023-03-16T21:31:22+01:00 ghci: only keep the GlobalRdrEnv in ModInfo The datatype GHC.UI.Info.ModInfo used to store a ModuleInfo, which includes a TypeEnv. This can easily cause space leaks as we have no way of forcing everything in a type environment. In GHC, we only use the GlobalRdrEnv, which we can force completely. So we only store that instead of a fully-fledged ModuleInfo. - - - - - 73d07c6e by Torsten Schmits at 2023-03-17T14:36:49-04:00 Add structured error messages for GHC.Tc.Utils.Backpack Tracking ticket: #20119 MR: !10127 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. One occurrence, when handing a nested error from the interface loading machinery, was omitted. It will be handled by a subsequent changeset that addresses interface errors. - - - - - a13affce by Andrei Borzenkov at 2023-03-21T11:17:17-04:00 Rename () into Unit, (,,...,,) into Tuple<n> (#21294) This patch implements a part of GHC Proposal #475. The key change is in GHC.Tuple.Prim: - data () = () - data (a,b) = (a,b) - data (a,b,c) = (a,b,c) ... + data Unit = () + data Tuple2 a b = (a,b) + data Tuple3 a b c = (a,b,c) ... And the rest of the patch makes sure that Unit and Tuple<n> are pretty-printed as () and (,,...,,) in various contexts. Updates the haddock submodule. Co-authored-by: Vladislav Zavialov <vlad.z.4096 at gmail.com> - - - - - 23642bf6 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: fix some wrongs in the eventlog format documentation - - - - - 90159773 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: explain the BLOCK_MARKER event - - - - - ab1c25e8 by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add BlockedOnMVarRead thread status in eventlog encodings - - - - - 898afaef by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add TASK_DELETE event in eventlog encodings - - - - - bb05b4cc by Adam Sandberg Ericsson at 2023-03-21T11:17:53-04:00 docs: add WALL_CLOCK_TIME event in eventlog encodings - - - - - eeea0343 by Torsten Schmits at 2023-03-21T11:18:34-04:00 Add structured error messages for GHC.Tc.Utils.Env Tracking ticket: #20119 MR: !10129 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - be1d4be8 by Bodigrim at 2023-03-21T11:19:13-04:00 Document pdep / pext primops - - - - - e8b4aac4 by Alex Mason at 2023-03-21T18:11:04-04:00 Allow LLVM backend to use HDoc for faster file generation. Also remove the MetaStmt constructor from LlvmStatement and places the annotations into the Store statement. Includes “Implement a workaround for -no-asm-shortcutting bug“ (https://gitlab.haskell.org/ghc/ghc/-/commit/2fda9e0df886cc551e2cd6b9c2a384192bdc3045) - - - - - ea24360d by Luite Stegeman at 2023-03-21T18:11:44-04:00 Compute LambdaFormInfo when using JavaScript backend. CmmCgInfos is needed to write interface files, but the JavaScript backend does not generate it, causing "Name without LFInfo" warnings. This patch adds a conservative but always correct CmmCgInfos when the JavaScript backend is used. Fixes #23053 - - - - - 926ad6de by Simon Peyton Jones at 2023-03-22T01:03:08-04:00 Be more careful about quantification This MR is driven by #23051. It does several things: * It is guided by the generalisation plan described in #20686. But it is still far from a complete implementation of that plan. * Add Note [Inferred type with escaping kind] to GHC.Tc.Gen.Bind. This explains that we don't (yet, pending #20686) directly prevent generalising over escaping kinds. * In `GHC.Tc.Utils.TcMType.defaultTyVar` we default RuntimeRep and Multiplicity variables, beause we don't want to quantify over them. We want to do the same for a Concrete tyvar, but there is nothing sensible to default it to (unless it has kind RuntimeRep, in which case it'll be caught by an earlier case). So we promote instead. * Pure refactoring in GHC.Tc.Solver: * Rename decideMonoTyVars to decidePromotedTyVars, since that's what it does. * Move the actual promotion of the tyvars-to-promote from `defaultTyVarsAndSimplify` to `decidePromotedTyVars`. This is a no-op; just tidies up the code. E.g then we don't need to return the promoted tyvars from `decidePromotedTyVars`. * A little refactoring in `defaultTyVarsAndSimplify`, but no change in behaviour. * When making a TauTv unification variable into a ConcreteTv (in GHC.Tc.Utils.Concrete.makeTypeConcrete), preserve the occ-name of the type variable. This just improves error messages. * Kill off dead code: GHC.Tc.Utils.TcMType.newConcreteHole - - - - - 0ab0cc11 by Sylvain Henry at 2023-03-22T01:03:48-04:00 Testsuite: use appropriate predicate for ManyUbxSums test (#22576) - - - - - 048c881e by romes at 2023-03-22T01:04:24-04:00 fix: Incorrect @since annotations in GHC.TypeError Fixes #23128 - - - - - a1528b68 by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T16318 (#22370) - - - - - ad765b6f by Sylvain Henry at 2023-03-22T01:05:04-04:00 Testsuite: use req_interp predicate for T20214 - - - - - e0b8eaf3 by Simon Peyton Jones at 2023-03-22T09:50:13+00:00 Refactor the constraint solver pipeline The big change is to put the entire type-equality solver into GHC.Tc.Solver.Equality, rather than scattering it over Canonical and Interact. Other changes * EqCt becomes its own data type, a bit like QCInst. This is great because EqualCtList is then just [EqCt] * New module GHC.Tc.Solver.Dict has come of the class-contraint solver. In due course it will be all. One step at a time. This MR is intended to have zero change in behaviour: it is a pure refactor. It opens the way to subsequent tidying up, we believe. - - - - - cedf9a3b by Torsten Schmits at 2023-03-22T15:31:18-04:00 Add structured error messages for GHC.Tc.Utils.TcMType Tracking ticket: #20119 MR: !10138 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30d45e97 by Sylvain Henry at 2023-03-22T15:32:01-04:00 Testsuite: use js_skip for T2615 (#22374) - - - - - 8c98deba by Armando Ramirez at 2023-03-23T09:19:32-04:00 Optimized Foldable methods for Data.Functor.Compose Explicitly define length, elem, etc. in Foldable instance for Data.Functor.Compose Implementation of https://github.com/haskell/core-libraries-committee/issues/57 - - - - - bc066108 by Armando Ramirez at 2023-03-23T09:19:32-04:00 Additional optimized versions - - - - - 80fce576 by Bodigrim at 2023-03-23T09:19:32-04:00 Simplify minimum/maximum in instance Foldable (Compose f g) - - - - - 8cb88a5a by Bodigrim at 2023-03-23T09:19:32-04:00 Update changelog to mention changes to instance Foldable (Compose f g) - - - - - e1c8c41d by Torsten Schmits at 2023-03-23T09:20:13-04:00 Add structured error messages for GHC.Tc.TyCl.PatSyn Tracking ticket: #20117 MR: !10158 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - 232ae7dd by Rodrigo Mesquita at 2023-04-26T12:37:37+01:00 docs: Remove mentions of ArrayArray# from FFI page Fixes #23277 - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - .gitlab/test-metrics.sh - .gitmodules - cabal.project-reinstall - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d027c629cdbae51f49b91dbbd8c77d1a427b66ef...232ae7dd3ccb37510001110cedb01f5b09fec3df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d027c629cdbae51f49b91dbbd8c77d1a427b66ef...232ae7dd3ccb37510001110cedb01f5b09fec3df You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 12:07:39 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Wed, 26 Apr 2023 08:07:39 -0400 Subject: [Git][ghc/ghc][wip/T23025] Don't add external names to the usage environment Message-ID: <6449140bc099e_178e74da8b230816334ea@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/T23025 at Glasgow Haskell Compiler / GHC Commits: e9a5a9b4 by Krzysztof Gogolewski at 2023-04-26T14:07:16+02:00 Don't add external names to the usage environment - - - - - 2 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Tc/Gen/Head.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -1025,7 +1025,11 @@ lintIdOcc var nargs Nothing -> return () Just dc -> checkTypeDataConOcc "expression" dc - ; usage <- varCallSiteUsage var + -- Don't add external names to the usage environment; + -- they are not relevant for linearity checks + ; usage <- case isExternalName (Var.varName var) of + False -> varCallSiteUsage var + True -> return zeroUE ; return (linted_bndr_ty, usage) } ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -1091,7 +1091,10 @@ tc_infer_id id_name check_local_id :: Id -> TcM () check_local_id id = do { checkThLocalId id - ; tcEmitBindingUsage $ unitUE (idName id) OneTy } + -- Don't add external names to the usage environment; + -- they are not relevant for linearity checks + ; unless (isExternalName (idName id)) $ + tcEmitBindingUsage $ unitUE (idName id) OneTy } check_naughty :: OccName -> TcId -> TcM () check_naughty lbl id View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9a5a9b4e27df4d13f4cb44a389f7afef885c5d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9a5a9b4e27df4d13f4cb44a389f7afef885c5d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 12:34:54 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 08:34:54 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64491a6e7303f_178e74db1cc5b016419a4@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 9ed45119 by Rodrigo Mesquita at 2023-04-26T13:34:41+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 16 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -586,12 +586,22 @@ Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~ -dcSourceArity does not take constraints into account, -but dcRepArity does. For example: +A `DataCon`'s source arity and core representation arity may differ: +`dcSourceArity` does not take constraints into account, but `dcRepArity` does. + +The additional arguments taken into account by `dcRepArity` include quantified +dictionaries and coercion arguments, lifted and unlifted (despite the unlifted +coercion arguments having a zero-width runtime representation). +For example: MkT :: Ord a => a -> T a dcSourceArity = 1 dcRepArity = 2 + MkU :: (b ~ '[]) => U b + dcSourceArity = 0 + dcRepArity = 1 + + Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A DataCon has two different sets of type variables: @@ -981,7 +991,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1405,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of value arguments (including zero-width coercions) +-- stored by the given `DataCon`'s worker in its Core representation. This may +-- differ from the number of arguments that appear in the source code; see also +-- Note [DataCon arities] dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1417,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether this `DataCon`'s worker, in its Core representation, takes +-- any value arguments. +-- +-- In particular, remember that we include coercion arguments in the arity of +-- the Core representation of the `DataCon` -- both lifted and unlifted +-- coercions, despite the latter having zero-width runtime representation. +-- +-- See also Note [DataCon arities]. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,123 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id` +* For Ids defined in this module: is `Nothing` +* For imported Ids: + * is (Just lf_info) if the LFInfo was serialised into the interface file + (typically, when the exporting module was compiled with -O) + * is Nothing if it wasn't serialised + +However, when an interface doesn't have a LambdaFormInfo for some imported Id +(so that its `lfInfo` field is `Nothing`), we can conservatively create one +using `mkLFImported`. + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146). In particular, saturated data constructor applications *must* be +unambiguously given `LFCon`, and the invariant + + If the LFInfo (serialised or built with mkLFImported) says LFCon, then it + really is a static data constructor, and similar for LFReEntrant + +must be upheld. + +In `mkLFImported`, we make a conservative approximation to the real +LambdaFormInfo as follows: + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged (by `litIdInfo`) with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> Maybe a` is given `LFReEntrant` + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -71,12 +71,13 @@ moving parts are: -fomit-interface-pragmas or -fno-code; and we won't read it in if you have -fignore-interface-pragmas. (We could revisit this decision.) -Note [Imported nullary datacon wrappers must have correct LFInfo] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As described in `Note [Conveying CAF-info and LFInfo between modules]`, -imported nullary datacons must have their LambdaFormInfo set to reflect the -fact that they are evaluated . This is necessary are otherwise references -to them may be passed untagged to code that expects tagged references. +imported unlifted nullary datacons must have their LambdaFormInfo set to +reflect the fact that they are evaluated . This is necessary as otherwise +references to them may be passed untagged to code that expects tagged +references. What may be less obvious is that this must be done for not only datacon workers but also *wrappers*. The reason is found in this program @@ -113,6 +114,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +164,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,8 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | This function counts all arguments post-unarisation, which includes +-- arguments with no runtime representation -- see Note [Unarisation and arity] idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -374,6 +374,7 @@ data IdInfo -- -- See documentation of the getters for what these packed fields mean. lfInfo :: !(Maybe LambdaFormInfo), + -- ^ See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure -- See documentation of the getters for what these packed fields mean. tagSig :: !(Maybe TagSig) @@ -439,7 +440,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -595,10 +595,12 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + wkr_lf_info = ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ed451199b0c955ee9a46d8e667eb88a4d0d2aa6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ed451199b0c955ee9a46d8e667eb88a4d0d2aa6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 13:24:19 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 09:24:19 -0400 Subject: [Git][ghc/ghc][wip/T23146] codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <64492603b0b4_178e74dbdafc7416536c6@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: ba2177fa by Rodrigo Mesquita at 2023-04-26T14:24:05+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 15 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -586,12 +586,22 @@ Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~ -dcSourceArity does not take constraints into account, -but dcRepArity does. For example: +A `DataCon`'s source arity and core representation arity may differ: +`dcSourceArity` does not take constraints into account, but `dcRepArity` does. + +The additional arguments taken into account by `dcRepArity` include quantified +dictionaries and coercion arguments, lifted and unlifted (despite the unlifted +coercion arguments having a zero-width runtime representation). +For example: MkT :: Ord a => a -> T a dcSourceArity = 1 dcRepArity = 2 + MkU :: (b ~ '[]) => U b + dcSourceArity = 0 + dcRepArity = 1 + + Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A DataCon has two different sets of type variables: @@ -981,7 +991,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1405,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of value arguments (including zero-width coercions) +-- stored by the given `DataCon`'s worker in its Core representation. This may +-- differ from the number of arguments that appear in the source code; see also +-- Note [DataCon arities] dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1417,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether this `DataCon`'s worker, in its Core representation, takes +-- any value arguments. +-- +-- In particular, remember that we include coercion arguments in the arity of +-- the Core representation of the `DataCon` -- both lifted and unlifted +-- coercions, despite the latter having zero-width runtime representation. +-- +-- See also Note [DataCon arities]. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -264,23 +264,123 @@ mkLFImported id = -- Use the LambdaFormInfo from the interface lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. + -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. + -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor + -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types + -- and Note [The LFInfo of Imported Ids] below + -> assert (hasNoNonZeroWidthArgs con) $ + LFCon con -- An imported nullary constructor -- We assume that the constructor is evaluated so that -- the id really does point directly to the constructor - | arity > 0 - -> LFReEntrant TopLevel arity True ArgUnknown - | otherwise -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id + hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys + +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As explained in Note [Conveying CAF-info and LFInfo between modules] and +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the +LambdaFormInfo records the details of a closure representation and is often, +when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id` +* For Ids defined in this module: is `Nothing` +* For imported Ids: + * is (Just lf_info) if the LFInfo was serialised into the interface file + (typically, when the exporting module was compiled with -O) + * is Nothing if it wasn't serialised + +However, when an interface doesn't have a LambdaFormInfo for some imported Id +(so that its `lfInfo` field is `Nothing`), we can conservatively create one +using `mkLFImported`. + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as +faithfully as possible or otherwise risk having pointers incorrectly tagged, +which can lead to performance issues and even segmentation faults (see #23231 +and #23146). In particular, saturated data constructor applications *must* be +unambiguously given `LFCon`, and the invariant + + If the LFInfo (serialised or built with mkLFImported) says LFCon, then it + really is a static data constructor, and similar for LFReEntrant + +must be upheld. + +In `mkLFImported`, we make a conservative approximation to the real +LambdaFormInfo as follows: + +(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are +tagged (by `litIdInfo`) with the corresponding arity. + - This is also true of data con wrappers and workers with arity > 0, + regardless of the runtime relevance of the arguments + - For example, `Just :: a -> Maybe a` is given `LFReEntrant` + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too + +(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because +they are fully saturated data constructor applications and pointers to them +should be tagged with the constructor index. + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +To ensure we properly give `LFReEntrant` to data constructors with some arity, +and `LFCon` only to data constructors with zero arity, we must first check for +`arity > 0` and only afterwards `isDataConId` -- the order of the guards in +`mkLFImported` is quite important. + +As an example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +-} ------------- mkLFStringLit :: LambdaFormInfo ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -71,12 +71,13 @@ moving parts are: -fomit-interface-pragmas or -fno-code; and we won't read it in if you have -fignore-interface-pragmas. (We could revisit this decision.) -Note [Imported nullary datacon wrappers must have correct LFInfo] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As described in `Note [Conveying CAF-info and LFInfo between modules]`, -imported nullary datacons must have their LambdaFormInfo set to reflect the -fact that they are evaluated . This is necessary are otherwise references -to them may be passed untagged to code that expects tagged references. +imported unlifted nullary datacons must have their LambdaFormInfo set to +reflect the fact that they are evaluated . This is necessary as otherwise +references to them may be passed untagged to code that expects tagged +references. What may be less obvious is that this must be done for not only datacon workers but also *wrappers*. The reason is found in this program @@ -113,6 +114,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +164,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,8 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | This function counts all arguments post-unarisation, which includes +-- arguments with no runtime representation -- see Note [Unarisation and arity] idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -374,6 +374,7 @@ data IdInfo -- -- See documentation of the getters for what these packed fields mean. lfInfo :: !(Maybe LambdaFormInfo), + -- ^ See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure -- See documentation of the getters for what these packed fields mean. tagSig :: !(Maybe TagSig) @@ -439,7 +440,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ba2177fa72f7829a4582937d22ae9f92caf1da48 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ba2177fa72f7829a4582937d22ae9f92caf1da48 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 13:50:48 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 26 Apr 2023 09:50:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: JS: Fix h$base_access implementation (issue 22576) Message-ID: <64492c38b764a_178e74dc7c25401668032@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - 36a7d161 by Sebastian Graf at 2023-04-26T09:50:41-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 1945487f by Josh Meredith at 2023-04-26T09:50:42-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 94d8b606 by Alan Zimmerman at 2023-04-26T09:50:42-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - 30 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Sinker.hs - compiler/GHC/StgToJS/StgUtils.hs - compiler/GHC/Types/Demand.hs - docs/users_guide/exts/implicit_parameters.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/743cd728239f8775fab8d6f7d5638247a32d1031...94d8b606c1df3230e1ceb1590f546588a2b448f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/743cd728239f8775fab8d6f7d5638247a32d1031...94d8b606c1df3230e1ceb1590f546588a2b448f7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 14:42:41 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 10:42:41 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/codebuffer-perftest Message-ID: <64493861c5814_178e74dd7c962816847f5@gitlab.mail> Josh Meredith pushed new branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/codebuffer-perftest You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 14:55:34 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 10:55:34 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 3 commits: Validate compatibility of ghcs when loading plugins Message-ID: <64493b66cd25f_178e74ddc0b4fc1688798@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 26d1e373 by romes at 2023-04-26T15:49:57+01:00 Validate compatibility of ghcs when loading plugins Ensure, when loading plugins, that the ghc the plugin depends on is the ghc loading the plugin -- otherwise fail to load the plugin. Progress towards #20742. - - - - - 775e6b5b by romes at 2023-04-26T15:51:42+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - d4bbc74b by Matthew Pickering at 2023-04-26T15:51:42+01:00 Use hash-unit-ids in release jobs Includes fix upload_ghc_libs glob - - - - - 8 changed files: - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC/Runtime/Loader.hs - hadrian/bindist/Makefile - hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8488080c632408d2397f9f129078f579e61e8652...d4bbc74b9f211d24428a06246a88fd88813f01b0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8488080c632408d2397f9f129078f579e61e8652...d4bbc74b9f211d24428a06246a88fd88813f01b0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 14:56:14 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 10:56:14 -0400 Subject: [Git][ghc/ghc][wip/romes/hardwire-ghc-unit-id] 23 commits: Implement -jsem: parallelism controlled by semaphores Message-ID: <64493b8e169bf_178e74ddc9e9f01689168@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/hardwire-ghc-unit-id at Glasgow Haskell Compiler / GHC Commits: 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - c7c897a0 by Matthew Pickering at 2023-04-26T15:56:06+01:00 hadrian: Flavour: Change args -> extraArgs Previously in a flavour definition you could override all the flags which were passed to GHC. This causes issues when needed to compute a package hash because we need to know what these extra arguments are going to be before computing the hash. The solution is to modify flavour so that the arguments you pass here are just extra ones rather than all the arguments that you need to compile something. This makes things work more like how cabal.project files work when you give extra arguments to a package and also means that flavour transformers correctly affect the hash. - - - - - 1ad1118c by romes at 2023-04-26T15:56:06+01:00 Hardwire a better unit-id for ghc Previously, the unit-id of ghc-the-library was fixed as `ghc`. This was done primarily because the compiler must know the unit-id of some packages (including ghc) a-priori to define wired-in names. However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed to `ghc` might result in subtle bugs when different ghc's interact. A good example of this is having GHC_A load a plugin compiled by GHC_B, where GHC_A and GHC_B are linked to ghc-libraries that are ABI incompatible. Without a distinction between the unit-id of the ghc library GHC_A is linked against and the ghc library the plugin it is loading was compiled against, we can't check compatibility. This patch gives a slightly better unit-id to ghc (ghc-version) by (1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0) (2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id. (2.1) `GHC.Settings.Config` is generated by Hadrian (2.2) and also by cabal through `compiler/Setup.hs` This unit-id definition is imported by `GHC.Unit.Types` and used to set the wired-in unit-id of "ghc", which was previously fixed to "ghc" The commits following this one will improve the unit-id with a cabal-style package hash and check compatibility when loading plugins. Note that we also ensure that ghc's unit key matches unit id both when hadrian or cabal builds ghc, and in this way we no longer need to add `ghc` to the WiringMap. - - - - - 032db057 by romes at 2023-04-26T15:56:06+01:00 Validate compatibility of ghcs when loading plugins Ensure, when loading plugins, that the ghc the plugin depends on is the ghc loading the plugin -- otherwise fail to load the plugin. Progress towards #20742. - - - - - e7b682ef by romes at 2023-04-26T15:56:06+01:00 Add hashes to unit-ids created by hadrian This commit adds support for computing an inputs hash for packages compiled by hadrian. The result is that ABI incompatible packages should be given different hashes and therefore be distinct in a cabal store. Hashing is enabled by the `--flag`, and is off by default as the hash contains a hash of the source files. We enable it when we produce release builds so that the artifacts we distribute have the right unit ids. - - - - - 1e794a65 by Matthew Pickering at 2023-04-26T15:56:06+01:00 Use hash-unit-ids in release jobs Includes fix upload_ghc_libs glob - - - - - 30 changed files: - .gitignore - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - .gitlab/rel_eng/upload_ghc_libs.py - .gitmodules - cabal.project-reinstall - compiler/GHC/Driver/Make.hs - + compiler/GHC/Driver/MakeSem.hs - compiler/GHC/Driver/Pipeline/LogQueue.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/GHC/Unit/Types.hs - compiler/GHC/Utils/Panic.hs - compiler/Setup.hs - compiler/ghc.cabal.in - configure.ac - docs/users_guide/9.8.1-notes.rst - docs/users_guide/exts/control.rst - docs/users_guide/exts/implicit_parameters.rst - docs/users_guide/exts/multiway_if.rst - docs/users_guide/javascript.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d4bbc74b9f211d24428a06246a88fd88813f01b0...1e794a65877eee0df6ee9aa7eb04bfbc0a5af67e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d4bbc74b9f211d24428a06246a88fd88813f01b0...1e794a65877eee0df6ee9aa7eb04bfbc0a5af67e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 14:57:52 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 10:57:52 -0400 Subject: [Git][ghc/ghc][wip/unitidset] WIP refactor `Set UnitId` to `UniqDSet UnitId` Message-ID: <64493bf062987_178e74ddc0b4fc1689680@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: dc2c21f0 by Josh Meredith at 2023-04-26T14:57:24+00:00 WIP refactor `Set UnitId` to `UniqDSet UnitId` - - - - - 21 changed files: - compiler/GHC.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Module/Deps.hs - compiler/GHC/Unit/Module/ModGuts.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Unit/Types.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -395,6 +395,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -418,8 +419,6 @@ import Data.Typeable ( Typeable ) import Data.Word ( Word8 ) import qualified Data.Map.Strict as Map -import Data.Set (Set) -import qualified Data.Set as S import qualified Data.Sequence as Seq import System.Directory @@ -604,7 +603,7 @@ setSessionDynFlags dflags0 = do logger <- getLogger dflags <- checkNewDynFlags logger dflags0 let all_uids = hsc_all_home_unit_ids hsc_env - case S.toList all_uids of + case uniqDSetToList all_uids of [uid] -> do setUnitDynFlagsNoCheck uid dflags modifySession (hscUpdateLoggerFlags . hscSetActiveUnitId (homeUnitId_ dflags)) @@ -1379,7 +1378,7 @@ data ModuleInfo = ModuleInfo { -- | Request information about a loaded 'Module' getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo) -- XXX: Maybe X getModuleInfo mdl = withSession $ \hsc_env -> do - if moduleUnitId mdl `S.member` hsc_all_home_unit_ids hsc_env + if moduleUnitId mdl `elementOfUniqDSet` hsc_all_home_unit_ids hsc_env then liftIO $ getHomeModuleInfo hsc_env mdl else liftIO $ getPackageModuleInfo hsc_env mdl @@ -1756,7 +1755,7 @@ isModuleTrusted m = withSession $ \hsc_env -> liftIO $ hscCheckSafe hsc_env m noSrcSpan -- | Return if a module is trusted and the pkgs it depends on to be trusted. -moduleTrustReqs :: GhcMonad m => Module -> m (Bool, Set UnitId) +moduleTrustReqs :: GhcMonad m => Module -> m (Bool, UnitIdSet) moduleTrustReqs m = withSession $ \hsc_env -> liftIO $ hscGetSafe hsc_env m noSrcSpan ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -56,12 +56,12 @@ import GHC.Types.SrcLoc import GHC.Types.CostCentre import GHC.Types.ForeignStubs import GHC.Types.Unique.Supply ( mkSplitUniqSupply ) +import GHC.Types.Unique.DSet import System.Directory import System.FilePath import System.IO -import Data.Set (Set) -import qualified Data.Set as Set +import Data.List ( sort ) {- ************************************************************************ @@ -84,7 +84,7 @@ codeOutput -> (a -> ForeignStubs) -> [(ForeignSrcLang, FilePath)] -- ^ additional files to be compiled with the C compiler - -> Set UnitId -- ^ Dependencies + -> UnitIdSet -- ^ Dependencies -> Stream IO RawCmmGroup a -- Compiled C-- -> IO (FilePath, (Bool{-stub_h_exists-}, Maybe FilePath{-stub_c_exists-}), @@ -161,11 +161,11 @@ outputC :: Logger -> DynFlags -> FilePath -> Stream IO RawCmmGroup a - -> Set UnitId + -> UnitIdSet -> IO a outputC logger dflags filenm cmm_stream unit_deps = withTiming logger (text "C codegen") (\a -> seq a () {- FIXME -}) $ do - let pkg_names = map unitIdString (Set.toAscList unit_deps) + let pkg_names = map unitIdString (uniqDSetToAscList unit_deps) doOutput filenm $ \ h -> do hPutStr h ("/* GHC_PACKAGES " ++ unwords pkg_names ++ "\n*/\n") hPutStr h "#include \"Stg.h\"\n" ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -127,7 +127,7 @@ hsc_HUE = ue_currentHomeUnitEnv . hsc_unit_env hsc_HUG :: HscEnv -> HomeUnitGraph hsc_HUG = ue_home_unit_graph . hsc_unit_env -hsc_all_home_unit_ids :: HscEnv -> Set.Set UnitId +hsc_all_home_unit_ids :: HscEnv -> UnitIdSet hsc_all_home_unit_ids = unitEnv_keys . hsc_HUG hscUpdateHPT_lazy :: (HomePackageTable -> HomePackageTable) -> HscEnv -> HscEnv ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -245,6 +245,7 @@ import GHC.Types.Name.Ppr import GHC.Types.Name.Set (NonCaffySet) import GHC.Types.TyThing import GHC.Types.HpcInfo +import GHC.Types.Unique.DSet import GHC.Utils.Fingerprint ( Fingerprint ) import GHC.Utils.Panic @@ -274,7 +275,6 @@ import Data.IORef import System.FilePath as FilePath import System.Directory import qualified Data.Set as S -import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) import Data.Bifunctor (first) @@ -1457,15 +1457,15 @@ checkSafeImports tcg_env clearDiagnostics -- Check safe imports are correct - safePkgs <- S.fromList <$> mapMaybeM checkSafe safeImps + safePkgs <- mkUniqDSet <$> mapMaybeM checkSafe safeImps safeErrs <- getDiagnostics clearDiagnostics -- Check non-safe imports are correct if inferring safety -- See the Note [Safe Haskell Inference] (infErrs, infPkgs) <- case (safeInferOn dflags) of - False -> return (emptyMessages, S.empty) - True -> do infPkgs <- S.fromList <$> mapMaybeM checkSafe regImps + False -> return (emptyMessages, emptyUniqDSet) + True -> do infPkgs <- mkUniqDSet <$> mapMaybeM checkSafe regImps infErrs <- getDiagnostics clearDiagnostics return (infErrs, infPkgs) @@ -1516,12 +1516,12 @@ checkSafeImports tcg_env checkSafe (m, l, _) = fst `fmap` hscCheckSafe' m l -- what pkg's to add to our trust requirements - pkgTrustReqs :: DynFlags -> Set UnitId -> Set UnitId -> + pkgTrustReqs :: DynFlags -> UnitIdSet -> UnitIdSet -> Bool -> ImportAvails pkgTrustReqs dflags req inf infPassed | safeInferOn dflags && not (safeHaskellModeEnabled dflags) && infPassed = emptyImportAvails { - imp_trust_pkgs = req `S.union` inf + imp_trust_pkgs = req `unionUniqDSets` inf } pkgTrustReqs dflags _ _ _ | safeHaskell dflags == Sf_Unsafe = emptyImportAvails @@ -1540,12 +1540,12 @@ hscCheckSafe hsc_env m l = runHsc hsc_env $ do return $ isEmptyMessages errs -- | Return if a module is trusted and the pkgs it depends on to be trusted. -hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, Set UnitId) +hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, UnitIdSet) hscGetSafe hsc_env m l = runHsc hsc_env $ do (self, pkgs) <- hscCheckSafe' m l good <- isEmptyMessages `fmap` getDiagnostics clearDiagnostics -- don't want them printed... - let pkgs' | Just p <- self = S.insert p pkgs + let pkgs' | Just p <- self = addOneToUniqDSet pkgs p | otherwise = pkgs return (good, pkgs') @@ -1554,7 +1554,7 @@ hscGetSafe hsc_env m l = runHsc hsc_env $ do -- own package be trusted and a list of other packages required to be trusted -- (these later ones haven't been checked) but the own package trust has been. hscCheckSafe' :: Module -> SrcSpan - -> Hsc (Maybe UnitId, Set UnitId) + -> Hsc (Maybe UnitId, UnitIdSet) hscCheckSafe' m l = do hsc_env <- getHscEnv let home_unit = hsc_home_unit hsc_env @@ -1566,7 +1566,7 @@ hscCheckSafe' m l = do -- Not necessary if that is reflected in dependencies | otherwise -> return (Just $ toUnitId (moduleUnit m), pkgs) where - isModSafe :: HomeUnit -> Module -> SrcSpan -> Hsc (Bool, Set UnitId) + isModSafe :: HomeUnit -> Module -> SrcSpan -> Hsc (Bool, UnitIdSet) isModSafe home_unit m l = do hsc_env <- getHscEnv dflags <- getDynFlags @@ -1648,10 +1648,10 @@ hscCheckSafe' m l = do -- | Check the list of packages are trusted. -checkPkgTrust :: Set UnitId -> Hsc () +checkPkgTrust :: UnitIdSet -> Hsc () checkPkgTrust pkgs = do hsc_env <- getHscEnv - let errors = S.foldr go emptyBag pkgs + let errors = foldr go emptyBag $ uniqDSetToAscList pkgs state = hsc_units hsc_env go pkg acc | unitIsTrusted $ unsafeLookupUnitId state pkg @@ -1699,7 +1699,7 @@ markUnsafeInfer tcg_env whyUnsafe = do False -> return tcg_env where - wiped_trust = (tcg_imports tcg_env) { imp_trust_pkgs = S.empty } + wiped_trust = (tcg_imports tcg_env) { imp_trust_pkgs = emptyUniqDSet } pprMod = ppr $ moduleName $ tcg_mod tcg_env whyUnsafe' df = vcat [ quotes pprMod <+> text "has been inferred as unsafe!" , text "Reason:" @@ -2060,7 +2060,7 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs in NoStubs `appendStubC` ip_init | otherwise = NoStubs (_output_filename, (_stub_h_exists, stub_c_exists), _foreign_fps, _caf_infos) - <- codeOutput logger tmpfs llvm_config dflags (hsc_units hsc_env) cmm_mod output_filename no_loc foreign_stubs [] S.empty + <- codeOutput logger tmpfs llvm_config dflags (hsc_units hsc_env) cmm_mod output_filename no_loc foreign_stubs [] emptyUniqDSet rawCmms return stub_c_exists where ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -107,6 +107,7 @@ import GHC.Types.SourceFile import GHC.Types.SourceError import GHC.Types.SrcLoc import GHC.Types.Unique.Map +import GHC.Types.Unique.DSet import GHC.Types.PkgQual import GHC.Unit @@ -490,7 +491,7 @@ load how_much = loadWithCache noIfaceCache how_much mkBatchMsg :: HscEnv -> Messager mkBatchMsg hsc_env = - if length (hsc_all_home_unit_ids hsc_env) > 1 + if sizeUniqDSet (hsc_all_home_unit_ids hsc_env) > 1 -- This also displays what unit each module is from. then batchMultiMsg else batchMsg @@ -1735,25 +1736,25 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] +checkHomeUnitsClosed :: UnitEnv -> UnitIdSet -> [(UnitId, UnitId)] -> [DriverMessages] -- Fast path, trivially closed. checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] + | sizeUniqDSet home_id_set == 1 = [] | otherwise = - let res = foldMap loop home_imp_ids + let res = foldl' (\acc ids -> unionUniqDSets acc $ loop ids) emptyUniqDSet home_imp_ids -- Now check whether everything which transitively depends on a home_unit is actually a home_unit -- These units are the ones which we need to load as home packages but failed to do for some reason, -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids + bad_unit_ids = res `minusUniqDSet` home_id_set + in if isEmptyUniqDSet bad_unit_ids then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] + else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (uniqDSetToAscList bad_unit_ids)] where rootLoc = mkGeneralSrcSpan (fsLit "") -- TODO: This could repeat quite a bit of work but I struggled to write this function. -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit + loop :: (UnitId, UnitId) -> UnitIdSet -- The units which transitively depend on a home unit loop (from_uid, uid) = let us = ue_findHomeUnitEnv from_uid ue in let um = unitInfoMap (homeUnitEnv_units us) in @@ -1761,20 +1762,21 @@ checkHomeUnitsClosed ue home_id_set home_imp_ids Nothing -> pprPanic "uid not found" (ppr uid) Just ui -> let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set + home_depends = mkUniqDSet depends `intersectUniqDSets` home_id_set + other_depends = mkUniqDSet depends `minusUniqDSet` home_id_set in -- Case 1: The unit directly depends on a home_id - if not (null home_depends) + if not (isEmptyUniqDSet home_depends) then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res + let res :: UnitIdSet + res = foldl' (\acc ide -> acc `unionUniqDSets` loop (from_uid, ide)) emptyUniqDSet $ uniqDSetToList other_depends + in addOneToUniqDSet res uid -- Case 2: Check the rest of the dependencies, and then see if any of them depended on else - let res = foldMap (loop . (from_uid,)) other_depends + let res = foldl' (\acc ide -> acc `unionUniqDSets` loop (from_uid, ide)) emptyUniqDSet $ uniqDSetToList other_depends in - if not (Set.null res) - then Set.insert uid res + if not (isEmptyUniqDSet res) + then addOneToUniqDSet res uid else res -- | Update the every ModSummary that is depended on ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -108,6 +108,7 @@ import GHC.Types.Target import GHC.Types.SrcLoc import GHC.Types.SourceFile import GHC.Types.SourceError +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -125,7 +126,6 @@ import Control.Monad import qualified Control.Monad.Catch as MC (handle) import Data.Maybe import Data.Either ( partitionEithers ) -import qualified Data.Set as Set import Data.Time ( getCurrentTime ) import GHC.Iface.Recomp @@ -408,8 +408,8 @@ link' logger tmpfs dflags unit_env batch_attempt_linking mHscMessager hpt home_mod_infos = eltsHpt hpt -- the packages we depend on - pkg_deps = Set.toList - $ Set.unions + pkg_deps = uniqDSetToAscList + $ unionManyUniqDSets $ fmap (dep_direct_pkgs . mi_deps . hm_iface) $ home_mod_infos ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Utils.Monad import GHC.Types.Name import GHC.Types.Name.Set ( NameSet, allUses ) import GHC.Types.Unique.Set +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -40,7 +41,6 @@ import Data.IORef import Data.List (sortBy) import Data.Map (Map) import qualified Data.Map as Map -import qualified Data.Set as Set import GHC.Linker.Types import GHC.Unit.Finder @@ -196,7 +196,7 @@ mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do mk_mod_usage_info :: UsageConfig -> HomeUnit - -> Set.Set UnitId + -> UnitIdSet -> Module -> ImportedMods -> NameSet @@ -255,7 +255,7 @@ mk_mod_usage_info uc home_unit home_unit_ids this_mod direct_imports used_names -- (need to recompile if its export list changes: export_fprint) mkUsage :: Module -> ModIface -> Maybe Usage mkUsage mod iface - | toUnitId (moduleUnit mod) `Set.notMember` home_unit_ids + | not $ toUnitId (moduleUnit mod) `elementOfUniqDSet` home_unit_ids = Just $ UsagePackageModule{ usg_mod = mod, usg_mod_hash = mod_hash, usg_safe = imp_safe } ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -504,7 +504,7 @@ loadInterface doc_str mod from -- overlapping instances. ; massertPpr ((isOneShot (ghcMode (hsc_dflags hsc_env))) - || moduleUnitId mod `notElem` hsc_all_home_unit_ids hsc_env + || not (moduleUnitId mod `elementOfUniqDSet` hsc_all_home_unit_ids hsc_env) || mod == gHC_PRIM) (text "Attempting to load home package interface into the EPS" $$ ppr hug $$ doc_str $$ ppr mod $$ ppr (moduleUnitId mod)) ; ignore_prags <- goptM Opt_IgnoreInterfacePragmas ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Types.SrcLoc import GHC.Types.Unique.Set import GHC.Types.Fixity.Env import GHC.Types.Unique.Map +import GHC.Types.Unique.DSet import GHC.Unit.External import GHC.Unit.Finder import GHC.Unit.State @@ -617,8 +618,8 @@ checkDependencies hsc_env summary iface all_home_units = hsc_all_home_unit_ids hsc_env units = hsc_units hsc_env prev_dep_mods = map (second gwib_mod) $ Set.toAscList $ dep_direct_mods (mi_deps iface) - prev_dep_pkgs = Set.toAscList (Set.union (dep_direct_pkgs (mi_deps iface)) - (dep_plugin_pkgs (mi_deps iface))) + prev_dep_pkgs = uniqDSetToAscList (unionUniqDSets (dep_direct_pkgs (mi_deps iface)) + (dep_plugin_pkgs (mi_deps iface))) implicit_deps = map (fsLit "Implicit",) (implicitPackageDeps dflags) @@ -633,7 +634,7 @@ checkDependencies hsc_env summary iface classify _ (Found _ mod) - | (toUnitId $ moduleUnit mod) `elem` all_home_units = Right (Left ((toUnitId $ moduleUnit mod), moduleName mod)) + | (toUnitId $ moduleUnit mod) `elementOfUniqDSet` all_home_units = Right (Left ((toUnitId $ moduleUnit mod), moduleName mod)) | otherwise = Right (Right (moduleNameFS (moduleName mod), toUnitId $ moduleUnit mod)) classify reason _ = Left (RecompBecause reason) ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -324,20 +324,20 @@ loadCmdLineLibs interp hsc_env = do loadCmdLineLibs' :: Interp -> HscEnv -> LoaderState -> IO LoaderState loadCmdLineLibs' interp hsc_env pls = snd <$> foldM - (\(done', pls') cur_uid -> load done' cur_uid pls') - (Set.empty, pls) - (hsc_all_home_unit_ids hsc_env) + (\(done', pls') cur_uid -> load done' cur_uid pls') + (emptyUniqDSet, pls) + (uniqDSetToList $ hsc_all_home_unit_ids hsc_env) where - load :: Set.Set UnitId -> UnitId -> LoaderState -> IO (Set.Set UnitId, LoaderState) - load done uid pls | uid `Set.member` done = return (done, pls) + load :: UnitIdSet -> UnitId -> LoaderState -> IO (UnitIdSet, LoaderState) + load done uid pls | uid `elementOfUniqDSet` done = return (done, pls) load done uid pls = do let hsc' = hscSetActiveUnitId uid hsc_env -- Load potential dependencies first (done', pls') <- foldM (\(done', pls') uid -> load done' uid pls') (done, pls) - (homeUnitDepends (hsc_units hsc')) + (homeUnitDepends (hsc_units hsc')) pls'' <- loadCmdLineLibs'' interp hsc' pls' - return $ (Set.insert uid done', pls'') + return $ (addOneToUniqDSet done' uid, pls'') loadCmdLineLibs'' :: Interp @@ -685,7 +685,7 @@ getLinkDeps :: HscEnv -> Maybe FilePath -- replace object suffixes? -> SrcSpan -- for error messages -> [Module] -- If you need these - -> IO ([Linkable], [Linkable], [UnitId], UniqDSet UnitId) -- ... then link these first + -> IO ([Linkable], [Linkable], [UnitId], UnitIdSet) -- ... then link these first -- The module and package dependencies for the needed modules are returned. -- See Note [Object File Dependencies] -- Fails with an IO exception if it can't find enough files @@ -737,7 +737,7 @@ getLinkDeps hsc_env pls replace_osuf span mods -- It is also a matter of correctness to use the module graph so that dependencies between home units -- is resolved correctly. - make_deps_loop :: (UniqDSet UnitId, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UniqDSet UnitId, Set.Set NodeKey) + make_deps_loop :: (UnitIdSet, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UnitIdSet, Set.Set NodeKey) make_deps_loop found [] = found make_deps_loop found@(found_units, found_mods) (nk:nexts) | NodeKey_Module nk `Set.member` found_mods = make_deps_loop found nexts @@ -766,7 +766,7 @@ getLinkDeps hsc_env pls replace_osuf span mods HsBootFile -> link_boot_mod_error (mi_module iface) _ -> return $ Just (mi_module iface) - in (mkUniqDSet $ Set.toList $ dep_direct_pkgs (mi_deps iface),) <$> mmod + in (dep_direct_pkgs (mi_deps iface),) <$> mmod Nothing -> let err = text "getLinkDeps: Home module not loaded" <+> ppr (gwib_mod gwib) <+> ppr uid in throwGhcExceptionIO (ProgramError (showSDoc dflags err)) @@ -780,9 +780,9 @@ getLinkDeps hsc_env pls replace_osuf span mods -- dependencies of that. Hence we need to traverse the dependency -- tree recursively. See bug #936, testcase ghci/prog007. follow_deps :: [Module] -- modules to follow - -> UniqDSet Module -- accum. module dependencies - -> UniqDSet UnitId -- accum. package dependencies - -> IO ([Module], UniqDSet UnitId) -- result + -> UniqDSet Module -- accum. module dependencies + -> UnitIdSet -- accum. package dependencies + -> IO ([Module], UnitIdSet) -- result follow_deps [] acc_mods acc_pkgs = return (uniqDSetToList acc_mods, acc_pkgs) follow_deps (mod:mods) acc_mods acc_pkgs @@ -814,7 +814,7 @@ getLinkDeps hsc_env pls replace_osuf span mods acc_mods' = case hsc_home_unit_maybe hsc_env of Nothing -> acc_mods Just home_unit -> addListToUniqDSet acc_mods (mod : map (mkHomeModule home_unit) mod_deps) - acc_pkgs' = addListToUniqDSet acc_pkgs (Set.toList pkg_deps) + acc_pkgs' = addListToUniqDSet acc_pkgs (uniqDSetToList pkg_deps) case hsc_home_unit_maybe hsc_env of Just home_unit | isHomeUnit home_unit pkg -> follow_deps (mod_deps' ++ mods) ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -37,7 +37,7 @@ module GHC.Linker.Types where import GHC.Prelude -import GHC.Unit ( UnitId, Module ) +import GHC.Unit ( UnitId, Module, UnitIdSet ) import GHC.ByteCode.Types ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type ( Fingerprint ) import GHCi.RemoteTypes ( ForeignHValue ) @@ -53,7 +53,6 @@ import Control.Concurrent.MVar import Data.Time ( UTCTime ) import Data.Maybe import GHC.Unit.Module.Env -import GHC.Types.Unique.DSet import GHC.Types.Unique.DFM import GHC.Unit.Module.WholeCoreBindings @@ -146,7 +145,7 @@ data LoadedPkgInfo { loaded_pkg_uid :: !UnitId , loaded_pkg_hs_objs :: ![LibrarySpec] , loaded_pkg_non_hs_objs :: ![LibrarySpec] - , loaded_pkg_trans_deps :: UniqDSet UnitId + , loaded_pkg_trans_deps :: UnitIdSet } instance Outputable LoadedPkgInfo where ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -75,6 +75,7 @@ import GHC.Types.HpcInfo import GHC.Types.Error import GHC.Types.PkgQual import GHC.Types.GREInfo (ConInfo(..)) +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Module.Warnings @@ -213,8 +214,8 @@ rnImports imports = do let merged_import_avail = clobberSourceImports imp_avails dflags <- getDynFlags let final_import_avail = - merged_import_avail { imp_dep_direct_pkgs = S.fromList (implicitPackageDeps dflags) - `S.union` imp_dep_direct_pkgs merged_import_avail} + merged_import_avail { imp_dep_direct_pkgs = mkUniqDSet (implicitPackageDeps dflags) + `unionUniqDSets` imp_dep_direct_pkgs merged_import_avail} return (decls, rdr_env, final_import_avail, hpc_usage) where @@ -494,7 +495,7 @@ renamePkgQual unit_env mn mb_pkg = case mb_pkg of -- | Calculate the 'ImportAvails' induced by an import of a particular -- interface, but without 'imp_mods'. calculateAvails :: HomeUnit - -> S.Set UnitId + -> UnitIdSet -> ModIface -> IsSafeImport -> IsBootInterface @@ -549,7 +550,7 @@ calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by -- Trusted packages are a lot like orphans. trusted_pkgs | mod_safe' = dep_trusted_pkgs deps - | otherwise = S.empty + | otherwise = emptyUniqDSet pkg = moduleUnit (mi_module iface) @@ -562,11 +563,11 @@ calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by | isHomeUnit home_unit pkg = ptrust | otherwise = False - dependent_pkgs = if toUnitId pkg `S.member` other_home_units - then S.empty - else S.singleton ipkg + dependent_pkgs = if toUnitId pkg `elementOfUniqDSet` other_home_units + then emptyUniqDSet + else unitUniqDSet ipkg - direct_mods = mkModDeps $ if toUnitId pkg `S.member` other_home_units + direct_mods = mkModDeps $ if toUnitId pkg `elementOfUniqDSet` other_home_units then S.singleton (moduleUnitId imp_mod, (GWIB (moduleName imp_mod) want_boot)) else S.empty ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -148,6 +148,7 @@ import GHC.Types.Id.Info( IdDetails(..) ) import GHC.Types.Var.Env import GHC.Types.TypeEnv import GHC.Types.Unique.FM +import GHC.Types.Unique.DSet import GHC.Types.Name import GHC.Types.Name.Env import GHC.Types.Name.Set @@ -185,7 +186,6 @@ import Data.List ( sortBy, sort ) import Data.List.NonEmpty ( NonEmpty (..) ) import qualified Data.List.NonEmpty as NE import Data.Ord -import qualified Data.Set as S import Data.Traversable ( for ) @@ -3134,7 +3134,7 @@ pprTcGblEnv (TcGblEnv { tcg_type_env = type_env, , text "Dependent modules:" <+> (ppr . sort . installedModuleEnvElts $ imp_direct_dep_mods imports) , text "Dependent packages:" <+> - ppr (S.toList $ imp_dep_direct_pkgs imports)] + ppr (uniqDSetToList $ imp_dep_direct_pkgs imports)] -- The use of sort is just to reduce unnecessary -- wobbling in testsuite output ===================================== compiler/GHC/Tc/Types.hs ===================================== @@ -142,6 +142,7 @@ import GHC.Types.SourceFile import GHC.Types.SrcLoc import GHC.Types.Var.Set import GHC.Types.Unique.FM +import GHC.Types.Unique.DSet import GHC.Types.Basic import GHC.Types.CostCentre.State import GHC.Types.HpcInfo @@ -1367,9 +1368,9 @@ plusModDeps = plusInstalledModuleEnv plus_mod_dep emptyImportAvails :: ImportAvails emptyImportAvails = ImportAvails { imp_mods = emptyModuleEnv, imp_direct_dep_mods = emptyInstalledModuleEnv, - imp_dep_direct_pkgs = S.empty, + imp_dep_direct_pkgs = emptyUniqDSet, imp_sig_mods = [], - imp_trust_pkgs = S.empty, + imp_trust_pkgs = emptyUniqDSet, imp_trust_own_pkg = False, imp_boot_mods = emptyInstalledModuleEnv, imp_orphs = [], @@ -1398,8 +1399,8 @@ plusImportAvails imp_orphs = orphs2, imp_finsts = finsts2 }) = ImportAvails { imp_mods = plusModuleEnv_C (++) mods1 mods2, imp_direct_dep_mods = ddmods1 `plusModDeps` ddmods2, - imp_dep_direct_pkgs = ddpkgs1 `S.union` ddpkgs2, - imp_trust_pkgs = tpkgs1 `S.union` tpkgs2, + imp_dep_direct_pkgs = ddpkgs1 `unionUniqDSets` ddpkgs2, + imp_trust_pkgs = tpkgs1 `unionUniqDSets` tpkgs2, imp_trust_own_pkg = tself1 || tself2, imp_boot_mods = srs1 `plusModDeps` srcs2, imp_sig_mods = unionListsOrd sig_mods1 sig_mods2, ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -32,6 +32,7 @@ module GHC.Types.Unique.DSet ( isEmptyUniqDSet, lookupUniqDSet, uniqDSetToList, + uniqDSetToAscList, partitionUniqDSet, mapUniqDSet ) where @@ -43,8 +44,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Unique.Set import GHC.Types.Unique +import GHC.Utils.Binary + import Data.Coerce import Data.Data +import Data.List (sort) -- See Note [UniqSet invariant] in GHC.Types.Unique.Set for why we want a newtype here. -- Beyond preserving invariants, we may also want to 'override' typeclass @@ -120,6 +124,9 @@ lookupUniqDSet = lookupUDFM . getUniqDSet uniqDSetToList :: UniqDSet a -> [a] uniqDSetToList = eltsUDFM . getUniqDSet +uniqDSetToAscList :: Ord a => UniqDSet a -> [a] +uniqDSetToAscList = sort . uniqDSetToList + partitionUniqDSet :: (a -> Bool) -> UniqDSet a -> (UniqDSet a, UniqDSet a) partitionUniqDSet p = coerce . partitionUDFM p . getUniqDSet @@ -140,3 +147,7 @@ instance Outputable a => Outputable (UniqDSet a) where pprUniqDSet :: (a -> SDoc) -> UniqDSet a -> SDoc pprUniqDSet f = braces . pprWithCommas f . uniqDSetToList + +instance (Uniquable a, Binary a) => Binary (UniqDSet a) where + put_ bh = put_ bh . uniqDSetToList + get bh = mkUniqDSet <$> get bh ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -81,6 +81,7 @@ import GHC.Utils.Misc (HasDebugCallStack) import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Utils.Panic (pprPanic) +import GHC.Types.Unique.DSet import GHC.Unit.Module.ModIface import GHC.Unit.Module import qualified Data.Set as Set @@ -339,8 +340,8 @@ unitEnv_lookup_maybe u env = Map.lookup u (unitEnv_graph env) unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v unitEnv_lookup u env = fromJust $ unitEnv_lookup_maybe u env -unitEnv_keys :: UnitEnvGraph v -> Set.Set UnitEnvGraphKey -unitEnv_keys env = Map.keysSet (unitEnv_graph env) +unitEnv_keys :: UnitEnvGraph v -> UnitIdSet +unitEnv_keys env = mkUniqDSet $ Map.keys (unitEnv_graph env) unitEnv_elts :: UnitEnvGraph v -> [(UnitEnvGraphKey, v)] unitEnv_elts env = Map.toList (unitEnv_graph env) @@ -443,7 +444,7 @@ ue_unitHomeUnit_maybe uid ue_env = ue_unitHomeUnit :: UnitId -> UnitEnv -> HomeUnit ue_unitHomeUnit uid ue_env = homeUnitEnv_unsafeHomeUnit $ ue_findHomeUnitEnv uid ue_env -ue_all_home_unit_ids :: UnitEnv -> Set.Set UnitId +ue_all_home_unit_ids :: UnitEnv -> UnitIdSet ue_all_home_unit_ids = unitEnv_keys . ue_home_unit_graph -- ------------------------------------------------------- -- Query and modify the currently active unit ===================================== compiler/GHC/Unit/Module/Deps.hs ===================================== @@ -28,6 +28,7 @@ import GHC.Unit.Module.Imported import GHC.Unit.Module import GHC.Unit.Home import GHC.Unit.State +import GHC.Types.Unique.DSet import GHC.Utils.Fingerprint import GHC.Utils.Binary @@ -53,13 +54,13 @@ data Dependencies = Deps -- ^ All home-package modules which are directly imported by this one. -- This may include modules from other units when using multiple home units - , dep_direct_pkgs :: Set UnitId + , dep_direct_pkgs :: UnitIdSet -- ^ All packages directly imported by this module -- I.e. packages to which this module's direct imports belong. -- Does not include other home units when using multiple home units. -- Modules from these units will go in `dep_direct_mods` - , dep_plugin_pkgs :: Set UnitId + , dep_plugin_pkgs :: UnitIdSet -- ^ All units needed for plugins ------------------------------------ @@ -69,7 +70,7 @@ data Dependencies = Deps -- ^ Transitive closure of hsig files in the home package - , dep_trusted_pkgs :: Set UnitId + , dep_trusted_pkgs :: UnitIdSet -- Packages which we are required to trust -- when the module is imported as a safe import -- (Safe Haskell). See Note [Tracking Trust Transitively] in GHC.Rename.Names @@ -110,7 +111,7 @@ data Dependencies = Deps mkDependencies :: HomeUnit -> Module -> ImportAvails -> [Module] -> Dependencies mkDependencies home_unit mod imports plugin_mods = let (home_plugins, external_plugins) = partition (isHomeUnit home_unit . moduleUnit) plugin_mods - plugin_units = Set.fromList (map (toUnitId . moduleUnit) external_plugins) + plugin_units = mkUniqDSet (map (toUnitId . moduleUnit) external_plugins) all_direct_mods = foldr (\mn m -> extendInstalledModuleEnv m mn (GWIB (moduleName mn) NotBoot)) (imp_direct_dep_mods imports) (map (fmap toUnitId) home_plugins) @@ -197,12 +198,12 @@ instance Binary Dependencies where noDependencies :: Dependencies noDependencies = Deps - { dep_direct_mods = Set.empty - , dep_direct_pkgs = Set.empty - , dep_plugin_pkgs = Set.empty + { dep_direct_mods = mempty + , dep_direct_pkgs = emptyUniqDSet + , dep_plugin_pkgs = emptyUniqDSet , dep_sig_mods = [] - , dep_boot_mods = Set.empty - , dep_trusted_pkgs = Set.empty + , dep_boot_mods = mempty + , dep_trusted_pkgs = emptyUniqDSet , dep_orphs = [] , dep_finsts = [] } @@ -220,11 +221,11 @@ pprDeps unit_state (Deps { dep_direct_mods = dmods = pprWithUnitState unit_state $ vcat [text "direct module dependencies:" <+> ppr_set ppr_mod dmods, text "boot module dependencies:" <+> ppr_set ppr bmods, - text "direct package dependencies:" <+> ppr_set ppr pkgs, - text "plugin package dependencies:" <+> ppr_set ppr plgns, - if null tps + text "direct package dependencies:" <+> ppr_unitIdSet ppr pkgs, + text "plugin package dependencies:" <+> ppr_unitIdSet ppr plgns, + if isEmptyUniqDSet tps then empty - else text "trusted package dependencies:" <+> ppr_set ppr tps, + else text "trusted package dependencies:" <+> ppr_unitIdSet ppr tps, text "orphans:" <+> fsep (map ppr orphs), text "family instance modules:" <+> fsep (map ppr finsts) ] @@ -235,6 +236,9 @@ pprDeps unit_state (Deps { dep_direct_mods = dmods ppr_set :: Outputable a => (a -> SDoc) -> Set a -> SDoc ppr_set w = fsep . fmap w . Set.toAscList + ppr_unitIdSet :: (UnitId -> SDoc) -> UnitIdSet -> SDoc + ppr_unitIdSet w = fsep . fmap w . sort . uniqDSetToList + -- | Records modules for which changes may force recompilation of this module -- See wiki: https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/recompilation-avoidance -- @@ -491,7 +495,7 @@ data ImportAvails imp_direct_dep_mods :: InstalledModuleEnv ModuleNameWithIsBoot, -- ^ Home-package modules directly imported by the module being compiled. - imp_dep_direct_pkgs :: Set UnitId, + imp_dep_direct_pkgs :: UnitIdSet, -- ^ Packages directly needed by the module being compiled imp_trust_own_pkg :: Bool, @@ -502,7 +506,7 @@ data ImportAvails -- Transitive information below here - imp_trust_pkgs :: Set UnitId, + imp_trust_pkgs :: UnitIdSet, -- ^ This records the -- packages the current module needs to trust for Safe Haskell -- compilation to succeed. A package is required to be trusted if ===================================== compiler/GHC/Unit/Module/ModGuts.hs ===================================== @@ -37,8 +37,6 @@ import GHC.Types.SourceFile ( HscSource(..), hscSourceToIsBoot ) import GHC.Types.SrcLoc import GHC.Types.CostCentre -import Data.Set (Set) - -- | A ModGuts is carried through the compiler, accumulating stuff as it goes -- There is only one ModGuts at any time, the one for the module @@ -137,7 +135,7 @@ data CgGuts cg_ccs :: [CostCentre], -- List of cost centres used in bindings and rules cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs cg_foreign_files :: ![(ForeignSrcLang, FilePath)], - cg_dep_pkgs :: !(Set UnitId), -- ^ Dependent packages, used to + cg_dep_pkgs :: !UnitIdSet, -- ^ Dependent packages, used to -- generate #includes for C code gen cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information cg_modBreaks :: !(Maybe ModBreaks), -- ^ Module breakpoints ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -346,10 +346,10 @@ data UnitConfig = UnitConfig , unitConfigFlagsIgnored :: [IgnorePackageFlag] -- ^ Ignored units , unitConfigFlagsTrusted :: [TrustFlag] -- ^ Trusted units , unitConfigFlagsPlugins :: [PackageFlag] -- ^ Plugins exposed units - , unitConfigHomeUnits :: Set.Set UnitId + , unitConfigHomeUnits :: UnitIdSet } -initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> UnitConfig +initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> UnitIdSet -> UnitConfig initUnitConfig dflags cached_dbs home_units = let !hu_id = homeUnitId_ dflags !hu_instanceof = homeUnitInstanceOf_ dflags @@ -626,7 +626,7 @@ listUnitInfo state = nonDetEltsUniqMap (unitInfoMap state) -- 'initUnits' can be called again subsequently after updating the -- 'packageFlags' field of the 'DynFlags', and it will update the -- 'unitState' in 'DynFlags'. -initUnits :: Logger -> DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> IO ([UnitDatabase UnitId], UnitState, HomeUnit, Maybe PlatformConstants) +initUnits :: Logger -> DynFlags -> Maybe [UnitDatabase UnitId] -> UnitIdSet -> IO ([UnitDatabase UnitId], UnitState, HomeUnit, Maybe PlatformConstants) initUnits logger dflags cached_dbs home_units = do let forceUnitInfoMap (state, _) = unitInfoMap state `seq` () @@ -1362,7 +1362,7 @@ mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..] merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do debugTraceMsg logger 2 $ text "loading package database" <+> text db_path - forM_ (Set.toList override_set) $ \pkg -> + forM_ (uniqDSetToList override_set) $ \pkg -> debugTraceMsg logger 2 $ text "package" <+> ppr pkg <+> text "overrides a previously defined package" @@ -1374,9 +1374,9 @@ mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..] -- The set of UnitIds which appear in both db and pkgs. These are the -- ones that get overridden. Compute this just to give some -- helpful debug messages at -v2 - override_set :: Set UnitId - override_set = Set.intersection (nonDetUniqMapToKeySet db_map) - (nonDetUniqMapToKeySet pkg_map) + override_set :: UnitIdSet + override_set = intersectUniqDSets (mkUniqDSet $ nonDetKeysUniqMap db_map) + (mkUniqDSet $ nonDetKeysUniqMap pkg_map) -- Now merge the sets together (NB: in case of duplicate, -- first argument preferred) @@ -1688,7 +1688,7 @@ mkUnitState logger cfg = do let !state = UnitState { preloadUnits = dep_preload , explicitUnits = explicit_pkgs - , homeUnitDepends = Set.toList home_unit_deps + , homeUnitDepends = uniqDSetToList home_unit_deps , unitInfoMap = pkg_db , preloadClosure = emptyUniqSet , moduleNameProvidersMap = mod_map @@ -1701,15 +1701,15 @@ mkUnitState logger cfg = do } return (state, raw_dbs) -selectHptFlag :: Set.Set UnitId -> PackageFlag -> Bool -selectHptFlag home_units (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `Set.member` home_units = True +selectHptFlag :: UnitIdSet -> PackageFlag -> Bool +selectHptFlag home_units (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `elementOfUniqDSet` home_units = True selectHptFlag _ _ = False -selectHomeUnits :: Set.Set UnitId -> [PackageFlag] -> Set.Set UnitId -selectHomeUnits home_units flags = foldl' go Set.empty flags +selectHomeUnits :: UnitIdSet -> [PackageFlag] -> UnitIdSet +selectHomeUnits home_units flags = foldl' go emptyUniqDSet flags where - go :: Set.Set UnitId -> PackageFlag -> Set.Set UnitId - go cur (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `Set.member` home_units = Set.insert (toUnitId uid) cur + go :: UnitIdSet -> PackageFlag -> UnitIdSet + go cur (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `elementOfUniqDSet` home_units = addOneToUniqDSet cur (toUnitId uid) -- MP: This does not yet support thinning/renaming go cur _ = cur ===================================== compiler/GHC/Unit/Types.hs ===================================== @@ -33,6 +33,7 @@ module GHC.Unit.Types , GenInstantiatedUnit (..) , InstantiatedUnit , DefUnitId + , UnitIdSet , Instantiations , GenInstantiations , mkInstantiatedUnit @@ -538,6 +539,8 @@ pprUnitId (UnitId fs) = sdocOption sdocUnitIdForUser ($ fs) -- code for. type DefUnitId = Definite UnitId +type UnitIdSet = UniqDSet UnitId + unitIdString :: UnitId -> String unitIdString = unpackFS . unitIdFS ===================================== ghc/GHCi/UI.hs ===================================== @@ -105,6 +105,7 @@ import GHC.Utils.Misc import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Bag (unitBag) import qualified GHC.Data.Strict as Strict +import GHC.Types.Unique.DSet -- Haskell Libraries import System.Console.Haskeline as Haskeline @@ -125,7 +126,6 @@ import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef ) import Data.List ( elemIndices, find, intercalate, intersperse, minimumBy, isPrefixOf, isSuffixOf, nub, partition, sort, sortBy, (\\) ) import qualified Data.List.NonEmpty as NE -import qualified Data.Set as S import Data.Maybe import qualified Data.Map as M import Data.IntMap.Strict (IntMap) @@ -561,7 +561,7 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let in_multi = sizeUniqDSet (hsc_all_home_unit_ids hsc_env) > 1 empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, @@ -2568,15 +2568,15 @@ isSafeModule m = do -- print info to user... liftIO $ putStrLn $ "Trust type is (Module: " ++ trust ++ ", Package: " ++ pkg ++ ")" liftIO $ putStrLn $ "Package Trust: " ++ (if packageTrustOn dflags then "On" else "Off") - when (not $ S.null good) + when (not $ isEmptyUniqDSet good) (liftIO $ putStrLn $ "Trusted package dependencies (trusted): " ++ - (intercalate ", " $ map (showPpr dflags) (S.toList good))) - case msafe && S.null bad of + (intercalate ", " $ map (showPpr dflags) (uniqDSetToList good))) + case msafe && isEmptyUniqDSet bad of True -> liftIO $ putStrLn $ mname ++ " is trusted!" False -> do - when (not $ null bad) + when (not $ isEmptyUniqDSet bad) (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): " - ++ (intercalate ", " $ map (showPpr dflags) (S.toList bad))) + ++ (intercalate ", " $ map (showPpr dflags) (uniqDSetToList bad))) liftIO $ putStrLn $ mname ++ " is NOT trusted!" where @@ -2586,8 +2586,8 @@ isSafeModule m = do | isHomeModule (hsc_home_unit hsc_env) md = True | otherwise = unitIsTrusted $ unsafeLookupUnit (hsc_units hsc_env) (moduleUnit md) - tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (S.empty, S.empty) - | otherwise = S.partition part deps + tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (emptyUniqDSet, emptyUniqDSet) + | otherwise = partitionUniqDSet part deps where part pkg = unitIsTrusted $ unsafeLookupUnitId unit_state pkg unit_state = hsc_units hsc_env dflags = hsc_dflags hsc_env View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dc2c21f0770c9c38ddb4a8ff53b2c024160356a9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dc2c21f0770c9c38ddb4a8ff53b2c024160356a9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 15:14:50 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 11:14:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/js-identsSEV Message-ID: <64493feab7e7_178e74de373ff0169169c@gitlab.mail> Josh Meredith pushed new branch wip/js-identsSEV at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/js-identsSEV You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 15:20:37 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Wed, 26 Apr 2023 11:20:37 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/usage-env Message-ID: <64494145da5a9_178e74de374bf81693667@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/usage-env at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/usage-env You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 15:23:21 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 26 Apr 2023 11:23:21 -0400 Subject: [Git][ghc/ghc][wip/T23083] 6 commits: Cleanup a TODO introduced in 1f94e0f7 Message-ID: <644941e933497_178e74de7c49c41695868@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 6b28eeec by Sebastian Graf at 2023-04-26T16:44:44+02:00 Cleanup a TODO introduced in 1f94e0f7 The change must have slipped through review of !4412 - - - - - 912b8d67 by Sebastian Graf at 2023-04-26T16:44:45+02:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - 0543483b by Sebastian Graf at 2023-04-26T16:44:45+02:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - a588f6b1 by Sebastian Graf at 2023-04-26T16:44:45+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - 52af72cb by Sebastian Graf at 2023-04-26T17:23:14+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 1bc1af75 by Sebastian Graf at 2023-04-26T17:23:14+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62c23369514a68c7f6903062722c800ff6c6b686...1bc1af75b0505aaf3edc41ebcacaf23c19e01352 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62c23369514a68c7f6903062722c800ff6c6b686...1bc1af75b0505aaf3edc41ebcacaf23c19e01352 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 15:34:56 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Wed, 26 Apr 2023 11:34:56 -0400 Subject: [Git][ghc/ghc][wip/T23083] CorePrep: Eta expand arguments (#23083) Message-ID: <644944a099c22_178e74de885bb016962b8@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: e721cc6f by Sebastian Graf at 2023-04-26T17:34:47+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 10 changed files: - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1047,16 +1047,16 @@ it off at source. -} {-# INLINE trivial_expr_fold #-} -trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r +trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> (CoreExpr -> r) -> CoreExpr -> r -- ^ The worker function for Note [exprIsTrivial] and Note [getIdFromTrivialExpr] -- This is meant to have the code of both functions in one place and make it -- easy to derive custom predicates. -- -- (trivial_expr_fold k_id k_triv k_not_triv e) --- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping) +-- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping W such that e = W[x]) -- * returns (k_lit x) if `e` is a trivial literal `l` (with trivial wrapping) -- * returns k_triv if `e` is a literal, type, or coercion (with trivial wrapping) --- * returns k_not_triv otherwise +-- * returns (k_not_triv e') if e' is not trivial (with trivial wrapping W such that e = W[e']) -- -- where "trivial wrapping" is -- * Type application or abstraction @@ -1073,10 +1073,10 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial] go (Cast e _) = go e go (Case e _ _ []) = go e -- See Note [Empty case is trivial] - go _ = k_not_triv + go e = k_not_triv e exprIsTrivial :: CoreExpr -> Bool -exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e +exprIsTrivial e = trivial_expr_fold (const True) (const True) True (const False) e {- Note [getIdFromTrivialExpr] @@ -1097,12 +1097,12 @@ T12076lit for an example where this matters. getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id -- See Note [getIdFromTrivialExpr] -getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic panic e +getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic (const panic) e where panic = pprPanic "getIdFromTrivialExpr" (ppr e) getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id -getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing Nothing e +getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing (const Nothing) e {- ********************************************************************* * * ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -552,9 +552,11 @@ coreToStgApp f args ticks = do -- --------------------------------------------------------------------------- getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg -getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic try_string e where panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + try_string (Lit l at LitString{}) = StgLitArg l -- string literals are not considered trivial, but atomic + try_string _ = panic coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1445,12 +1445,33 @@ cpeArg env dmd arg ; if okCpeArg arg2 then do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } else return (floats2, arg2) } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1568,6 +1589,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1931,6 +1990,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1941,6 +2005,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,10 @@ +module T23083 where + +-- Just ($), but NOINLINE so that we don't inline it eagerly, subverting the +-- test case +($$) :: (a -> b) -> a -> b +($$) f x = f x +{-# NOINLINE ($$) #-} + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $$)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,47 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 34, types: 34, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 6, types: 5, coercions: 0, joins: 0/0} +(T23083.$$) [InlPrag=NOINLINE] :: forall a b. (a -> b) -> a -> b +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +(T23083.$$) = \ (@a) (@b) (f [Occ=Once1!] :: a -> b) (x [Occ=Once1] :: a) -> f x + +-- RHS size: {terms: 12, types: 12, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e721cc6f460f3c44e2ff3c846e8ac60e4a980e01 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e721cc6f460f3c44e2ff3c846e8ac60e4a980e01 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 15:43:59 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 11:43:59 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] Revert some things Message-ID: <644946bf51531_178e74dee95f0016966a1@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: 036a6bc5 by Rodrigo Mesquita at 2023-04-25T18:00:45+01:00 Revert some things - - - - - 3 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -30,7 +30,6 @@ module GHC.Cmm.CLabel ( mkApEntryLabel, mkApInfoTableLabel, mkClosureTableLabel, - mkShortConAppLabel, mkBytesLabel, mkLocalBlockLabel, @@ -522,8 +521,6 @@ data IdLabelInfo | ClosureTable -- ^ Table of closures for Enum tycons - | ShortConApp -- ^ Temporary name, temporary documentation. A special static closure for nullarydatacons - | Bytes -- ^ Content of a string literal. See -- Note [Bytes label]. | BlockInfoTable -- ^ Like LocalInfoTable but for a proc-point block @@ -557,7 +554,6 @@ instance Outputable IdLabelInfo where ppr (ConEntry mn) = text "ConEntry" <+> ppr mn ppr (ConInfoTable mn) = text "ConInfoTable" <+> ppr mn ppr ClosureTable = text "ClosureTable" - ppr ShortConApp = text "ShortConApp" -- ROMES:TODO: name ppr Bytes = text "Bytes" ppr BlockInfoTable = text "BlockInfoTable" ppr (IdTickyInfo info) = text "IdTickyInfo" <+> ppr info @@ -623,7 +619,6 @@ mkClosureLabel :: Name -> CafInfo -> CLabel mkInfoTableLabel :: Name -> CafInfo -> CLabel mkEntryLabel :: Name -> CafInfo -> CLabel mkClosureTableLabel :: Name -> CafInfo -> CLabel -mkShortConAppLabel :: Name -> CafInfo -> CLabel mkConInfoTableLabel :: Name -> ConInfoTableLocation -> CLabel mkBytesLabel :: Name -> CLabel mkClosureLabel name c = IdLabel name c Closure @@ -633,7 +628,6 @@ mkInfoTableLabel name c | otherwise = IdLabel name c LocalInfoTable mkEntryLabel name c = IdLabel name c Entry mkClosureTableLabel name c = IdLabel name c ClosureTable -mkShortConAppLabel name c = IdLabel name c ShortConApp -- Special case for the normal 'DefinitionSite' case so that the 'ConInfoTable' application can be floated to a CAF. mkConInfoTableLabel name DefinitionSite = IdLabel name NoCafRefs (ConInfoTable DefinitionSite) mkConInfoTableLabel name k = IdLabel name NoCafRefs (ConInfoTable k) @@ -786,7 +780,6 @@ isForeignLabel _lbl = False isStaticClosureLabel :: CLabel -> Bool -- Closure defined in haskell (.hs) isStaticClosureLabel (IdLabel _ _ Closure) = True -isStaticClosureLabel (IdLabel _ _ ShortConApp) = True -- Closure defined in cmm isStaticClosureLabel (CmmLabel _ _ _ CmmClosure) = True isStaticClosureLabel _lbl = False @@ -1258,7 +1251,6 @@ idInfoLabelType info = ConInfoTable {} -> DataLabel ClosureTable -> DataLabel IdTickyInfo{} -> DataLabel - ShortConApp -> DataLabel Bytes -> DataLabel _ -> CodeLabel @@ -1663,7 +1655,6 @@ ppIdFlavor x = pp_cSEP <> case x of UsageSite m n -> pprModule m <> pp_cSEP <> int n <> pp_cSEP <> text "con_info" ClosureTable -> text "closure_tbl" - ShortConApp -> text "special_con_app" -- ROMES:TODO: Name Bytes -> text "bytes" BlockInfoTable -> text "info" ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -233,7 +233,6 @@ mkModuleInit cost_centre_info this_mod hpc_info cgEnumerationTyCon :: TyCon -> FCode () cgEnumerationTyCon tycon = do platform <- getPlatform - -- ROMES:TODO: Kind of code I need to emit conapp declarations for nullary gadt emitRODataLits (mkClosureTableLabel (tyConName tycon) NoCafRefs) [ CmmLabelOff (mkClosureLabel (dataConName con) NoCafRefs) (tagForCon platform con) @@ -265,12 +264,6 @@ cgDataCon mn data_con , rep_ty <- typePrimRep (scaledThing ty) , not (isVoidRep rep_ty) ] - -- In the case of a data con that isn't nullary in its core - -- representation, but that has no zero-width args, we generate a - -- special static closure alongside its normal _closure - -- ROMES:TODO: Write a long note about it - ; when (not (isNullaryRepDataCon data_con) && hasNoNonZeroWidthArgs data_con) (cgNullaryDataConApp data_con) - ; emitClosureAndInfoTable platform dyn_info_tbl NativeDirectCall [] $ -- NB: the closure pointer is assumed *untagged* on -- entry to a constructor. If the pointer is tagged, ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -12,8 +12,7 @@ ----------------------------------------------------------------------------- module GHC.StgToCmm.DataCon ( - cgTopRhsCon, buildDynCon, bindConArgs, - cgNullaryDataConApp + cgTopRhsCon, buildDynCon, bindConArgs ) where import GHC.Prelude @@ -382,14 +381,6 @@ precomputedStaticConInfo_maybe cfg binder con [arg] precomputedStaticConInfo_maybe _ _ _ _ = Nothing --- Closely related to precomputed static things,,, write long note: ROMES:TODO -cgNullaryDataConApp :: DataCon -> FCode () -cgNullaryDataConApp con - = emitRODataLits (mkShortConAppLabel (dataConName con) NoCafRefs) - [ CmmLabel (mkConInfoTableLabel (dataConName con) DefinitionSite) - ] - - --------------------------------------------------------------- -- Binding constructor arguments --------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/036a6bc577e2655b3efac5ec14f3b6bf527d70fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/036a6bc577e2655b3efac5ec14f3b6bf527d70fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 16:31:03 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 12:31:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/jsSaturate Message-ID: <644951c7300b5_178e74df92296417050dd@gitlab.mail> Josh Meredith pushed new branch wip/jsSaturate at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/jsSaturate You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 17:00:15 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Wed, 26 Apr 2023 13:00:15 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] Implement simple C call Message-ID: <6449589f5b0c6_178e74e03df06417165ac@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: 4481208a by Sven Tennie at 2023-04-26T16:59:48+00:00 Implement simple C call - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -23,6 +23,7 @@ import GHC.Platform.Regs import GHC.Utils.Panic import GHC.Cmm.BlockId import GHC.Utils.Trace +import Debug.Trace -- | Don't try to compile all GHC Cmm files in the beginning. -- Ignore them. There's a flag to decide we really want to emit something. @@ -226,6 +227,7 @@ annExpr e instr {- debugIsOn -} = ANN (text . show $ e) instr generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) generateJumpTableForInstr _ = Nothing + genCCall :: ForeignTarget -- function to call -> [CmmFormal] -- where to put the result @@ -251,9 +253,10 @@ genCCall target dest_regs arg_regs = do (CmmLit (CmmLabel lbl)) -> pure (TLabel lbl, nilOL) -- ... if it's not a label--well--let's compute the expression into a -- register and jump to that. See Note [PLT vs GOT relocations] - e -> do - (reg, _format, reg_code) <- getSomeReg expr - pure (TReg reg, reg_code) + e -> trace ("genCCall - target : " ++ show e ++ " - " ++ showPprUnsafe (pdoc platform e)) $ + do + (reg, _format, reg_code) <- getSomeReg expr + pure (TReg reg, reg_code) -- compute the code and register logic for all arg_regs. -- this will give us the format information to match on. arg_regs' <- mapM getSomeReg arg_regs @@ -287,15 +290,20 @@ genCCall target dest_regs arg_regs = do -- , POP_STACK_FRAME -- , DELTA 0 ] - let code = call_target_code -- compute the label (possibly into a register) - `appOL` moveStackDown (stackSpace `div` 8) - `appOL` passArgumentsCode -- put the arguments into x0, ... - `appOL` (unitOL $ J call_target) -- jump + traceM $ "genCCall - call_target : " ++ show call_target + + let code = call_target_code -- compute the label (possibly into a register) + `appOL` passArgumentsCode -- put the arguments into a0, ... + `appOL` mkCall call_target -- jump `appOL` readResultsCode -- parse the results into registers - `appOL` moveStackUp (stackSpace `div` 8) return code e -> error $ "TODO genCCall" ++ showSDocUnsafe (pdoc platform e) where + mkCall :: Target -> OrdList Instr + mkCall (TLabel label) = unitOL $ CALL label + mkCall (TReg reg) = unitOL $ JALR reg + mkCall t = error $ "mkCall - " ++ show t + passArguments :: [Reg] -> [Reg] -> [(Reg, Format, ForeignHint, InstrBlock)] -> Int -> [Reg] -> InstrBlock -> NatM (Int, [Reg], InstrBlock) passArguments _ _ [] stackSpace accumRegs accumCode = return (stackSpace, accumRegs, accumCode) passArguments (gpReg:gpRegs) fpRegs ((r, format, hint, code_r):args) stackSpace accumRegs accumCode | isIntFormat format = do ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -42,6 +42,9 @@ data Instr LA Reg CLabel | -- jump pseudo-instruction J Target + | -- call pseudo-instruction + CALL CLabel + | JALR Reg | -- copy register MV Reg Reg @@ -49,6 +52,7 @@ data Target = TBlock BlockId | TReg Reg | TLabel CLabel + deriving Show allocMoreStack :: Int -> @@ -104,6 +108,8 @@ regUsageOfInstr platform instr = case instr of -- Looks like J doesn't change registers (beside PC) -- This might be wrong. J {} -> none + CALL {} -> usage([],[(RegReal . realRegSingle) 1]) -- call sets register x1 (ra) + JALR reg -> usage([reg],[(RegReal . realRegSingle) 1]) -- call sets register x1 (ra) where none = usage ([], []) -- filtering the usage is necessary, otherwise the register @@ -138,6 +144,8 @@ patchRegsOfInstr instr env = case instr of -- Looks like J doesn't change registers (beside PC) -- This might be wrong. J {} -> instr + CALL {} -> instr + JALR reg -> JALR (env reg) MV dst src -> MV (env dst) (env src) -- | Checks whether this instruction is a jump/branch instruction. @@ -150,8 +158,12 @@ isJumpishInstr ANN {} = False isJumpishInstr DELTA {} = False isJumpishInstr LDATA {} = False isJumpishInstr NEWBLOCK {} = False +isJumpishInstr MV {} = False +isJumpishInstr LA {} = False isJumpishInstr LI {} = False isJumpishInstr J {} = True +isJumpishInstr CALL {} = True +isJumpishInstr JALR {} = True -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the @@ -224,6 +236,8 @@ isMetaInstr instr = LA {} -> False J {} -> False MV {} -> False + CALL {} -> False + JALR {} -> False -- | Copy the value in a register to another one. -- Must work for all register classes. @@ -251,6 +265,8 @@ takeRegRegMoveInstr LI {} = Nothing takeRegRegMoveInstr LA {} = Nothing takeRegRegMoveInstr J {} = Nothing takeRegRegMoveInstr (MV dst src) = Just (src, dst) +takeRegRegMoveInstr CALL {} = Nothing +takeRegRegMoveInstr JALR {} = Nothing -- | Make an unconditional jump instruction. -- For architectures with branch delay slots, its ok to put ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -142,9 +142,11 @@ pprInstr platform instr = case instr of PUSH_STACK_FRAME -> error "pprInstr: PUSH_STACK_FRAME" POP_STACK_FRAME -> error "pprInstr: POP_STACK_FRAME" J label -> line $ pprJ label + CALL label -> line $ text "\tcall" <+> pprAsmLabel platform label + JALR reg -> line $ text "\tjalr" <+> text "ra" <> char ',' <+> pprReg reg <> char ',' <+> char '0' LI reg immediate -> line $ pprLI reg immediate - LA reg label -> error $ "pprInstr: LA " ++ show reg ++ " " ++ show label - MV dst src -> error $ "pprInstr: MV " ++ show dst ++ " " ++ show src + LA reg label -> line $ text "\tla" <+> pprReg reg <> char ',' <+> pprAsmLabel platform label + MV dst src -> line $ text "\tmv" <+> pprReg dst <> char ',' <+> pprReg src where pprLI :: IsLine doc => Reg -> Integer -> doc pprLI reg immediate = text "\tli" <+> pprReg reg <> char ',' <+> (text.show) immediate View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4481208a93ddfe0a1d7ba979aff80928b2955354 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4481208a93ddfe0a1d7ba979aff80928b2955354 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 17:55:53 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Wed, 26 Apr 2023 13:55:53 -0400 Subject: [Git][ghc/ghc][wip/unitidset] lint Message-ID: <644965a91d723_178e74e14054701733413@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: 926d7960 by Josh Meredith at 2023-04-26T17:55:44+00:00 lint - - - - - 1 changed file: - compiler/GHC/Driver/CodeOutput.hs Changes: ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -61,7 +61,6 @@ import GHC.Types.Unique.DSet import System.Directory import System.FilePath import System.IO -import Data.List ( sort ) {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/926d79605354edc20dabe68381a39f59029b5945 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/926d79605354edc20dabe68381a39f59029b5945 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 18:51:21 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 26 Apr 2023 14:51:21 -0400 Subject: [Git][ghc/ghc][master] DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <644972a9aafbb_178e74e234a318174848a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 14 changed files: - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Demand.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs - testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr - testsuite/tests/stranal/should_compile/T18894.stderr - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T23208.hs - + testsuite/tests/stranal/should_run/T23208.stderr - + testsuite/tests/stranal/should_run/T23208_Lib.hs - testsuite/tests/stranal/should_run/all.T Changes: ===================================== compiler/GHC/Core/Opt/DmdAnal.hs ===================================== @@ -97,28 +97,35 @@ dmdAnalProgram opts fam_envs rules binds where anal_body env' | WithDmdType body_ty bs' <- go env' bs - = WithDmdType (add_exported_uses env' body_ty (bindersOf b)) bs' + = WithDmdType (body_ty `plusDmdType` keep_alive_roots env' (bindersOf b)) bs' cons_up :: WithDmdType (DmdResult b [b]) -> WithDmdType [b] cons_up (WithDmdType dmd_ty (R b' bs')) = WithDmdType dmd_ty (b' : bs') - add_exported_uses :: AnalEnv -> DmdType -> [Id] -> DmdType - add_exported_uses env = foldl' (add_exported_use env) - - -- If @e@ is denoted by @dmd_ty@, then @add_exported_use _ dmd_ty id@ - -- corresponds to the demand type of @(id, e)@, but is a lot more direct. - -- See Note [Analysing top-level bindings]. - add_exported_use :: AnalEnv -> DmdType -> Id -> DmdType - add_exported_use env dmd_ty id - | isExportedId id || elemVarSet id rule_fvs - -- See Note [Absence analysis for stable unfoldings and RULES] - = dmd_ty `plusDmdType` fst (dmdAnalStar env topDmd (Var id)) - | otherwise - = dmd_ty + keep_alive_roots :: AnalEnv -> [Id] -> DmdEnv + -- See Note [Absence analysis for stable unfoldings and RULES] + -- Here we keep alive "roots", e.g., exported ids and stuff mentioned in + -- orphan RULES + keep_alive_roots env ids = plusDmdEnvs (map (demandRoot env) (filter is_root ids)) + + is_root :: Id -> Bool + is_root id = isExportedId id || elemVarSet id rule_fvs rule_fvs :: IdSet rule_fvs = rulesRhsFreeIds rules +demandRoot :: AnalEnv -> Id -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoot env id = fst (dmdAnalStar env topDmd (Var id)) + +demandRoots :: AnalEnv -> [Id] -> DmdEnv +-- See Note [Absence analysis for stable unfoldings and RULES] +demandRoots env roots = plusDmdEnvs (map (demandRoot env) roots) + +demandRootSet :: AnalEnv -> IdSet -> DmdEnv +demandRootSet env ids = demandRoots env (nonDetEltsUniqSet ids) + -- It's OK to use nonDetEltsUniqSet here because plusDmdType is commutative + -- | We attach useful (e.g. not 'topDmd') 'idDemandInfo' to top-level bindings -- that satisfy this function. -- @@ -343,7 +350,7 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec -- See Note [Absence analysis for stable unfoldings and RULES] rule_fvs = bndrRuleAndUnfoldingIds id - final_ty = body_ty' `plusDmdType` rhs_ty `keepAliveDmdType` rule_fvs + final_ty = body_ty' `plusDmdType` rhs_ty `plusDmdType` demandRootSet env rule_fvs -- | Let bindings can be processed in two ways: -- Down (RHS before body) or Up (body before RHS). @@ -360,18 +367,18 @@ dmdAnalBindLetUp top_lvl env id rhs anal_body = WithDmdType final_ty (R (NonRec dmdAnalBindLetDown :: TopLevelFlag -> AnalEnv -> SubDemand -> CoreBind -> (AnalEnv -> WithDmdType a) -> WithDmdType (DmdResult CoreBind a) dmdAnalBindLetDown top_lvl env dmd bind anal_body = case bind of NonRec id rhs - | (env', lazy_fv, id1, rhs1) <- + | (env', weak_fv, id1, rhs1) <- dmdAnalRhsSig top_lvl NonRecursive env dmd id rhs - -> do_rest env' lazy_fv [(id1, rhs1)] (uncurry NonRec . only) + -> do_rest env' weak_fv [(id1, rhs1)] (uncurry NonRec . only) Rec pairs - | (env', lazy_fv, pairs') <- dmdFix top_lvl env dmd pairs - -> do_rest env' lazy_fv pairs' Rec + | (env', weak_fv, pairs') <- dmdFix top_lvl env dmd pairs + -> do_rest env' weak_fv pairs' Rec where - do_rest env' lazy_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') + do_rest env' weak_fv pairs1 build_bind = WithDmdType final_ty (R (build_bind pairs2) body') where WithDmdType body_ty body' = anal_body env' -- see Note [Lazy and unleashable free variables] - dmd_ty = addLazyFVs body_ty lazy_fv + dmd_ty = addWeakFVs body_ty weak_fv WithDmdType final_ty id_dmds = findBndrsDmds env' dmd_ty (strictMap fst pairs1) -- Important to force this as build_bind might not force it. !pairs2 = strictZipWith do_one pairs1 id_dmds @@ -408,14 +415,14 @@ anticipateANF e n dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr - -> (PlusDmdArg, CoreExpr) + -> (DmdEnv, CoreExpr) dmdAnalStar env (n :* sd) e -- NB: (:*) expands AbsDmd and BotDmd as needed | WithDmdType dmd_ty e' <- dmdAnal env sd e , n' <- anticipateANF e n -- See Note [Anticipating ANF in demand analysis] -- and Note [Analysing with absent demand] - = (toPlusDmdArg $ multDmdType n' dmd_ty, e') + = (discardArgDmds $ multDmdType n' dmd_ty, e') -- Main Demand Analysis machinery dmdAnal, dmdAnal' :: AnalEnv @@ -428,13 +435,13 @@ dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $ dmdAnal' _ _ (Lit lit) = WithDmdType nopDmdType (Lit lit) dmdAnal' _ _ (Type ty) = WithDmdType nopDmdType (Type ty) -- Doesn't happen, in fact dmdAnal' _ _ (Coercion co) - = WithDmdType (unitDmdType (coercionDmdEnv co)) (Coercion co) + = WithDmdType (noArgsDmdType (coercionDmdEnv co)) (Coercion co) dmdAnal' env dmd (Var var) = WithDmdType (dmdTransform env var dmd) (Var var) dmdAnal' env dmd (Cast e co) - = WithDmdType (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co)) (Cast e' co) + = WithDmdType (dmd_ty `plusDmdType` coercionDmdEnv co) (Cast e' co) where WithDmdType dmd_ty e' = dmdAnal env dmd e @@ -532,7 +539,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt_con bndrs rhs]) = alt_ty2 WithDmdType scrut_ty scrut' = dmdAnal env scrut_sd scrut - res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = alt_ty3 `plusDmdType` discardArgDmds scrut_ty in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd @@ -569,7 +576,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) = deferAfterPreciseException alt_ty1 | otherwise = alt_ty1 - res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty + res_ty = scrut_ty `plusDmdType` discardArgDmds alt_ty2 in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut @@ -1030,7 +1037,7 @@ dmdTransform env var sd -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr boxity, ppr sd]) $ - unitDmdType (unitVarEnv var (C_11 :* sd)) + noArgsDmdType (addVarDmdEnv nopDmdEnv var (C_11 :* sd)) {- ********************************************************************* * * @@ -1038,6 +1045,10 @@ dmdTransform env var sd * * ********************************************************************* -} +-- | An environment in which all demands are weak according to 'isWeakDmd'. +-- See Note [Lazy and unleashable free variables]. +type WeakDmds = VarEnv Demand + -- | @dmdAnalRhsSig@ analyses the given RHS to compute a demand signature -- for the LetDown rule. It works as follows: -- @@ -1052,13 +1063,13 @@ dmdAnalRhsSig -> RecFlag -> AnalEnv -> SubDemand -> Id -> CoreExpr - -> (AnalEnv, DmdEnv, Id, CoreExpr) + -> (AnalEnv, WeakDmds, Id, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs - = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr lazy_fv) $ - (final_env, lazy_fv, final_id, final_rhs) + = -- pprTrace "dmdAnalRhsSig" (ppr id $$ ppr let_dmd $$ ppr rhs_dmds $$ ppr sig $$ ppr weak_fvs) $ + (final_env, weak_fvs, final_id, final_rhs) where threshold_arity = thresholdArity id rhs @@ -1076,11 +1087,11 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs = unboxedWhenSmall env rec_flag (resultType_maybe id) topSubDmd WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_dmd rhs - DmdType rhs_fv rhs_dmds rhs_div = rhs_dmd_ty + DmdType rhs_env rhs_dmds = rhs_dmd_ty (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id threshold_arity - rhs_dmds rhs_div rhs' + rhs_dmds (de_div rhs_env) rhs' - sig = mkDmdSigForArity threshold_arity (DmdType sig_fv final_rhs_dmds rhs_div) + sig = mkDmdSigForArity threshold_arity (DmdType sig_env final_rhs_dmds) opts = ae_opts env final_id = setIdDmdAndBoxSig opts id sig @@ -1098,15 +1109,19 @@ dmdAnalRhsSig top_lvl rec_flag env let_dmd id rhs -- we'd have to do an additional iteration. reuseEnv makes sure that -- we never get used-once info for FVs of recursive functions. -- See #14816 where we try to get rid of reuseEnv. - rhs_fv1 = case rec_flag of - Recursive -> reuseEnv rhs_fv - NonRecursive -> rhs_fv + rhs_env1 = case rec_flag of + Recursive -> reuseEnv rhs_env + NonRecursive -> rhs_env -- See Note [Absence analysis for stable unfoldings and RULES] - rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` bndrRuleAndUnfoldingIds id + rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (bndrRuleAndUnfoldingIds id) -- See Note [Lazy and unleashable free variables] - !(!lazy_fv, !sig_fv) = partitionVarEnv isWeakDmd rhs_fv2 + !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2 + +splitWeakDmds :: DmdEnv -> (DmdEnv, WeakDmds) +splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs) + where (!weak_fvs, !sig_fvs) = partitionVarEnv isWeakDmd fvs thresholdArity :: Id -> CoreExpr -> Arity -- See Note [Demand signatures are computed for a threshold arity based on idArity] @@ -1365,8 +1380,8 @@ GHC.Core.Opt.Arity)! A small example is the test case NewtypeArity. Note [Absence analysis for stable unfoldings and RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Ticket #18638 shows that it's really important to do absence analysis -for stable unfoldings. Consider +Among others, tickets #18638 and #23208 show that it's really important to treat +stable unfoldings as demanded. Consider g = blah @@ -1383,23 +1398,47 @@ and transform to Now if f is subsequently inlined, we'll use 'g' and ... disaster. -SOLUTION: if f has a stable unfolding, adjust its DmdEnv (the demands -on its free variables) so that no variable mentioned in its unfolding -is Absent. This is done by the function Demand.keepAliveDmdEnv. - -ALSO: do the same for Ids free in the RHS of any RULES for f. +SOLUTION: if f has a stable unfolding, treat every free variable as a +/demand root/, that is: Analyse it as if it was a variable occuring in a +'topDmd' context. This is done in `demandRoot` (which we also use for exported +top-level ids). Do the same for Ids free in the RHS of any RULES for f. -PS: You may wonder how it can be that f's optimised RHS has somehow -discarded 'g', but when f is inlined we /don't/ discard g in the same -way. I think a simple example is - g = (a,b) - f = \x. fst g - {-# INLINE f #-} +Wrinkles: -Now f's optimised RHS will be \x.a, but if we change g to (error "..") -(since it is apparently Absent) and then inline (\x. fst g) we get -disaster. But regardless, #18638 was a more complicated version of -this, that actually happened in practice. + (W1) You may wonder how it can be that f's optimised RHS has somehow + discarded 'g', but when f is inlined we /don't/ discard g in the same + way. I think a simple example is + g = (a,b) + f = \x. fst g + {-# INLINE f #-} + + Now f's optimised RHS will be \x.a, but if we change g to (error "..") + (since it is apparently Absent) and then inline (\x. fst g) we get + disaster. But regardless, #18638 was a more complicated version of + this, that actually happened in practice. + + (W2) You might wonder why we don't simply take the free vars of the + unfolding/RULE and map them to topDmd. The reason is that any of the free vars + might have demand signatures themselves that in turn demand transitive free + variables and that we hence need to unleash! This came up in #23208. + Consider + + err :: Int -> b + err = error "really important message" + + sg :: Int -> Int + sg _ = case err of {} -- Str=<1B>b {err:->S} + + g :: a -> a -- g is exported + g x = x + {-# RULES "g" g @Int = sg #-} + + Here, `err` is only demanded by `sg`'s demand signature: It doesn't occur + in the weak_fvs of `sg`'s RHS at all. Hence when we `demandRoots` `sg` + because it occurs in the RULEs of `g` (which is exported), we better unleash + the demand signature of `sg`, too! Before #23208 we simply added a 'topDmd' + for `sg`, failing to unleash the signature and hence observed an absent + error instead of the `really important message`. Note [DmdAnal for DataCon wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2101,8 +2140,7 @@ dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding -> SubDemand -> [(Id,CoreExpr)] - -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info - + -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) -- Binders annotated with strictness info dmdFix top_lvl env let_dmd orig_pairs = loop 1 initial_pairs where @@ -2113,33 +2151,33 @@ dmdFix top_lvl env let_dmd orig_pairs -- If fixed-point iteration does not yield a result we use this instead -- See Note [Safe abortion in the fixed-point iteration] - abort :: (AnalEnv, DmdEnv, [(Id,CoreExpr)]) - abort = (env, lazy_fv', zapped_pairs) - where (lazy_fv, pairs') = step True (zapIdDmdSig orig_pairs) + abort :: (AnalEnv, WeakDmds, [(Id,CoreExpr)]) + abort = (env, weak_fv', zapped_pairs) + where (weak_fv, pairs') = step True (zapIdDmdSig orig_pairs) -- Note [Lazy and unleashable free variables] - non_lazy_fvs = plusVarEnvList $ map (dmdSigDmdEnv . idDmdSig . fst) pairs' - lazy_fv' = lazy_fv `plusVarEnv` mapVarEnv (const topDmd) non_lazy_fvs + weak_fvs = plusVarEnvList $ map (de_fvs . dmdSigDmdEnv . idDmdSig . fst) pairs' + weak_fv' = plusVarEnv_C plusDmd weak_fv $ mapVarEnv (const topDmd) weak_fvs zapped_pairs = zapIdDmdSig pairs' -- The fixed-point varies the idDmdSig field of the binders, and terminates if that -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, WeakDmds, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs - | found_fixpoint = (final_anal_env, lazy_fv, pairs') + | found_fixpoint = (final_anal_env, weak_fv, pairs') | n == 10 = abort | otherwise = loop (n+1) pairs' where found_fixpoint = map (idDmdSig . fst) pairs' == map (idDmdSig . fst) pairs first_round = n == 1 - (lazy_fv, pairs') = step first_round pairs + (weak_fv, pairs') = step first_round pairs final_anal_env = extendAnalEnvs top_lvl env (map fst pairs') - step :: Bool -> [(Id, CoreExpr)] -> (DmdEnv, [(Id, CoreExpr)]) - step first_round pairs = (lazy_fv, pairs') + step :: Bool -> [(Id, CoreExpr)] -> (WeakDmds, [(Id, CoreExpr)]) + step first_round pairs = (weak_fv, pairs') where -- In all but the first iteration, delete the virgin flag start_env | first_round = env @@ -2147,17 +2185,17 @@ dmdFix top_lvl env let_dmd orig_pairs start = (extendAnalEnvs top_lvl start_env (map fst pairs), emptyVarEnv) - !((_,!lazy_fv), !pairs') = mapAccumL my_downRhs start pairs + !((_,!weak_fv), !pairs') = mapAccumL my_downRhs start pairs -- mapAccumL: Use the new signature to do the next pair -- The occurrence analyser has arranged them in a good order -- so this can significantly reduce the number of iterations needed - my_downRhs (env, lazy_fv) (id,rhs) + my_downRhs (env, weak_fv) (id,rhs) = -- pprTrace "my_downRhs" (ppr id $$ ppr (idDmdSig id) $$ ppr sig) $ - ((env', lazy_fv'), (id', rhs')) + ((env', weak_fv'), (id', rhs')) where - !(!env', !lazy_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs - !lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 + !(!env', !weak_fv1, !id', !rhs') = dmdAnalRhsSig top_lvl Recursive env let_dmd id rhs + !weak_fv' = plusVarEnv_C plusDmd weak_fv weak_fv1 zapIdDmdSig :: [(Id, CoreExpr)] -> [(Id, CoreExpr)] zapIdDmdSig pairs = [(setIdDmdSig id nopSig, rhs) | (id, rhs) <- pairs ] @@ -2231,23 +2269,24 @@ convenient to do it there. * * ********************************************************************* -} -unitDmdType :: DmdEnv -> DmdType -unitDmdType dmd_env = DmdType dmd_env [] topDiv +noArgsDmdType :: DmdEnv -> DmdType +noArgsDmdType dmd_env = DmdType dmd_env [] coercionDmdEnv :: Coercion -> DmdEnv coercionDmdEnv co = coercionsDmdEnv [co] coercionsDmdEnv :: [Coercion] -> DmdEnv -coercionsDmdEnv cos = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCos cos) - -- The VarSet from coVarsOfCos is really a VarEnv Var +coercionsDmdEnv cos + = mkTermDmdEnv $ mapVarEnv (const topDmd) $ getUniqSet $ coVarsOfCos cos + -- The VarSet from coVarsOfCos is really a VarEnv Var addVarDmd :: DmdType -> Var -> Demand -> DmdType -addVarDmd (DmdType fv ds res) var dmd - = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res +addVarDmd (DmdType fv ds) var dmd + = DmdType (addVarDmdEnv fv var dmd) ds -addLazyFVs :: DmdType -> DmdEnv -> DmdType -addLazyFVs dmd_ty lazy_fvs - = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs +addWeakFVs :: DmdType -> WeakDmds -> DmdType +addWeakFVs dmd_ty weak_fvs + = dmd_ty `plusDmdType` mkTermDmdEnv weak_fvs -- Using plusDmdType (rather than just plus'ing the envs) -- is vital. Consider -- let f = \x -> (x,y) @@ -2256,7 +2295,7 @@ addLazyFVs dmd_ty lazy_fvs -- demand with the bottom coming up from 'error' -- -- I got a loop in the fixpointer without this, due to an interaction - -- with the lazy_fv filtering in dmdAnalRhsSig. Roughly, it was + -- with the weak_fv filtering in dmdAnalRhsSig. Roughly, it was -- letrec f n x -- = letrec g y = x `fatbar` -- letrec h z = z + ...g... @@ -2357,14 +2396,14 @@ DmdType. But now the signature lies! (Missing variables are assumed to be absent.) To make up for this, the code that analyses the binding keeps the demand on those -variable separate (usually called "lazy_fv") and adds it to the demand of the +variable separate (usually called "weak_fv") and adds it to the demand of the whole binding later. What if we decide _not_ to store a strictness signature for a binding at all, as we do when aborting a fixed-point iteration? The we risk losing the information that the strict variables are being used. In that case, we take all free variables mentioned in the (unsound) strictness signature, conservatively approximate the -demand put on them (topDmd), and add that to the "lazy_fv" returned by "dmdFix". +demand put on them (topDmd), and add that to the "weak_fv" returned by "dmdFix". ************************************************************************ ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt at DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1111,7 +1111,7 @@ cpeApp top_env expr where depth = val_args args stricts = case idDmdSig v of - DmdSig (DmdType _ demands _) + DmdSig (DmdType _ demands) | listLengthCmp demands depth /= GT -> demands -- length demands <= depth | otherwise -> [] ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -43,23 +43,20 @@ module GHC.Types.Demand ( -- ** Manipulating Boxity of a Demand unboxDeeplyDmd, - -- * Demand environments - DmdEnv, emptyDmdEnv, - keepAliveDmdEnv, reuseEnv, - -- * Divergence Divergence(..), topDiv, botDiv, exnDiv, lubDivergence, isDeadEndDiv, + -- * Demand environments + DmdEnv(..), addVarDmdEnv, mkTermDmdEnv, nopDmdEnv, plusDmdEnv, plusDmdEnvs, + reuseEnv, + -- * Demand types DmdType(..), dmdTypeDepth, -- ** Algebra nopDmdType, botDmdType, - lubDmdType, plusDmdType, multDmdType, - -- *** PlusDmdArg - PlusDmdArg, mkPlusDmdArg, toPlusDmdArg, + lubDmdType, plusDmdType, multDmdType, discardArgDmds, -- ** Other operations peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException, - keepAliveDmdType, -- * Demand signatures DmdSig(..), mkDmdSigForArity, mkClosedDmdSig, mkVanillaDmdSig, @@ -85,9 +82,8 @@ module GHC.Types.Demand ( import GHC.Prelude -import GHC.Types.Var ( Var, Id ) +import GHC.Types.Var import GHC.Types.Var.Env -import GHC.Types.Var.Set import GHC.Types.Unique.FM import GHC.Types.Basic import GHC.Data.Maybe ( orElse ) @@ -1054,7 +1050,7 @@ mkWorkerDemand n = C_01 :* go n argsOneShots :: DmdSig -> Arity -> [[OneShotInfo]] -- ^ See Note [Computing one-shot info] -argsOneShots (DmdSig (DmdType _ arg_ds _)) n_val_args +argsOneShots (DmdSig (DmdType _ arg_ds)) n_val_args | unsaturated_call = [] | otherwise = go arg_ds where @@ -1466,7 +1462,7 @@ lubDivergence _ _ = Dunno -- defaultFvDmd (r1 `lubDivergence` r2) = defaultFvDmd r1 `lubDmd` defaultFvDmd r2 -- (See Note [Default demand on free variables and arguments] for why) --- | See Note [Asymmetry of 'plus*'], which concludes that 'plusDivergence' +-- | See Note [Asymmetry of plusDmdType], which concludes that 'plusDivergence' -- needs to be symmetric. -- Strictly speaking, we should have @plusDivergence Dunno Diverges = ExnOrDiv at . -- But that regresses in too many places (every infinite loop, basically) to be @@ -1737,112 +1733,131 @@ a consequence of fixed-point iteration, it's not important that they agree. -} -- Subject to Note [Default demand on free variables and arguments] -type DmdEnv = VarEnv Demand +-- | Captures the result of an evaluation of an expression, by +-- +-- * Listing how the free variables of that expression have been evaluted +-- ('de_fvs') +-- * Saying whether or not evaluation would surely diverge ('de_div') +-- +-- See Note [Demand env Equality]. +data DmdEnv = DE { de_fvs :: !(VarEnv Demand), de_div :: !Divergence } + +instance Eq DmdEnv where + DE fv1 div1 == DE fv2 div2 + = div1 == div2 && canonicalise div1 fv1 == canonicalise div2 fv2 + where + canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + +mkEmptyDmdEnv :: Divergence -> DmdEnv +mkEmptyDmdEnv div = DE emptyVarEnv div + +-- | Build a potentially terminating 'DmdEnv' from a finite map that says what +-- has been evaluated so far +mkTermDmdEnv :: VarEnv Demand -> DmdEnv +mkTermDmdEnv fvs = DE fvs topDiv + +nopDmdEnv :: DmdEnv +nopDmdEnv = mkEmptyDmdEnv topDiv -emptyDmdEnv :: DmdEnv -emptyDmdEnv = emptyVarEnv +botDmdEnv :: DmdEnv +botDmdEnv = mkEmptyDmdEnv botDiv + +exnDmdEnv :: DmdEnv +exnDmdEnv = mkEmptyDmdEnv exnDiv + +lubDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +lubDmdEnv (DE fv1 d1) (DE fv2 d2) = DE lub_fv lub_div + where + -- See Note [Demand env Equality] + lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2) + lub_div = lubDivergence d1 d2 + +addVarDmdEnv :: DmdEnv -> Id -> Demand -> DmdEnv +addVarDmdEnv env@(DE fvs div) id dmd + = DE (extendVarEnv fvs id (dmd `plusDmd` lookupDmdEnv env id)) div + +plusDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv +plusDmdEnv (DE fv1 d1) (DE fv2 d2) + -- In contrast to Note [Asymmetry of plusDmdType], this function is symmetric. + | isEmptyVarEnv fv2, defaultFvDmd d2 == absDmd + = DE fv1 (d1 `plusDivergence` d2) -- a very common case that is much more efficient + | isEmptyVarEnv fv1, defaultFvDmd d1 == absDmd + = DE fv2 (d1 `plusDivergence` d2) -- another very common case that is much more efficient + | otherwise + = DE (plusVarEnv_CD plusDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)) + (d1 `plusDivergence` d2) + +-- | 'DmdEnv' is a monoid via 'plusDmdEnv' and 'nopDmdEnv'; this is its 'msum' +plusDmdEnvs :: [DmdEnv] -> DmdEnv +plusDmdEnvs [] = nopDmdEnv +plusDmdEnvs pdas = foldl1' plusDmdEnv pdas multDmdEnv :: Card -> DmdEnv -> DmdEnv -multDmdEnv C_11 env = env -multDmdEnv C_00 _ = emptyDmdEnv -multDmdEnv n env = mapVarEnv (multDmd n) env +multDmdEnv C_11 env = env +multDmdEnv C_00 _ = nopDmdEnv +multDmdEnv n (DE fvs div) = DE (mapVarEnv (multDmd n) fvs) (multDivergence n div) reuseEnv :: DmdEnv -> DmdEnv reuseEnv = multDmdEnv C_1N --- | @keepAliveDmdType dt vs@ makes sure that the Ids in @vs@ have --- /some/ usage in the returned demand types -- they are not Absent. --- See Note [Absence analysis for stable unfoldings and RULES] --- in "GHC.Core.Opt.DmdAnal". -keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv -keepAliveDmdEnv env vs - = nonDetStrictFoldVarSet add env vs - where - add :: Id -> DmdEnv -> DmdEnv - add v env = extendVarEnv_C add_dmd env v topDmd +lookupDmdEnv :: DmdEnv -> Id -> Demand +-- See Note [Default demand on free variables and arguments] +lookupDmdEnv (DE fv div) id = lookupVarEnv fv id `orElse` defaultFvDmd div - add_dmd :: Demand -> Demand -> Demand - -- If the existing usage is Absent, make it used - -- Otherwise leave it alone - add_dmd dmd _ | isAbsDmd dmd = topDmd - | otherwise = dmd +delDmdEnv :: DmdEnv -> Id -> DmdEnv +delDmdEnv (DE fv div) id = DE (fv `delVarEnv` id) div -- | Characterises how an expression -- --- * Evaluates its free variables ('dt_env') +-- * Evaluates its free variables ('dt_env') including divergence info -- * Evaluates its arguments ('dt_args') --- * Diverges on every code path or not ('dt_div') -- --- Equality is defined modulo 'defaultFvDmd's in 'dt_env'. --- See Note [Demand type Equality]. data DmdType = DmdType - { dt_env :: !DmdEnv -- ^ Demand on explicitly-mentioned free variables + { dt_env :: !DmdEnv -- ^ Demands on free variables. + -- See Note [Demand type Divergence] , dt_args :: ![Demand] -- ^ Demand on arguments - , dt_div :: !Divergence -- ^ Whether evaluation diverges. - -- See Note [Demand type Divergence] } --- | See Note [Demand type Equality]. +-- | See Note [Demand env Equality]. instance Eq DmdType where - (==) (DmdType fv1 ds1 div1) - (DmdType fv2 ds2 div2) = div1 == div2 && ds1 == ds2 -- cheap checks first - && canonicalise div1 fv1 == canonicalise div2 fv2 - where - canonicalise div fv = filterUFM (/= defaultFvDmd div) fv + DmdType env1 ds1 == DmdType env2 ds2 + = ds1 == ds2 -- cheap checks first + && env1 == env2 -- | Compute the least upper bound of two 'DmdType's elicited /by the same -- incoming demand/! lubDmdType :: DmdType -> DmdType -> DmdType -lubDmdType d1 d2 - = DmdType lub_fv lub_ds lub_div +lubDmdType d1 d2 = DmdType lub_fv lub_ds where n = max (dmdTypeDepth d1) (dmdTypeDepth d2) - (DmdType fv1 ds1 r1) = etaExpandDmdType n d1 - (DmdType fv2 ds2 r2) = etaExpandDmdType n d2 - - -- See Note [Demand type Equality] - lub_fv = plusVarEnv_CD lubDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd r2) + (DmdType fv1 ds1) = etaExpandDmdType n d1 + (DmdType fv2 ds2) = etaExpandDmdType n d2 lub_ds = zipWithEqual "lubDmdType" lubDmd ds1 ds2 - lub_div = lubDivergence r1 r2 - -type PlusDmdArg = (DmdEnv, Divergence) + lub_fv = lubDmdEnv fv1 fv2 -mkPlusDmdArg :: DmdEnv -> PlusDmdArg -mkPlusDmdArg env = (env, topDiv) +discardArgDmds :: DmdType -> DmdEnv +discardArgDmds (DmdType fv _) = fv -toPlusDmdArg :: DmdType -> PlusDmdArg -toPlusDmdArg (DmdType fv _ r) = (fv, r) - -plusDmdType :: DmdType -> PlusDmdArg -> DmdType -plusDmdType (DmdType fv1 ds1 r1) (fv2, t2) - -- See Note [Asymmetry of 'plus*'] - -- 'plus' takes the argument/result info from its *first* arg, - -- using its second arg just for its free-var info. - | isEmptyVarEnv fv2, defaultFvDmd t2 == absDmd - = DmdType fv1 ds1 (r1 `plusDivergence` t2) -- a very common case that is much more efficient - | otherwise - = DmdType (plusVarEnv_CD plusDmd fv1 (defaultFvDmd r1) fv2 (defaultFvDmd t2)) - ds1 - (r1 `plusDivergence` t2) +plusDmdType :: DmdType -> DmdEnv -> DmdType +plusDmdType (DmdType fv ds) fv' + -- See Note [Asymmetry of plusDmdType] + -- 'DmdEnv' forms a (monoidal) action on 'DmdType' via this operation. + = DmdType (plusDmdEnv fv fv') ds botDmdType :: DmdType -botDmdType = DmdType emptyDmdEnv [] botDiv +botDmdType = DmdType botDmdEnv [] -- | The demand type of doing nothing (lazy, absent, no Divergence -- information). Note that it is ''not'' the top of the lattice (which would be -- "may use everything"), so it is (no longer) called topDmdType. nopDmdType :: DmdType -nopDmdType = DmdType emptyDmdEnv [] topDiv - -isNopDmdType :: DmdType -> Bool -isNopDmdType (DmdType env args div) - = div == topDiv && null args && isEmptyVarEnv env +nopDmdType = DmdType nopDmdEnv [] -- | The demand type of an unspecified expression that is guaranteed to -- throw a (precise or imprecise) exception or diverge. exnDmdType :: DmdType -exnDmdType = DmdType emptyDmdEnv [] exnDiv +exnDmdType = DmdType exnDmdEnv [] dmdTypeDepth :: DmdType -> Arity dmdTypeDepth = length . dt_args @@ -1851,7 +1866,7 @@ dmdTypeDepth = length . dt_args -- expansion, where n must not be lower than the demand types depth. -- It appends the argument list with the correct 'defaultArgDmd'. etaExpandDmdType :: Arity -> DmdType -> DmdType -etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} +etaExpandDmdType n d at DmdType{dt_args = ds, dt_env = env} | n == depth = d | n > depth = d{dt_args = inc_ds} | otherwise = pprPanic "etaExpandDmdType: arity decrease" (ppr n $$ ppr d) @@ -1863,7 +1878,7 @@ etaExpandDmdType n d at DmdType{dt_args = ds, dt_div = div} -- * Divergence is still valid: -- - A dead end after 2 arguments stays a dead end after 3 arguments -- - The remaining case is Dunno, which is already topDiv - inc_ds = take n (ds ++ repeat (defaultArgDmd div)) + inc_ds = take n (ds ++ repeat (defaultArgDmd (de_div env))) -- | A conservative approximation for a given 'DmdType' in case of an arity -- decrease. Currently, it's just nopDmdType. @@ -1875,30 +1890,27 @@ splitDmdTy :: DmdType -> (Demand, DmdType) -- We already have a suitable demand on all -- free vars, so no need to add more! splitDmdTy ty at DmdType{dt_args=dmd:args} = (dmd, ty{dt_args=args}) -splitDmdTy ty at DmdType{dt_div=div} = (defaultArgDmd div, ty) +splitDmdTy ty at DmdType{dt_env=env} = (defaultArgDmd (de_div env), ty) multDmdType :: Card -> DmdType -> DmdType -multDmdType n (DmdType fv args res_ty) +multDmdType n (DmdType fv args) = -- pprTrace "multDmdType" (ppr n $$ ppr fv $$ ppr (multDmdEnv n fv)) $ DmdType (multDmdEnv n fv) (map (multDmd n) args) - (multDivergence n res_ty) peelFV :: DmdType -> Var -> (DmdType, Demand) -peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) - (DmdType fv' ds res, dmd) +peelFV (DmdType fv ds) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv) + (DmdType fv' ds, dmd) where -- Force these arguments so that old `Env` is not retained. - !fv' = fv `delVarEnv` id - -- See Note [Default demand on free variables and arguments] - !dmd = lookupVarEnv fv id `orElse` defaultFvDmd res + !fv' = fv `delDmdEnv` id + !dmd = lookupDmdEnv fv id addDemand :: Demand -> DmdType -> DmdType -addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res +addDemand dmd (DmdType fv ds) = DmdType fv (dmd:ds) findIdDemand :: DmdType -> Var -> Demand -findIdDemand (DmdType fv _ res) id - = lookupVarEnv fv id `orElse` defaultFvDmd res +findIdDemand (DmdType fv _) id = lookupDmdEnv fv id -- | When e is evaluated after executing an IO action that may throw a precise -- exception, we act as if there is an additional control flow path that is @@ -1914,11 +1926,6 @@ findIdDemand (DmdType fv _ res) id deferAfterPreciseException :: DmdType -> DmdType deferAfterPreciseException = lubDmdType exnDmdType --- | See 'keepAliveDmdEnv'. -keepAliveDmdType :: DmdType -> VarSet -> DmdType -keepAliveDmdType (DmdType fvs ds res) vars = - DmdType (fvs `keepAliveDmdEnv` vars) ds res - {- Note [deferAfterPreciseException] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The big picture is in Note [Precise exceptions and strictness analysis] @@ -1974,32 +1981,25 @@ on err via the App rule. In contrast to weaker head strictness, this demand is strong enough to unleash err's signature and hence we see that the whole expression diverges! -Note [Demand type Equality] +Note [Demand env Equality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -What is the difference between the DmdType {x->A} and ? +What is the difference between the Demand env {x->A} and {}? Answer: There is none! They have the exact same semantics, because any var that -is not mentioned in 'dt_env' implicitly has demand 'defaultFvDmd', based on -the divergence of the demand type 'dt_div'. -Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV -demand of BotDiv is B. But neither is equal to b, because y has demand B in +is not mentioned in 'de_fvs' implicitly has demand 'defaultFvDmd', based on +the divergence of the demand env 'de_div'. +Similarly, b{x->B, y->A} is the same as b{y->A}, because the default FV +demand of BotDiv is B. But neither is equal to b{}, because y has demand B in the latter, not A as before. -NB: 'dt_env' technically can't stand for its own, because it doesn't tell us the -demand on FVs that don't appear in the DmdEnv. Hence 'PlusDmdArg' carries along -a 'Divergence', for example. - -The Eq instance of DmdType must reflect that, otherwise we can get into monotonicity -issues during fixed-point iteration ({x->A} /= /= {x->A} /= ...). -It does so by filtering out any default FV demands prior to comparing 'dt_env'. -An alternative would be to maintain an invariant that there are no default FV demands -in 'dt_env' to begin with, but that seems more involved to maintain in the current -implementation. +The Eq instance of DmdEnv must reflect that, otherwise we can get into monotonicity +issues during fixed-point iteration ({x->A} /= {} /= {x->A} /= ...). +It does so by filtering out any default FV demands prior to comparing 'de_fvs'. -Note that 'lubDmdType' maintains this kind of equality by using 'plusVarEnv_CD', -involving 'defaultFvDmd' for any entries present in one 'dt_env' but not the +Note that 'lubDmdEnv' maintains this kind of equality by using 'plusVarEnv_CD', +involving 'defaultFvDmd' for any entries present in one 'de_fvs' but not the other. -Note [Asymmetry of 'plus*'] +Note [Asymmetry of plusDmdType] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'plus' for DmdTypes is *asymmetrical*, because there can only one be one type contributing argument demands! For example, given (e1 e2), we get @@ -2155,24 +2155,24 @@ newtype DmdSig -- | Turns a 'DmdType' computed for the particular 'Arity' into a 'DmdSig' -- unleashable at that arity. See Note [Understanding DmdType and DmdSig]. mkDmdSigForArity :: Arity -> DmdType -> DmdSig -mkDmdSigForArity arity dmd_ty@(DmdType fvs args div) - | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) div +mkDmdSigForArity arity dmd_ty@(DmdType fvs args) + | arity < dmdTypeDepth dmd_ty = DmdSig $ DmdType fvs (take arity args) | otherwise = DmdSig (etaExpandDmdType arity dmd_ty) mkClosedDmdSig :: [Demand] -> Divergence -> DmdSig -mkClosedDmdSig ds res = mkDmdSigForArity (length ds) (DmdType emptyDmdEnv ds res) +mkClosedDmdSig ds div = mkDmdSigForArity (length ds) (DmdType (mkEmptyDmdEnv div) ds) mkVanillaDmdSig :: Arity -> Divergence -> DmdSig mkVanillaDmdSig ar div = mkClosedDmdSig (replicate ar topDmd) div splitDmdSig :: DmdSig -> ([Demand], Divergence) -splitDmdSig (DmdSig (DmdType _ dmds res)) = (dmds, res) +splitDmdSig (DmdSig (DmdType env dmds)) = (dmds, de_div env) dmdSigDmdEnv :: DmdSig -> DmdEnv -dmdSigDmdEnv (DmdSig (DmdType env _ _)) = env +dmdSigDmdEnv (DmdSig (DmdType env _)) = env hasDemandEnvSig :: DmdSig -> Bool -hasDemandEnvSig = not . isEmptyVarEnv . dmdSigDmdEnv +hasDemandEnvSig = not . isEmptyVarEnv . de_fvs . dmdSigDmdEnv botSig :: DmdSig botSig = DmdSig botDmdType @@ -2181,23 +2181,23 @@ nopSig :: DmdSig nopSig = DmdSig nopDmdType isNopSig :: DmdSig -> Bool -isNopSig (DmdSig ty) = isNopDmdType ty +isNopSig (DmdSig ty) = ty == nopDmdType -- | True if the signature diverges or throws an exception in a saturated call. -- See Note [Dead ends]. isDeadEndSig :: DmdSig -> Bool -isDeadEndSig (DmdSig (DmdType _ _ res)) = isDeadEndDiv res +isDeadEndSig (DmdSig (DmdType env _)) = isDeadEndDiv (de_div env) -- | True if the signature diverges or throws an imprecise exception in a saturated call. -- NB: In constrast to 'isDeadEndSig' this returns False for 'exnDiv'. -- See Note [Dead ends] -- and Note [Precise vs imprecise exceptions]. isBottomingSig :: DmdSig -> Bool -isBottomingSig (DmdSig (DmdType _ _ res)) = res == botDiv +isBottomingSig (DmdSig (DmdType env _)) = de_div env == botDiv -- | True when the signature indicates all arguments are boxed onlyBoxedArguments :: DmdSig -> Bool -onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds +onlyBoxedArguments (DmdSig (DmdType _ dmds)) = all demandIsBoxed dmds where demandIsBoxed BotDmd = True demandIsBoxed AbsDmd = True @@ -2217,12 +2217,15 @@ onlyBoxedArguments (DmdSig (DmdType _ dmds _)) = all demandIsBoxed dmds -- Hence this function conservatively returns False in that case. -- See Note [Dead ends]. isDeadEndAppSig :: DmdSig -> Int -> Bool -isDeadEndAppSig (DmdSig (DmdType _ ds res)) n - = isDeadEndDiv res && not (lengthExceeds ds n) +isDeadEndAppSig (DmdSig (DmdType env ds)) n + = isDeadEndDiv (de_div env) && not (lengthExceeds ds n) + +trimBoxityDmdEnv :: DmdEnv -> DmdEnv +trimBoxityDmdEnv (DE fvs div) = DE (mapVarEnv trimBoxity fvs) div trimBoxityDmdType :: DmdType -> DmdType -trimBoxityDmdType (DmdType fvs ds res) = - DmdType (mapVarEnv trimBoxity fvs) (map trimBoxity ds) res +trimBoxityDmdType (DmdType env ds) = + DmdType (trimBoxityDmdEnv env) (map trimBoxity ds) trimBoxityDmdSig :: DmdSig -> DmdSig trimBoxityDmdSig = coerce trimBoxityDmdType @@ -2247,12 +2250,11 @@ transferBoxity from to = go_dmd from to _ -> trimBoxity to_dmd transferArgBoxityDmdType :: DmdType -> DmdType -> DmdType -transferArgBoxityDmdType _from@(DmdType _ from_ds _) to@(DmdType to_fvs to_ds to_res) +transferArgBoxityDmdType _from@(DmdType _ from_ds) to@(DmdType to_env to_ds) | equalLength from_ds to_ds = -- pprTraceWith "transfer" (\r -> ppr _from $$ ppr to $$ ppr r) $ - DmdType to_fvs -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] + DmdType to_env -- Only arg boxity! See Note [Don't change boxity without worker/wrapper] (zipWith transferBoxity from_ds to_ds) - to_res | otherwise = trimBoxityDmdType to @@ -2263,10 +2265,10 @@ prependArgsDmdSig :: Int -> DmdSig -> DmdSig -- ^ Add extra ('topDmd') arguments to a strictness signature. -- In contrast to 'etaConvertDmdSig', this /prepends/ additional argument -- demands. This is used by FloatOut. -prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds res)) - | new_args == 0 = sig - | isNopDmdType dmd_ty = sig - | otherwise = DmdSig (DmdType env dmds' res) +prependArgsDmdSig new_args sig@(DmdSig dmd_ty@(DmdType env dmds)) + | new_args == 0 = sig + | dmd_ty == nopDmdType = sig + | otherwise = DmdSig (DmdType env dmds') where dmds' = assertPpr (new_args > 0) (ppr new_args) $ replicate new_args topDmd ++ dmds @@ -2308,7 +2310,7 @@ type DmdTransformer = SubDemand -> DmdType -- Given a function's 'DmdSig' and a 'SubDemand' for the evaluation context, -- return how the function evaluates its free variables and arguments. dmdTransformSig :: DmdSig -> DmdTransformer -dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds _)) sd +dmdTransformSig (DmdSig dmd_ty@(DmdType _ arg_ds)) sd = multDmdType (fst $ peelManyCalls (length arg_ds) sd) dmd_ty -- see Note [Demands from unsaturated function calls] -- and Note [What are demand signatures?] @@ -2323,7 +2325,7 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of where arity = length str_marks (n, body_sd) = peelManyCalls arity sd - mk_body_ty n dmds = DmdType emptyDmdEnv (zipWith (bump n) str_marks dmds) topDiv + mk_body_ty n dmds = DmdType nopDmdEnv (zipWith (bump n) str_marks dmds) bump n str dmd | isMarkedStrict str = multDmd n (plusDmd str_field_dmd dmd) | otherwise = multDmd n dmd str_field_dmd = C_01 :* seqSubDmd -- Why not C_11? See Note [Data-con worker strictness] @@ -2334,11 +2336,11 @@ dmdTransformDataConSig str_marks sd = case viewProd arity body_sd of dmdTransformDictSelSig :: DmdSig -> DmdTransformer -- NB: This currently doesn't handle newtype dictionaries. -- It should simply apply call_sd directly to the dictionary, I suppose. -dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod] _)) call_sd +dmdTransformDictSelSig (DmdSig (DmdType _ [_ :* prod])) call_sd | (n, sd') <- peelCallDmd call_sd , Prod _ sig_ds <- prod = multDmdType n $ - DmdType emptyDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] topDiv + DmdType nopDmdEnv [C_11 :* mkProd Unboxed (map (enhance sd') sig_ds)] | otherwise = nopDmdType -- See Note [Demand transformer for a dictionary selector] where @@ -2460,9 +2462,12 @@ This is weird, so I'm not worried about whether this optimises brilliantly; but it should not fall over. -} +zapDmdEnv :: DmdEnv -> DmdEnv +zapDmdEnv (DE _ div) = mkEmptyDmdEnv div + -- | Remove the demand environment from the signature. zapDmdEnvSig :: DmdSig -> DmdSig -zapDmdEnvSig (DmdSig (DmdType _ ds r)) = mkClosedDmdSig ds r +zapDmdEnvSig (DmdSig (DmdType env ds)) = DmdSig (DmdType (zapDmdEnv env) ds) zapUsageDemand :: Demand -> Demand -- Remove the usage info, but not the strictness info, from the demand @@ -2483,8 +2488,8 @@ zapUsedOnceDemand = kill_usage $ KillFlags -- | Remove all `C_01 :*` info (but not `CM` sub-demands) from the strictness -- signature zapUsedOnceSig :: DmdSig -> DmdSig -zapUsedOnceSig (DmdSig (DmdType env ds r)) - = DmdSig (DmdType env (map zapUsedOnceDemand ds) r) +zapUsedOnceSig (DmdSig (DmdType env ds)) + = DmdSig (DmdType env (map zapUsedOnceDemand ds)) data KillFlags = KillFlags { kf_abs :: Bool @@ -2569,11 +2574,11 @@ seqDemandList :: [Demand] -> () seqDemandList = foldr (seq . seqDemand) () seqDmdType :: DmdType -> () -seqDmdType (DmdType env ds res) = - seqDmdEnv env `seq` seqDemandList ds `seq` res `seq` () +seqDmdType (DmdType env ds) = + seqDmdEnv env `seq` seqDemandList ds `seq` () seqDmdEnv :: DmdEnv -> () -seqDmdEnv env = seqEltsUFM seqDemand env +seqDmdEnv (DE fvs _) = seqEltsUFM seqDemand fvs seqDmdSig :: DmdSig -> () seqDmdSig (DmdSig ty) = seqDmdType ty @@ -2682,17 +2687,20 @@ instance Outputable Divergence where ppr ExnOrDiv = char 'x' -- for e(x)ception ppr Dunno = empty -instance Outputable DmdType where - ppr (DmdType fv ds res) - = hsep [hcat (map (angleBrackets . ppr) ds) <> ppr res, - if null fv_elts then empty - else braces (fsep (map pp_elt fv_elts))] +instance Outputable DmdEnv where + ppr (DE fvs div) + = ppr div <> if null fv_elts then empty + else braces (fsep (map pp_elt fv_elts)) where pp_elt (uniq, dmd) = ppr uniq <> text "->" <> ppr dmd - fv_elts = nonDetUFMToList fv + fv_elts = nonDetUFMToList fvs -- It's OK to use nonDetUFMToList here because we only do it for -- pretty printing +instance Outputable DmdType where + ppr (DmdType fv ds) + = hcat (map (angleBrackets . ppr) ds) <> ppr fv + instance Outputable DmdSig where ppr (DmdSig ty) = ppr ty @@ -2741,15 +2749,6 @@ instance Binary SubDemand where 2 -> Prod <$> get bh <*> get bh _ -> pprPanic "Binary:SubDemand" (ppr (fromIntegral h :: Int)) -instance Binary DmdSig where - put_ bh (DmdSig aa) = put_ bh aa - get bh = DmdSig <$> get bh - -instance Binary DmdType where - -- Ignore DmdEnv when spitting out the DmdType - put_ bh (DmdType _ ds dr) = put_ bh ds *> put_ bh dr - get bh = DmdType emptyDmdEnv <$> get bh <*> get bh - instance Binary Divergence where put_ bh Dunno = putByte bh 0 put_ bh ExnOrDiv = putByte bh 1 @@ -2761,3 +2760,16 @@ instance Binary Divergence where 1 -> return ExnOrDiv 2 -> return Diverges _ -> pprPanic "Binary:Divergence" (ppr (fromIntegral h :: Int)) + +instance Binary DmdEnv where + -- Ignore VarEnv when spitting out the DmdType + put_ bh (DE _ d) = put_ bh d + get bh = DE emptyVarEnv <$> get bh + +instance Binary DmdType where + put_ bh (DmdType fv ds) = put_ bh fv *> put_ bh ds + get bh = DmdType <$> get bh <*> get bh + +instance Binary DmdSig where + put_ bh (DmdSig aa) = put_ bh aa + get bh = DmdSig <$> get bh ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -110,6 +110,6 @@ test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) -test('T19969', normal, compile, ['-ddump-simpl -dsuppress-uniques']) +test('T19969', [grep_errmsg('LoopBreaker')], compile, ['-ddump-simpl -dsuppress-uniques']) # f should become loopbreaker test('T19883', normal, compile, ['']) test('T22719', normal, compile, ['-ddump-simpl -dsuppress-uniques -dno-typeable-binds']) ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -228,7 +228,6 @@ test('T13027', normal, compile, ['']) test('T13025', normal, makefile_test, ['T13025']) -test('T13143', only_ways(['optasm']), compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-ticks']) test('T13156', normal, makefile_test, ['T13156']) test('T11444', normal, compile, ['']) test('str-rules', @@ -414,7 +413,8 @@ test('T17966', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) # We expect to see a SPEC rule for $cm test('T19644', [ grep_errmsg(r'SPEC') ], compile, ['-O -ddump-spec']) test('T21391', normal, compile, ['-O -dcore-lint']) -test('T22112', normal, compile, ['-O -dsuppress-uniques -dno-typeable-binds -ddump-simpl']) +# T22112: Simply test that dumping the Core doesn't loop becuse of the unfolding and ignore the dump output +test('T22112', [ grep_errmsg('never matches') ], compile, ['-O -dsuppress-uniques -dno-typeable-binds -fexpose-all-unfoldings -ddump-simpl']) test('T21391a', normal, compile, ['-O -dcore-lint']) # We don't want to see a thunk allocation for the insertBy expression after CorePrep. test('T21392', [ grep_errmsg(r'sat.* :: \[\(.*Unique, .*Int\)\]'), expect_broken(21392) ], compile, ['-O -ddump-prep -dno-typeable-binds -dsuppress-uniques']) ===================================== testsuite/tests/simplCore/should_compile/T13143.hs → testsuite/tests/stranal/should_compile/T13143.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr → testsuite/tests/stranal/should_compile/T13143.stderr ===================================== @@ -7,21 +7,22 @@ Rec { -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. (# #) -> a -[GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] -T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) +[GblId, Arity=1, Str=b{sBp->S}, Cpr=b, Unf=OtherCon []] +T13143.$wf + = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) end Rec } -- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} f [InlPrag=NOINLINE[final]] :: forall a. Int -> a [GblId, Arity=1, - Str=b, + Str=b{sBp->S}, Cpr=b, Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True) - Tmpl= \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)}] -f = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##) + Tmpl= \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##)}] +f = \ (@a_sBm) _ [Occ=Dead] -> T13143.$wf @a_sBm GHC.Prim.(##) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T13143.$trModule4 :: GHC.Prim.Addr# @@ -65,9 +66,9 @@ T13143.$trModule = GHC.Types.Module T13143.$trModule3 T13143.$trModule1 -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} -lvl :: Int -[GblId, Str=b, Cpr=b] -lvl = T13143.$wf @Int GHC.Prim.(##) +lvl_rBN :: Int +[GblId, Str=b{sBp->S}, Cpr=b] +lvl_rBN = T13143.$wf @Int GHC.Prim.(##) Rec { -- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0} @@ -78,17 +79,17 @@ T13143.$wg [InlPrag=[2], Occ=LoopBreaker] Str=<1L><1L>, Unf=OtherCon []] T13143.$wg - = \ (ds :: Bool) (ds1 :: Bool) (ww :: GHC.Prim.Int#) -> - case ds of { + = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (ww_sBv :: GHC.Prim.Int#) -> + case ds_sBr of { False -> - case ds1 of { - False -> T13143.$wg GHC.Types.False GHC.Types.True ww; - True -> GHC.Prim.+# ww 1# + case ds1_sBs of { + False -> T13143.$wg GHC.Types.False GHC.Types.True ww_sBv; + True -> GHC.Prim.+# ww_sBv 1# }; True -> - case ds1 of { - False -> T13143.$wg GHC.Types.True GHC.Types.True ww; - True -> case lvl of wild2 { } + case ds1_sBs of { + False -> T13143.$wg GHC.Types.True GHC.Types.True ww_sBv; + True -> case lvl_rBN of wild2_00 { } } } end Rec } @@ -102,17 +103,20 @@ g [InlPrag=[2]] :: Bool -> Bool -> Int -> Int Unf=Unf{Src=StableSystem, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=3,unsat_ok=True,boring_ok=False) - Tmpl= \ (ds [Occ=Once1] :: Bool) - (ds1 [Occ=Once1] :: Bool) - (p [Occ=Once1!] :: Int) -> - case p of { GHC.Types.I# ww [Occ=Once1] -> - case T13143.$wg ds ds1 ww of ww1 [Occ=Once1] { __DEFAULT -> - GHC.Types.I# ww1 + Tmpl= \ (ds_sBr [Occ=Once1] :: Bool) + (ds1_sBs [Occ=Once1] :: Bool) + (p_sBt [Occ=Once1!] :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv [Occ=Once1] -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA [Occ=Once1] + { __DEFAULT -> + GHC.Types.I# ww1_sBA } }}] -g = \ (ds :: Bool) (ds1 :: Bool) (p :: Int) -> - case p of { GHC.Types.I# ww -> - case T13143.$wg ds ds1 ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } +g = \ (ds_sBr :: Bool) (ds1_sBs :: Bool) (p_sBt :: Int) -> + case p_sBt of { GHC.Types.I# ww_sBv -> + case T13143.$wg ds_sBr ds1_sBs ww_sBv of ww1_sBA { __DEFAULT -> + GHC.Types.I# ww1_sBA + } } ===================================== testsuite/tests/stranal/should_compile/T18894.stderr ===================================== @@ -1,48 +1,54 @@ -==================== Demand analysis ==================== -Result size of Demand analysis +==================== Demand analysis (including Boxity) ==================== +Result size of Demand analysis (including Boxity) = {terms: 189, types: 95, coercions: 0, joins: 0/2} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 42, types: 15, coercions: 0, joins: 0/1} @@ -51,8 +57,9 @@ g2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId, Arity=2, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 106 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 20] 106 20}] g2 = \ (m :: Int) (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -64,8 +71,9 @@ g2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -81,22 +89,25 @@ g2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} @@ -104,8 +115,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -128,22 +140,25 @@ h2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 15# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = (lvl, lvl) -- RHS size: {terms: 36, types: 10, coercions: 0, joins: 0/1} @@ -151,8 +166,9 @@ g1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] :: Int -> (Int, Int) [LclId, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 86 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 86 10}] g1 = \ (ds [Dmd=1!P(1L)] :: Int) -> case ds of { GHC.Types.I# ds [Dmd=1L] -> @@ -164,8 +180,9 @@ g1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -181,15 +198,17 @@ g1 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 30 0}] lvl = g1 (GHC.Types.I# 2#) -- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} @@ -197,8 +216,9 @@ h1 :: Int -> Int [LclIdX, Arity=1, Str=<1!P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 111 10}] h1 = \ (ds [Dmd=1!P(SL)] :: Int) -> case ds of wild [Dmd=M!P(1L)] { GHC.Types.I# ds [Dmd=SL] -> @@ -224,43 +244,49 @@ Result size of Demand analysis -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 20 0}] $trModule = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Prim.Addr# [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 30 0}] $trModule = "T18894"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule :: GHC.Types.TrName [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] $trModule = GHC.Types.TrNameS $trModule -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18894.$trModule :: GHC.Types.Module [LclIdX, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] T18894.$trModule = GHC.Types.Module $trModule $trModule -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 0# -- RHS size: {terms: 39, types: 17, coercions: 0, joins: 0/1} @@ -269,8 +295,9 @@ $wg2 [InlPrag=NOINLINE, Dmd=LC(S,C(1,!P(M!P(L),1!P(L))))] [LclId[StrictWorker([])], Arity=2, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 76 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20 30] 76 20}] $wg2 = \ (m :: Int) (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -281,8 +308,9 @@ $wg2 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -297,8 +325,9 @@ $wg2 -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} lvl :: Int [LclId, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [] 10 10}] lvl = GHC.Types.I# 2# -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/0} @@ -306,8 +335,9 @@ h2 :: Int -> Int [LclIdX, Arity=1, Str=<1P(SL)>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [20] 162 10}] h2 = \ (ds [Dmd=1P(SL)] :: Int) -> case ds of wild { GHC.Types.I# ds [Dmd=SL] -> @@ -333,8 +363,9 @@ $wg1 [InlPrag=NOINLINE, Dmd=LC(L,!P(L,L))] [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 56 20}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [30] 56 20}] $wg1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds { @@ -345,8 +376,9 @@ $wg1 let { c1# :: GHC.Prim.Int# [LclId, - Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 2 0}] + Unf=Unf{Src=, TopLvl=False, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 2 0}] c1# = GHC.Prim.andI# 1# (GHC.Prim.<# wild 0#) } in case GHC.Prim.-# (GHC.Prim.quotInt# (GHC.Prim.-# 2# c1#) wild) c1# of ds2 @@ -361,17 +393,19 @@ $wg1 -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} lvl :: (Int, Int) [LclId, - Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, - WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 10}] + Unf=Unf{Src=, TopLvl=True, + Value=False, ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 50 10}] lvl = case $wg1 2# of { (# ww, ww #) -> (GHC.Types.I# ww, ww) } -- RHS size: {terms: 22, types: 16, coercions: 0, joins: 0/0} -$wh1 [InlPrag=[2], Dmd=LC(S,!P(L))] :: GHC.Prim.Int# -> Int +$wh1 [InlPrag=[2]] :: GHC.Prim.Int# -> Int [LclId[StrictWorker([])], Arity=1, Str=<1L>, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 91 10}] + Unf=Unf{Src=, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=IF_ARGS [50] 91 10}] $wh1 = \ (ww [Dmd=1L] :: GHC.Prim.Int#) -> case ww of ds [Dmd=ML] { @@ -388,8 +422,8 @@ h1 [InlPrag=[2]] :: Int -> Int [LclIdX, Arity=1, Str=<1!P(1L)>, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, + Unf=Unf{Src=StableSystem, TopLvl=True, + Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) Tmpl= \ (ds [Occ=Once1!, Dmd=S!P(SL)] :: Int) -> case ds of { GHC.Types.I# ww [Occ=Once1, Dmd=SL] -> $wh1 ww }}] ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -42,6 +42,9 @@ test('T13031', normal, makefile_test, []) test('T13077', normal, compile, ['']) test('T13077a', normal, compile, ['']) +# T13143: WW for NOINLINE function f +test('T13143', [ grep_errmsg(r'^T13143\.\$wf') ], compile, ['-ddump-simpl']) + # T15627 # Absent bindings of unlifted types should be WW'ed away. # The idea is to check that both $wmutVar and $warray ===================================== testsuite/tests/stranal/should_run/T23208.hs ===================================== @@ -0,0 +1,4 @@ +import T23208_Lib + +main = print $ g (15 :: Int) + ===================================== testsuite/tests/stranal/should_run/T23208.stderr ===================================== @@ -0,0 +1,3 @@ +T23208: really important message +CallStack (from HasCallStack): + error, called at T23208_Lib.hs:4:7 in main:T23208_Lib ===================================== testsuite/tests/stranal/should_run/T23208_Lib.hs ===================================== @@ -0,0 +1,12 @@ +module T23208_Lib (g) where + +err :: Int -> b +err = error "really important message" + +sg :: Int -> Int +sg n = err n +{-# NOINLINE sg #-} +g :: a -> a +g x = x +{-# NOINLINE g #-} +{-# RULES "g" g @Int = sg #-} ===================================== testsuite/tests/stranal/should_run/all.T ===================================== @@ -32,3 +32,4 @@ test('T22475', normal, compile_and_run, ['']) test('T22475b', normal, compile_and_run, ['']) # T22549: Do not strictify DFuns, otherwise we will <> test('T22549', normal, compile_and_run, ['-fdicts-strict -fno-specialise']) +test('T23208', exit_code(1), multimod_compile_and_run, ['T23208_Lib', 'T23208']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c30ac25f7dfaded58bb2ff85d4bffe662e4af8b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c30ac25f7dfaded58bb2ff85d4bffe662e4af8b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 18:51:54 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 26 Apr 2023 14:51:54 -0400 Subject: [Git][ghc/ghc][master] Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Message-ID: <644972cad29c1_178e74e24262c817518dd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 27 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Sinker.hs - compiler/GHC/StgToJS/StgUtils.hs - testsuite/tests/dependent/should_compile/all.T - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_run/all.T Changes: ===================================== compiler/GHC/ByteCode/Instr.hs ===================================== @@ -252,7 +252,7 @@ pprStgAltShort opts GenStgAlt{alt_con=con, alt_bndrs=args, alt_rhs=expr} = ppr con <+> sep (map ppr args) <+> text "->" <+> pprStgExprShort opts expr pprStgRhsShort :: OutputablePass pass => StgPprOpts -> GenStgRhs pass -> SDoc -pprStgRhsShort opts (StgRhsClosure _ext _cc upd_flag args body) = +pprStgRhsShort opts (StgRhsClosure _ext _cc upd_flag args body _typ) = hang (hsep [ char '\\' <> ppr upd_flag, brackets (interppSP args) ]) 4 (pprStgExprShort opts body) pprStgRhsShort opts rhs = pprStgRhs opts rhs ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -691,7 +691,7 @@ coreToStgRhs (bndr, rhs) = do return (mkStgRhs bndr new_rhs) -- Represents the RHS of a binding for use with mk(Top)StgRhs. -data PreStgRhs = PreStgRhs [Id] StgExpr -- The [Id] is empty for thunks +data PreStgRhs = PreStgRhs [Id] StgExpr Type -- The [Id] is empty for thunks -- Convert the RHS of a binding from Core to STG. This is a wrapper around -- coreToStgExpr that can handle value lambdas. @@ -699,7 +699,7 @@ coreToPreStgRhs :: HasDebugCallStack => CoreExpr -> CtsM PreStgRhs coreToPreStgRhs expr = extendVarEnvCts [ (a, LambdaBound) | a <- args' ] $ do { body' <- coreToStgExpr body - ; return (PreStgRhs args' body') } + ; return (PreStgRhs args' body' (exprType body)) } where (args, body) = myCollectBinders expr args' = filterStgBinders args @@ -713,13 +713,13 @@ mkTopStgRhs CoreToStgOpts { coreToStg_platform = platform , coreToStg_ExternalDynamicRefs = opt_ExternalDynamicRefs , coreToStg_AutoSccsOnIndividualCafs = opt_AutoSccsOnIndividualCafs - } this_mod ccs bndr (PreStgRhs bndrs rhs) + } this_mod ccs bndr (PreStgRhs bndrs rhs typ) | not (null bndrs) = -- The list of arguments is non-empty, so not CAF ( StgRhsClosure noExtFieldSilent dontCareCCS ReEntrant - bndrs rhs + bndrs rhs typ , ccs ) -- After this point we know that `bndrs` is empty, @@ -730,19 +730,19 @@ mkTopStgRhs CoreToStgOpts = -- CorePrep does this right, but just to make sure assertPpr (not (isUnboxedTupleDataCon con || isUnboxedSumDataCon con)) (ppr bndr $$ ppr con $$ ppr args) - ( StgRhsCon dontCareCCS con mn ticks args, ccs ) + ( StgRhsCon dontCareCCS con mn ticks args typ, ccs ) -- Otherwise it's a CAF, see Note [Cost-centre initialization plan]. | opt_AutoSccsOnIndividualCafs = ( StgRhsClosure noExtFieldSilent caf_ccs - upd_flag [] rhs + upd_flag [] rhs typ , collectCC caf_cc caf_ccs ccs ) | otherwise = ( StgRhsClosure noExtFieldSilent all_cafs_ccs - upd_flag [] rhs + upd_flag [] rhs typ , ccs ) where @@ -766,12 +766,12 @@ mkTopStgRhs CoreToStgOpts -- Generate a non-top-level RHS. Cost-centre is always currentCCS, -- see Note [Cost-centre initialization plan]. mkStgRhs :: Id -> PreStgRhs -> StgRhs -mkStgRhs bndr (PreStgRhs bndrs rhs) +mkStgRhs bndr (PreStgRhs bndrs rhs typ) | not (null bndrs) = StgRhsClosure noExtFieldSilent currentCCS ReEntrant - bndrs rhs + bndrs rhs typ -- After this point we know that `bndrs` is empty, -- so this is not a function binding @@ -782,15 +782,15 @@ mkStgRhs bndr (PreStgRhs bndrs rhs) StgRhsClosure noExtFieldSilent currentCCS ReEntrant -- ignored for LNE - [] rhs + [] rhs typ | StgConApp con mn args _ <- unticked_rhs - = StgRhsCon currentCCS con mn ticks args + = StgRhsCon currentCCS con mn ticks args typ | otherwise = StgRhsClosure noExtFieldSilent currentCCS - upd_flag [] rhs + upd_flag [] rhs typ where (ticks, unticked_rhs) = stripStgTicksTop (not . tickishIsCode) rhs ===================================== compiler/GHC/Stg/BcPrep.hs ===================================== @@ -37,14 +37,14 @@ type BcPrepM a = State BcPrepM_State a bcPrepRHS :: StgRhs -> BcPrepM StgRhs -- explicitly match all constructors so we get a warning if we miss any -bcPrepRHS (StgRhsClosure fvs cc upd args (StgTick bp at Breakpoint{} expr)) = do +bcPrepRHS (StgRhsClosure fvs cc upd args (StgTick bp at Breakpoint{} expr) typ) = do {- If we have a breakpoint directly under an StgRhsClosure we don't need to introduce a new binding for it. -} expr' <- bcPrepExpr expr - pure (StgRhsClosure fvs cc upd args (StgTick bp expr')) -bcPrepRHS (StgRhsClosure fvs cc upd args expr) = - StgRhsClosure fvs cc upd args <$> bcPrepExpr expr + pure (StgRhsClosure fvs cc upd args (StgTick bp expr') typ) +bcPrepRHS (StgRhsClosure fvs cc upd args expr typ) = + StgRhsClosure fvs cc upd args <$> bcPrepExpr expr <*> pure typ bcPrepRHS con at StgRhsCon{} = pure con bcPrepExpr :: StgExpr -> BcPrepM StgExpr @@ -59,6 +59,7 @@ bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _) rhs) ReEntrant [] expr' + tick_ty ) letExp = StgLet noExtFieldSilent bnd (StgApp id []) pure letExp @@ -71,6 +72,7 @@ bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _) rhs) ReEntrant [voidArgId] expr' + tick_ty ) pure $ StgLet noExtFieldSilent bnd (StgApp id [StgVarArg realWorldPrimId]) bcPrepExpr (StgTick tick rhs) = @@ -110,10 +112,10 @@ bcPrepBind (StgRec bnds) = bcPrepSingleBind :: (Id, StgRhs) -> (Id, StgRhs) -- If necessary, modify this Id and body to protect not-necessarily-lifted join points. -- See Note [Not-necessarily-lifted join points], step 2. -bcPrepSingleBind (x, StgRhsClosure ext cc upd_flag args body) +bcPrepSingleBind (x, StgRhsClosure ext cc upd_flag args body typ) | isNNLJoinPoint x = ( protectNNLJoinPointId x - , StgRhsClosure ext cc upd_flag (args ++ [voidArgId]) body) + , StgRhsClosure ext cc upd_flag (args ++ [voidArgId]) body typ) bcPrepSingleBind bnd = bnd bcPrepTopLvl :: StgTopBinding -> BcPrepM StgTopBinding ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -319,11 +319,11 @@ stgCseTopLvl in_scope (StgTopLifted (StgRec eqs)) where in_scope' = in_scope `extendInScopeSetList` [ bndr | (bndr, _) <- eqs ] stgCseTopLvlRhs :: InScopeSet -> InStgRhs -> OutStgRhs -stgCseTopLvlRhs in_scope (StgRhsClosure ext ccs upd args body) +stgCseTopLvlRhs in_scope (StgRhsClosure ext ccs upd args body typ) = let body' = stgCseExpr (initEnv in_scope) body - in StgRhsClosure ext ccs upd args body' -stgCseTopLvlRhs _ (StgRhsCon ccs dataCon mu ticks args) - = StgRhsCon ccs dataCon mu ticks args + in StgRhsClosure ext ccs upd args body' typ +stgCseTopLvlRhs _ (StgRhsCon ccs dataCon mu ticks args typ) + = StgRhsCon ccs dataCon mu ticks args typ ------------------------------ -- The actual AST traversal -- @@ -427,7 +427,7 @@ stgCsePairs env0 ((b,e):pairs) -- The RHS of a binding. -- If it is a constructor application, either short-cut it or extend the environment stgCseRhs :: CseEnv -> OutId -> InStgRhs -> (Maybe (OutId, OutStgRhs), CseEnv) -stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args) +stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args typ) | Just other_bndr <- envLookup dataCon args' env , not (isWeakLoopBreaker (idOccInfo bndr)) -- See Note [Care with loop breakers] = let env' = addSubst bndr other_bndr env @@ -435,15 +435,15 @@ stgCseRhs env bndr (StgRhsCon ccs dataCon mu ticks args) | otherwise = let env' = addDataCon bndr dataCon args' env -- see Note [Case 1: CSEing allocated closures] - pair = (bndr, StgRhsCon ccs dataCon mu ticks args') + pair = (bndr, StgRhsCon ccs dataCon mu ticks args' typ) in (Just pair, env') where args' = substArgs env args -stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) +stgCseRhs env bndr (StgRhsClosure ext ccs upd args body typ) = let (env1, args') = substBndrs env args env2 = forgetCse env1 -- See Note [Free variables of an StgClosure] body' = stgCseExpr env2 body - in (Just (substVar env bndr, StgRhsClosure ext ccs upd args' body'), env) + in (Just (substVar env bndr, StgRhsClosure ext ccs upd args' body' typ), env) mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr ===================================== compiler/GHC/Stg/Debug.hs ===================================== @@ -68,7 +68,7 @@ collectStgBind (StgRec pairs) = do return (StgRec es) collectStgRhs :: Id -> StgRhs -> M StgRhs -collectStgRhs bndr (StgRhsClosure ext cc us bs e)= do +collectStgRhs bndr (StgRhsClosure ext cc us bs e t) = do let name = idName bndr -- If the name has a span, use that initially as the source position in-case @@ -78,10 +78,10 @@ collectStgRhs bndr (StgRhsClosure ext cc us bs e)= do _ -> id e' <- with_span $ collectExpr e recordInfo bndr e' - return $ StgRhsClosure ext cc us bs e' -collectStgRhs _bndr (StgRhsCon cc dc _mn ticks args) = do + return $ StgRhsClosure ext cc us bs e' t +collectStgRhs _bndr (StgRhsCon cc dc _mn ticks args typ) = do n' <- numberDataCon dc ticks - return (StgRhsCon cc dc n' ticks args) + return (StgRhsCon cc dc n' ticks args typ) recordInfo :: Id -> StgExpr -> M () ===================================== compiler/GHC/Stg/FVs.hs ===================================== @@ -255,13 +255,13 @@ exprFVs env = go rhsFVs :: Env -> StgRhs -> (CgStgRhs, TopFVs, LocalFVs) -rhsFVs env (StgRhsClosure _ ccs uf bs body) +rhsFVs env (StgRhsClosure _ ccs uf bs body typ) | (body', top_fvs, lcl_fvs) <- exprFVs (addLocals bs env) body , let lcl_fvs' = delDVarSetList lcl_fvs bs - = (StgRhsClosure lcl_fvs' ccs uf bs body', top_fvs, lcl_fvs') -rhsFVs env (StgRhsCon ccs dc mu ts bs) + = (StgRhsClosure lcl_fvs' ccs uf bs body' typ, top_fvs, lcl_fvs') +rhsFVs env (StgRhsCon ccs dc mu ts bs typ) | (top_fvs, lcl_fvs) <- argsFVs env bs - = (StgRhsCon ccs dc mu ts bs, top_fvs, lcl_fvs) + = (StgRhsCon ccs dc mu ts bs typ, top_fvs, lcl_fvs) argsFVs :: Env -> [StgArg] -> (TopFVs, LocalFVs) argsFVs env = foldl' f (emptyVarSet, emptyDVarSet) ===================================== compiler/GHC/Stg/InferTags.hs ===================================== @@ -481,7 +481,7 @@ inferTagBind in_env (StgRec pairs) initSig :: forall p. (Id, GenStgRhs p) -> TagSig -- Initial signature for the fixpoint loop initSig (_bndr, StgRhsCon {}) = TagSig TagTagged -initSig (bndr, StgRhsClosure _ _ _ _ _) = +initSig (bndr, StgRhsClosure _ _ _ _ _ _) = fromMaybe defaultSig (idTagSig_maybe bndr) where defaultSig = (TagSig TagTagged) @@ -516,13 +516,13 @@ inferTagRhs :: forall p. -> TagEnv p -- ^ -> GenStgRhs p -- ^ -> (TagSig, GenStgRhs 'InferTaggedBinders) -inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body) +inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body typ) | isDeadEndId bnd_id && (notNull) bndrs -- See Note [Bottom functions are TagTagged] - = (TagSig TagTagged, StgRhsClosure ext cc upd out_bndrs body') + = (TagSig TagTagged, StgRhsClosure ext cc upd out_bndrs body' typ) | otherwise = --pprTrace "inferTagRhsClosure" (ppr (_top, _grp_ids, env,info')) $ - (TagSig info', StgRhsClosure ext cc upd out_bndrs body') + (TagSig info', StgRhsClosure ext cc upd out_bndrs body' typ) where out_bndrs | Just marks <- idCbvMarks_maybe bnd_id @@ -553,11 +553,11 @@ inferTagRhs bnd_id in_env (StgRhsClosure ext cc upd bndrs body) | otherwise -> TagDunno in (id, TagSig tag) -inferTagRhs _ env _rhs@(StgRhsCon cc con cn ticks args) +inferTagRhs _ env _rhs@(StgRhsCon cc con cn ticks args typ) -- Constructors, which have untagged arguments to strict fields -- become thunks. We encode this by giving changing RhsCon nodes the info TagDunno = --pprTrace "inferTagRhsCon" (ppr grp_ids) $ - (TagSig (inferConTag env con args), StgRhsCon cc con cn ticks args) + (TagSig (inferConTag env con args), StgRhsCon cc con cn ticks args typ) -- Adjust let semantics to the targeted backend. -- See Note [Tag inference for interpreted code] ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -1,4 +1,4 @@ --- + -- Copyright (c) 2019 Andreas Klebinger -- @@ -343,7 +343,7 @@ rewriteBinds top_flag b@(StgRec binds) = -- Rewrite a RHS rewriteRhs :: (Id,TagSig) -> InferStgRhs -> RM (TgStgRhs) -rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs_ #-} do +rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args typ) = {-# SCC rewriteRhs_ #-} do -- pprTraceM "rewriteRhs" (ppr _id) -- Look up the nodes representing the constructor arguments. @@ -359,7 +359,7 @@ rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs let evalArgs = [v | StgVarArg v <- needsEval] :: [Id] if (null evalArgs) - then return $! (StgRhsCon ccs con cn ticks args) + then return $! (StgRhsCon ccs con cn ticks args typ) else do --assert not (isTaggedSig tagSig) -- pprTraceM "CreatingSeqs for " $ ppr _id <+> ppr node_id @@ -373,11 +373,11 @@ rewriteRhs (_id, _tagSig) (StgRhsCon ccs con cn ticks args) = {-# SCC rewriteRhs fvs <- fvArgs args -- lcls <- getFVs -- pprTraceM "RhsClosureConversion" (ppr (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) $$ text "lcls:" <> ppr lcls) - return $! (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) -rewriteRhs _binding (StgRhsClosure fvs ccs flag args body) = do + return $! (StgRhsClosure fvs ccs ReEntrant [] $! conExpr) typ +rewriteRhs _binding (StgRhsClosure fvs ccs flag args body typ) = do withBinders NotTopLevel args $ withClosureLcls fvs $ - StgRhsClosure fvs ccs flag (map fst args) <$> rewriteExpr body + StgRhsClosure fvs ccs flag (map fst args) <$> rewriteExpr body <*> pure typ -- return (closure) fvArgs :: [StgArg] -> RM DVarSet ===================================== compiler/GHC/Stg/Lift.hs ===================================== @@ -198,20 +198,20 @@ liftRhs -- as lambda binders, discarding all free vars. -> LlStgRhs -> LiftM OutStgRhs -liftRhs mb_former_fvs rhs@(StgRhsCon ccs con mn ts args) +liftRhs mb_former_fvs rhs@(StgRhsCon ccs con mn ts args typ) = assertPpr (isNothing mb_former_fvs) (text "Should never lift a constructor" $$ pprStgRhs panicStgPprOpts rhs) $ - StgRhsCon ccs con mn ts <$> traverse liftArgs args -liftRhs Nothing (StgRhsClosure _ ccs upd infos body) = + StgRhsCon ccs con mn ts <$> traverse liftArgs args <*> pure typ +liftRhs Nothing (StgRhsClosure _ ccs upd infos body typ) = -- This RHS wasn't lifted. withSubstBndrs (map binderInfoBndr infos) $ \bndrs' -> - StgRhsClosure noExtFieldSilent ccs upd bndrs' <$> liftExpr body -liftRhs (Just former_fvs) (StgRhsClosure _ ccs upd infos body) = + StgRhsClosure noExtFieldSilent ccs upd bndrs' <$> liftExpr body <*> pure typ +liftRhs (Just former_fvs) (StgRhsClosure _ ccs upd infos body typ) = -- This RHS was lifted. Insert extra binders for @former_fvs at . withSubstBndrs (map binderInfoBndr infos) $ \bndrs' -> do let bndrs'' = dVarSetElems former_fvs ++ bndrs' - StgRhsClosure noExtFieldSilent ccs upd bndrs'' <$> liftExpr body + StgRhsClosure noExtFieldSilent ccs upd bndrs'' <$> liftExpr body <*> pure typ liftArgs :: InStgArg -> LiftM OutStgArg liftArgs a@(StgLitArg _) = pure a ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -241,10 +241,10 @@ tagSkeletonBinding is_lne body_skel body_arg_occs (StgRec pairs) bndr' = BindsClosure bndr (bndr `elemVarSet` scope_occs) tagSkeletonRhs :: Id -> CgStgRhs -> (Skeleton, IdSet, LlStgRhs) -tagSkeletonRhs _ (StgRhsCon ccs dc mn ts args) - = (NilSk, mkArgOccs args, StgRhsCon ccs dc mn ts args) -tagSkeletonRhs bndr (StgRhsClosure fvs ccs upd bndrs body) - = (rhs_skel, body_arg_occs, StgRhsClosure fvs ccs upd bndrs' body') +tagSkeletonRhs _ (StgRhsCon ccs dc mn ts args typ) + = (NilSk, mkArgOccs args, StgRhsCon ccs dc mn ts args typ) +tagSkeletonRhs bndr (StgRhsClosure fvs ccs upd bndrs body typ) + = (rhs_skel, body_arg_occs, StgRhsClosure fvs ccs upd bndrs' body' typ) where bndrs' = map BoringBinder bndrs (body_skel, body_arg_occs, body') = tagSkeletonExpr body @@ -330,7 +330,7 @@ goodToLift cfg top_lvl rec_flag expander pairs scope = decide -- We don't lift updatable thunks or constructors any_memoized = any is_memoized_rhs rhss is_memoized_rhs StgRhsCon{} = True - is_memoized_rhs (StgRhsClosure _ _ upd _ _) = isUpdatable upd + is_memoized_rhs (StgRhsClosure _ _ upd _ _ _) = isUpdatable upd -- Don't lift binders occurring as arguments. This would result in complex -- argument expressions which would have to be given a name, reintroducing @@ -399,7 +399,7 @@ goodToLift cfg top_lvl rec_flag expander pairs scope = decide rhsLambdaBndrs :: LlStgRhs -> [Id] rhsLambdaBndrs StgRhsCon{} = [] -rhsLambdaBndrs (StgRhsClosure _ _ _ bndrs _) = map binderInfoBndr bndrs +rhsLambdaBndrs (StgRhsClosure _ _ _ bndrs _ _) = map binderInfoBndr bndrs -- | The size in words of a function closure closing over the given 'Id's, -- including the header. ===================================== compiler/GHC/Stg/Lift/Monad.hs ===================================== @@ -197,12 +197,12 @@ collectFloats = go (0 :: Int) [] -- | Omitting this makes for strange closure allocation schemes that crash the -- GC. removeRhsCCCS :: GenStgRhs pass -> GenStgRhs pass -removeRhsCCCS (StgRhsClosure ext ccs upd bndrs body) +removeRhsCCCS (StgRhsClosure ext ccs upd bndrs body typ) | isCurrentCCS ccs - = StgRhsClosure ext dontCareCCS upd bndrs body -removeRhsCCCS (StgRhsCon ccs con mu ts args) + = StgRhsClosure ext dontCareCCS upd bndrs body typ +removeRhsCCCS (StgRhsCon ccs con mu ts args typ) | isCurrentCCS ccs - = StgRhsCon dontCareCCS con mu ts args + = StgRhsCon dontCareCCS con mu ts args typ removeRhsCCCS rhs = rhs -- | The analysis monad consists of the following 'RWST' components: ===================================== compiler/GHC/Stg/Lint.hs ===================================== @@ -222,25 +222,25 @@ checkNoCurrentCCS rhs = do opts <- getStgPprOpts let rhs' = pprStgRhs opts rhs case rhs of - StgRhsClosure _ ccs _ _ _ + StgRhsClosure _ ccs _ _ _ _ | isCurrentCCS ccs -> addErrL (text "Top-level StgRhsClosure with CurrentCCS" $$ rhs') - StgRhsCon ccs _ _ _ _ + StgRhsCon ccs _ _ _ _ _ | isCurrentCCS ccs -> addErrL (text "Top-level StgRhsCon with CurrentCCS" $$ rhs') _ -> return () lintStgRhs :: (OutputablePass a, BinderP a ~ Id) => GenStgRhs a -> LintM () -lintStgRhs (StgRhsClosure _ _ _ [] expr) +lintStgRhs (StgRhsClosure _ _ _ [] expr _) = lintStgExpr expr -lintStgRhs (StgRhsClosure _ _ _ binders expr) +lintStgRhs (StgRhsClosure _ _ _ binders expr _) = addLoc (LambdaBodyOf binders) $ addInScopeVars binders $ lintStgExpr expr -lintStgRhs rhs@(StgRhsCon _ con _ _ args) = do +lintStgRhs rhs@(StgRhsCon _ con _ _ args _) = do opts <- getStgPprOpts when (isUnboxedTupleDataCon con || isUnboxedSumDataCon con) $ do addErrL (text "StgRhsCon is an unboxed tuple or sum application" $$ ===================================== compiler/GHC/Stg/Stats.hs ===================================== @@ -122,10 +122,10 @@ statBinding top (StgRec pairs) statRhs :: Bool -> (Id, StgRhs) -> StatEnv -statRhs top (_, StgRhsCon _ _ _ _ _) +statRhs top (_, StgRhsCon _ _ _ _ _ _) = countOne (ConstructorBinds top) -statRhs top (_, StgRhsClosure _ _ u _ body) +statRhs top (_, StgRhsClosure _ _ u _ body _) = statExpr body `combineSE` countOne ( case u of ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -393,6 +393,7 @@ data GenStgRhs pass [BinderP pass] -- ^ arguments; if empty, then not a function; -- as above, order is important. (GenStgExpr pass) -- ^ body + Type -- ^ result type {- An example may be in order. Consider: @@ -422,6 +423,7 @@ important): ConstructorNumber [StgTickish] [StgArg] -- Args + Type -- Type, for rewriting to an StgRhsClosure -- | Like 'GHC.Hs.Extension.NoExtField', but with an 'Outputable' instance that -- returns 'empty'. @@ -439,14 +441,14 @@ noExtFieldSilent = NoExtFieldSilent -- implications on build time... stgRhsArity :: StgRhs -> Int -stgRhsArity (StgRhsClosure _ _ _ bndrs _) +stgRhsArity (StgRhsClosure _ _ _ bndrs _ _) = assert (all isId bndrs) $ length bndrs -- The arity never includes type parameters, but they should have gone by now stgRhsArity (StgRhsCon {}) = 0 freeVarsOfRhs :: (XRhsClosure pass ~ DIdSet) => GenStgRhs pass -> DIdSet -freeVarsOfRhs (StgRhsCon _ _ _ _ args) = mkDVarSet [ id | StgVarArg id <- args ] -freeVarsOfRhs (StgRhsClosure fvs _ _ _ _) = fvs +freeVarsOfRhs (StgRhsCon _ _ _ _ args _) = mkDVarSet [ id | StgVarArg id <- args ] +freeVarsOfRhs (StgRhsClosure fvs _ _ _ _ _) = fvs {- ************************************************************************ @@ -892,14 +894,14 @@ instance Outputable AltType where pprStgRhs :: OutputablePass pass => StgPprOpts -> GenStgRhs pass -> SDoc pprStgRhs opts rhs = case rhs of - StgRhsClosure ext cc upd_flag args body + StgRhsClosure ext cc upd_flag args body _ -> hang (hsep [ if stgSccEnabled opts then ppr cc else empty , ppUnlessOption sdocSuppressStgExts (ppr ext) , char '\\' <> ppr upd_flag, brackets (interppSP args) ]) 4 (pprStgExpr opts body) - StgRhsCon cc con mid _ticks args + StgRhsCon cc con mid _ticks args _ -> hcat [ if stgSccEnabled opts then ppr cc <> space else empty , case mid of NoNumber -> empty ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -483,14 +483,14 @@ unariseBinding rho (StgRec xrhss) = StgRec <$> mapM (\(x, rhs) -> (x,) <$> unariseRhs rho rhs) xrhss unariseRhs :: UnariseEnv -> StgRhs -> UniqSM StgRhs -unariseRhs rho (StgRhsClosure ext ccs update_flag args expr) +unariseRhs rho (StgRhsClosure ext ccs update_flag args expr typ) = do (rho', args1) <- unariseFunArgBinders rho args expr' <- unariseExpr rho' expr - return (StgRhsClosure ext ccs update_flag args1 expr') + return (StgRhsClosure ext ccs update_flag args1 expr' typ) -unariseRhs rho (StgRhsCon ccs con mu ts args) +unariseRhs rho (StgRhsCon ccs con mu ts args typ) = assert (not (isUnboxedTupleDataCon con || isUnboxedSumDataCon con)) - return (StgRhsCon ccs con mu ts (unariseConArgs rho args)) + return (StgRhsCon ccs con mu ts (unariseConArgs rho args) typ) -------------------------------------------------------------------------------- ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -350,8 +350,8 @@ schemeR fvs (nm, rhs) -- underlying expression collect :: CgStgRhs -> ([Var], CgStgExpr) -collect (StgRhsClosure _ _ _ args body) = (args, body) -collect (StgRhsCon _cc dc cnum _ticks args) = ([], StgConApp dc cnum args []) +collect (StgRhsClosure _ _ _ args body _) = (args, body) +collect (StgRhsCon _cc dc cnum _ticks args _typ) = ([], StgConApp dc cnum args []) schemeR_wrk :: [Id] @@ -534,7 +534,7 @@ schemeE d s p e@(StgOpApp {}) = schemeT d s p e schemeE d s p (StgLetNoEscape xlet bnd body) = schemeE d s p (StgLet xlet bnd body) schemeE d s p (StgLet _xlet - (StgNonRec x (StgRhsCon _cc data_con _cnum _ticks args)) + (StgNonRec x (StgRhsCon _cc data_con _cnum _ticks args _typ)) body) = do -- Special case for a non-recursive let whose RHS is a -- saturated constructor application. ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -199,12 +199,12 @@ cgTopBinding logger tmpfs cfg = \case cgTopRhs :: StgToCmmConfig -> RecFlag -> Id -> CgStgRhs -> (CgIdInfo, FCode ()) -- The Id is passed along for setting up a binding... -cgTopRhs cfg _rec bndr (StgRhsCon _cc con mn _ts args) +cgTopRhs cfg _rec bndr (StgRhsCon _cc con mn _ts args _typ) = cgTopRhsCon cfg bndr con mn (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise -cgTopRhs cfg rec bndr (StgRhsClosure fvs cc upd_flag args body) +cgTopRhs cfg rec bndr (StgRhsClosure fvs cc upd_flag args body _typ) = assertPpr (isEmptyDVarSet fvs) (text "fvs:" <> ppr fvs) $ -- There should be no free variables cgTopRhsClosure (stgToCmmPlatform cfg) rec bndr cc upd_flag args body ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -250,14 +250,14 @@ cgRhs :: Id -- (see above) ) -cgRhs id (StgRhsCon cc con mn _ts args) +cgRhs id (StgRhsCon cc con mn _ts args _typ) = withNewTickyCounterCon id con mn $ buildDynCon id mn True cc con (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise {- See Note [GC recovery] in "GHC.StgToCmm.Closure" -} -cgRhs id (StgRhsClosure fvs cc upd_flag args body) +cgRhs id (StgRhsClosure fvs cc upd_flag args body _typ) = do profile <- getProfile check_tags <- stgToCmmDoTagCheck <$> getStgToCmmConfig ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -200,9 +200,9 @@ cgLetNoEscapeRhsBody -> Id -> CgStgRhs -> FCode (CgIdInfo, FCode ()) -cgLetNoEscapeRhsBody local_cc bndr (StgRhsClosure _ cc _upd args body) +cgLetNoEscapeRhsBody local_cc bndr (StgRhsClosure _ cc _upd args body _typ) = cgLetNoEscapeClosure bndr local_cc cc (nonVoidIds args) body -cgLetNoEscapeRhsBody local_cc bndr (StgRhsCon cc con mn _ts args) +cgLetNoEscapeRhsBody local_cc bndr (StgRhsCon cc con mn _ts args _typ) = cgLetNoEscapeClosure bndr local_cc cc [] (StgConApp con mn args (pprPanic "cgLetNoEscapeRhsBody" $ text "StgRhsCon doesn't have type args")) ===================================== compiler/GHC/StgToJS/CodeGen.hs ===================================== @@ -290,10 +290,10 @@ genToplevelDecl i rhs = do genToplevelConEntry :: Id -> CgStgRhs -> G JStat genToplevelConEntry i rhs = case rhs of - StgRhsCon _cc con _mu _ts _args + StgRhsCon _cc con _mu _ts _args _typ | isDataConWorkId i -> genSetConInfo i con (stgRhsLive rhs) -- NoSRT - StgRhsClosure _ _cc _upd_flag _args _body + StgRhsClosure _ _cc _upd_flag _args _body _typ | Just dc <- isDataConWorkId_maybe i -> genSetConInfo i dc (stgRhsLive rhs) -- srt _ -> pure mempty @@ -321,11 +321,11 @@ mkDataEntry = ValExpr $ JFunc [] returnStack genToplevelRhs :: Id -> CgStgRhs -> G JStat -- general cases: genToplevelRhs i rhs = case rhs of - StgRhsCon cc con _mu _tys args -> do + StgRhsCon cc con _mu _tys args _typ -> do ii <- identForId i allocConStatic ii cc con args return mempty - StgRhsClosure _ext cc _upd_flag {- srt -} args body -> do + StgRhsClosure _ext cc _upd_flag {- srt -} args body typ -> do {- algorithm: - collect all Id refs that are in the global id cache @@ -335,7 +335,7 @@ genToplevelRhs i rhs = case rhs of -} eid@(TxtI eidt) <- identForEntryId i (TxtI idt) <- identForId i - body <- genBody (initExprCtx i) i R2 args body + body <- genBody (initExprCtx i) R2 args body typ global_occs <- globalOccs (jsSaturate (Just "ghcjs_tmp_sat_") body) let lidents = map global_ident global_occs let lids = map global_id global_occs ===================================== compiler/GHC/StgToJS/Expr.hs ===================================== @@ -74,7 +74,6 @@ import GHC.Core.Type hiding (typeSize) import GHC.Utils.Misc import GHC.Utils.Monad import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import GHC.Utils.Outputable (ppr, renderWithContext, defaultSDocContext) import qualified Control.Monad.Trans.State.Strict as State import GHC.Data.FastString @@ -148,7 +147,7 @@ genBind ctx bndr = ctx' = ctxClearLneFrame ctx assign :: Id -> CgStgRhs -> G (Maybe JStat) - assign b (StgRhsClosure _ _ccs {-[the_fv]-} _upd [] expr) + assign b (StgRhsClosure _ _ccs {-[the_fv]-} _upd [] expr _typ) | let strip = snd . stripStgTicksTop (not . tickishIsCode) , StgCase (StgApp scrutinee []) _ (AlgAlt _) [GenStgAlt (DataAlt _) params sel_expr] <- strip expr , StgApp selectee [] <- strip sel_expr @@ -168,7 +167,7 @@ genBind ctx bndr = ([tgt], [the_fvj]) -> return $ Just (tgt ||= ApplExpr (var ("h$c_sel_" <> mkFastString sel_tag)) [the_fvj]) _ -> panic "genBind.assign: invalid size" - assign b (StgRhsClosure _ext _ccs _upd [] expr) + assign b (StgRhsClosure _ext _ccs _upd [] expr _typ) | snd (isInlineExpr (ctxEvaluatedIds ctx) expr) = do d <- declVarsForId b tgt <- varsForId b @@ -180,9 +179,9 @@ genBind ctx bndr = addEvalRhs c [] = c addEvalRhs c ((b,r):xs) - | StgRhsCon{} <- r = addEvalRhs (ctxAssertEvaluated b c) xs - | (StgRhsClosure _ _ ReEntrant _ _) <- r = addEvalRhs (ctxAssertEvaluated b c) xs - | otherwise = addEvalRhs c xs + | StgRhsCon{} <- r = addEvalRhs (ctxAssertEvaluated b c) xs + | (StgRhsClosure _ _ ReEntrant _ _ _) <- r = addEvalRhs (ctxAssertEvaluated b c) xs + | otherwise = addEvalRhs c xs genBindLne :: HasDebugCallStack => ExprCtx @@ -223,7 +222,7 @@ genBindLne ctx bndr = do -- is initially set to null, changed to h$blackhole when the thunk is being evaluated. -- genEntryLne :: HasDebugCallStack => ExprCtx -> Id -> CgStgRhs -> G () -genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = +genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body typ) = resetSlots $ do let payloadSize = ctxLneFrameSize ctx vars = ctxLneFrameVars ctx @@ -238,7 +237,7 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = ]) | otherwise = mempty lvs <- popLneFrame True payloadSize ctx - body <- genBody ctx i R1 args body + body <- genBody ctx R1 args body typ ei@(TxtI eii) <- identForEntryId i sr <- genStaticRefsRhs rhs let f = JFunc [] (bh <> lvs <> body) @@ -251,7 +250,7 @@ genEntryLne ctx i rhs@(StgRhsClosure _ext _cc update args body) = CIStackFrame sr emitToplevel (ei ||= toJExpr f) -genEntryLne ctx i (StgRhsCon cc con _mu _ticks args) = resetSlots $ do +genEntryLne ctx i (StgRhsCon cc con _mu _ticks args _typ) = resetSlots $ do let payloadSize = ctxLneFrameSize ctx ei@(TxtI _eii) <- identForEntryId i -- di <- varForDataConWorker con @@ -265,12 +264,12 @@ genEntryLne ctx i (StgRhsCon cc con _mu _ticks args) = resetSlots $ do -- | Generate the entry function for a local closure genEntry :: HasDebugCallStack => ExprCtx -> Id -> CgStgRhs -> G () genEntry _ _i StgRhsCon {} = return () -genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body) = resetSlots $ do +genEntry ctx i rhs@(StgRhsClosure _ext cc {-_bi live-} upd_flag args body typ) = resetSlots $ do let live = stgLneLiveExpr rhs -- error "fixme" -- probably find live vars in body ll <- loadLiveFun live llv <- verifyRuntimeReps live upd <- genUpdFrame upd_flag i - body <- genBody entryCtx i R2 args body + body <- genBody entryCtx R2 args body typ ei@(TxtI eii) <- identForEntryId i et <- genEntryType args setcc <- ifProfiling $ @@ -302,12 +301,12 @@ genEntryType args0 = do -- | Generate the body of an object genBody :: HasDebugCallStack => ExprCtx - -> Id -> StgReg -> [Id] -> CgStgExpr + -> Type -> G JStat -genBody ctx i startReg args e = do +genBody ctx startReg args e typ = do -- load arguments into local variables la <- do args' <- concatMapM genIdArgI args @@ -318,7 +317,7 @@ genBody ctx i startReg args e = do -- compute PrimReps and their number of slots required to return the result of -- i applied to args. - let res_vars = resultSize args i + let res_vars = resultSize typ -- compute typed expressions for each slot and assign registers let go_var regs = \case @@ -359,22 +358,12 @@ genBody ctx i startReg args e = do -- In case of failure to determine the type, we default to LiftedRep as it's -- probably what it is. -- -resultSize :: HasDebugCallStack => [Id] -> Id -> [(PrimRep, Int)] -resultSize args i = result +resultSize :: HasDebugCallStack => Type -> [(PrimRep, Int)] +resultSize ty = result where result = result_reps `zip` result_slots result_slots = fmap (slotCount . primRepSize) result_reps - result_reps = trim_args (unwrapType (idType i)) (length args) - - trim_args t 0 = typePrimRep t - trim_args t n - | Just (_af, _mult, arg, res) <- splitFunTy_maybe t - , nargs <- length (typePrimRepArgs arg) - , assert (n >= nargs) True - = trim_args (unwrapType res) (n - nargs) - | otherwise - = pprTrace "result_type: not a function type, assume LiftedRep" (ppr t) - [LiftedRep] + result_reps = typePrimRep ty -- | Ensure that the set of identifiers has valid 'RuntimeRep's. This function -- returns a no-op when 'csRuntimeAssert' in 'StgToJSConfig' is False. @@ -540,19 +529,19 @@ allocCls dynMiddle xs = do toCl (i, StgRhsCon cc con []) = do ii <- identForId i Left <$> (return (decl ii) <> allocCon ii con cc []) -} - toCl (i, StgRhsCon cc con _mui _ticjs [a]) | isUnboxableCon con = do + toCl (i, StgRhsCon cc con _mui _ticjs [a] _typ) | isUnboxableCon con = do ii <- identForId i ac <- allocCon ii con cc =<< genArg a pure (Left (decl ii <> ac)) -- dynamics - toCl (i, StgRhsCon cc con _mu _ticks ar) = + toCl (i, StgRhsCon cc con _mu _ticks ar _typ) = -- fixme do we need to handle unboxed? Right <$> ((,,,) <$> identForId i <*> varForDataConWorker con <*> concatMapM genArg ar <*> pure cc) - toCl (i, cl@(StgRhsClosure _ext cc _upd_flag _args _body)) = + toCl (i, cl@(StgRhsClosure _ext cc _upd_flag _args _body _typ)) = let live = stgLneLiveExpr cl in Right <$> ((,,,) <$> identForId i <*> varForEntryId i ===================================== compiler/GHC/StgToJS/Sinker.hs ===================================== @@ -64,11 +64,11 @@ sinkPgm' m pgm = alwaysSinkable :: CgStgBinding -> [(Id, CgStgExpr)] alwaysSinkable (StgRec {}) = [] alwaysSinkable (StgNonRec b rhs) = case rhs of - StgRhsClosure _ _ _ _ e@(StgLit l) + StgRhsClosure _ _ _ _ e@(StgLit l) _ | isSmallSinkableLit l , isLocal b -> [(b,e)] - StgRhsCon _ccs dc cnum _ticks as@[StgLitArg l] + StgRhsCon _ccs dc cnum _ticks as@[StgLitArg l] _typ | isSmallSinkableLit l , isLocal b , isUnboxableCon dc @@ -88,9 +88,9 @@ onceSinkable _m (StgNonRec b rhs) , isLocal b = [(b,e)] where getSinkable = \case - StgRhsCon _ccs dc cnum _ticks args -> Just (StgConApp dc cnum args []) - StgRhsClosure _ _ _ _ e@(StgLit{}) -> Just e - _ -> Nothing + StgRhsCon _ccs dc cnum _ticks args _typ -> Just (StgConApp dc cnum args []) + StgRhsClosure _ _ _ _ e@(StgLit{}) _typ -> Just e + _ -> Nothing onceSinkable _ _ = [] -- | collect all idents used only once in an argument at the top level @@ -115,8 +115,8 @@ collectArgsTop = \case collectArgsTopRhs :: CgStgRhs -> [Id] collectArgsTopRhs = \case - StgRhsCon _ccs _dc _mu _ticks args -> concatMap collectArgsA args - StgRhsClosure {} -> [] + StgRhsCon _ccs _dc _mu _ticks args _typ -> concatMap collectArgsA args + StgRhsClosure {} -> [] -- | fold over all Id in StgArg in the AST collectArgs :: CgStgBinding -> [Id] @@ -126,8 +126,8 @@ collectArgs = \case collectArgsR :: CgStgRhs -> [Id] collectArgsR = \case - StgRhsClosure _x0 _x1 _x2 _x3 e -> collectArgsE e - StgRhsCon _ccs _con _mu _ticks args -> concatMap collectArgsA args + StgRhsClosure _x0 _x1 _x2 _x3 e _typ -> collectArgsE e + StgRhsCon _ccs _con _mu _ticks args _typ -> concatMap collectArgsA args collectArgsAlt :: CgStgAlt -> [Id] collectArgsAlt alt = collectArgsE (alt_rhs alt) @@ -171,7 +171,7 @@ topSortDecls _m binds = rest ++ nr' keys = mkUniqSet (map node_key vs) getV e@(StgNonRec b _) = DigraphNode e b [] getV _ = error "topSortDecls: getV, unexpected binding" - collectDeps (StgNonRec b (StgRhsCon _cc _dc _cnum _ticks args)) = + collectDeps (StgNonRec b (StgRhsCon _cc _dc _cnum _ticks args _typ)) = [ (i, b) | StgVarArg i <- args, i `elementOfUniqSet` keys ] collectDeps _ = [] g = graphFromVerticesAndAdjacency vs (concatMap collectDeps nr) ===================================== compiler/GHC/StgToJS/StgUtils.hs ===================================== @@ -67,8 +67,8 @@ bindingRefs u = \case rhsRefs :: UniqFM Id CgStgExpr -> CgStgRhs -> Set Id rhsRefs u = \case - StgRhsClosure _ _ _ _ body -> exprRefs u body - StgRhsCon _ccs d _mu _ticks args -> l s [ i | AnId i <- dataConImplicitTyThings d] <> l (argRefs u) args + StgRhsClosure _ _ _ _ body _ -> exprRefs u body + StgRhsCon _ccs d _mu _ticks args _ -> l s [ i | AnId i <- dataConImplicitTyThings d] <> l (argRefs u) args exprRefs :: UniqFM Id CgStgExpr -> CgStgExpr -> Set Id exprRefs u = \case @@ -97,7 +97,7 @@ hasExport bnd = StgNonRec b e -> isExportedBind b e StgRec bs -> any (uncurry isExportedBind) bs where - isExportedBind _i (StgRhsCon _cc con _ _ _) = + isExportedBind _i (StgRhsCon _cc con _ _ _ _) = getUnique con == staticPtrDataConKey isExportedBind _ _ = False @@ -152,8 +152,8 @@ stgBindRhsLive b = stgRhsLive :: CgStgRhs -> LiveVars stgRhsLive = \case - StgRhsClosure _ _ _ args e -> delDVarSetList (stgExprLive True e) args - StgRhsCon _ _ _ _ args -> unionDVarSets (map stgArgLive args) + StgRhsClosure _ _ _ args e _ -> delDVarSetList (stgExprLive True e) args + StgRhsCon _ _ _ _ args _ -> unionDVarSets (map stgArgLive args) stgArgLive :: StgArg -> LiveVars stgArgLive = \case @@ -189,8 +189,8 @@ bindees = \case StgRec bs -> map fst bs isUpdatableRhs :: CgStgRhs -> Bool -isUpdatableRhs (StgRhsClosure _ _ u _ _) = isUpdatable u -isUpdatableRhs _ = False +isUpdatableRhs (StgRhsClosure _ _ u _ _ _) = isUpdatable u +isUpdatableRhs _ = False stgLneLive' :: CgStgBinding -> [Id] stgLneLive' b = filter (`notElem` bindees b) (stgLneLive b) @@ -241,9 +241,9 @@ inspectInlineBinding v = \case inspectInlineRhs :: UniqSet Id -> Id -> CgStgRhs -> UniqSet Id inspectInlineRhs v i = \case - StgRhsCon{} -> addOneToUniqSet v i - StgRhsClosure _ _ ReEntrant _ _ -> addOneToUniqSet v i - _ -> v + StgRhsCon{} -> addOneToUniqSet v i + StgRhsClosure _ _ ReEntrant _ _ _ -> addOneToUniqSet v i + _ -> v isInlineForeignCall :: ForeignCall -> Bool isInlineForeignCall (CCall (CCallSpec _ cconv safety)) = ===================================== testsuite/tests/dependent/should_compile/all.T ===================================== @@ -40,7 +40,7 @@ test('T13938', [req_th, extra_files(['T13938a.hs'])], makefile_test, ['T13938']) test('T14556', normal, compile, ['']) test('T14720', normal, compile, ['']) test('T14066a', normal, compile, ['']) -test('T14749', js_broken(22364), compile, ['']) +test('T14749', normal, compile, ['']) test('T14991', normal, compile, ['']) test('DkNameRes', normal, compile, ['']) test('T15346', normal, compile, ['']) ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -85,7 +85,7 @@ test('RepPolyUnliftedNewtype', normal, compile, ['-fno-warn-partial-type-signatures -fno-warn-deprecated-flags']) test('RepPolyWildcardPattern', normal, compile_fail, ['']) test('RepPolyWrappedVar', normal, compile_fail, ['']) -test('RepPolyWrappedVar2', js_broken(23280), compile, ['']) +test('RepPolyWrappedVar2', normal, compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -587,7 +587,7 @@ test('T13651a', normal, compile, ['']) test('T13680', normal, compile, ['']) test('T13785', normal, compile, ['']) test('T13804', normal, compile, ['']) -test('T13822', js_broken(22364), compile, ['']) +test('T13822', normal, compile, ['']) test('T13848', normal, compile, ['']) test('T13879', normal, compile, ['']) test('T13881', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_run/all.T ===================================== @@ -126,7 +126,7 @@ test('KindInvariant', normal, ghci_script, ['KindInvariant.script']) # unboxed sums and ghci does not support those yet. test('StrictPats', omit_ways(['ghci']), compile_and_run, ['']) test('T12809', omit_ways(['ghci']), compile_and_run, ['']) -test('EtaExpandLevPoly', [omit_ways(['ghci']), js_broken(22576)], compile_and_run, ['']) +test('EtaExpandLevPoly', [omit_ways(['ghci'])], compile_and_run, ['']) test('TestTypeableBinary', normal, compile_and_run, ['']) test('Typeable1', normal, compile_fail, ['-Werror']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77f506b888624b4fd30205fb8512f39435055a27 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/77f506b888624b4fd30205fb8512f39435055a27 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 18:52:24 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 26 Apr 2023 14:52:24 -0400 Subject: [Git][ghc/ghc][master] EPA: Use ExplicitBraces only in HsModule Message-ID: <644972e8d6896_178e74e234b4d417555f6@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - 21 changed files: - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - testsuite/tests/ghc-api/exactprint/T22919.stderr - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/module/mod185.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr - testsuite/tests/parser/should_compile/DumpSemis.stderr - testsuite/tests/parser/should_compile/KindSigs.stderr - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/parser/should_compile/T20452.stderr - testsuite/tests/parser/should_compile/T20718.stderr - testsuite/tests/parser/should_compile/T20718b.stderr - testsuite/tests/parser/should_compile/T20846.stderr - testsuite/tests/printer/T18791.stderr - testsuite/tests/printer/Test20297.stdout - utils/check-exact/ExactPrint.hs - utils/check-exact/Parsers.hs Changes: ===================================== compiler/GHC/Hs.hs ===================================== @@ -101,7 +101,7 @@ deriving instance Data (HsModule GhcPs) data AnnsModule = AnnsModule { am_main :: [AddEpAnn], - am_decls :: AnnList, + am_decls :: [TrailingAnn], am_eof :: Maybe (RealSrcSpan, RealSrcSpan) -- End of file and end of prior token } deriving (Data, Eq) ===================================== compiler/GHC/Parser.y ===================================== @@ -925,20 +925,17 @@ maybemodwarning :: { Maybe (LocatedP (WarningTxt GhcPs)) } (AnnPragma (mo $1) (mc $4) (fst $ unLoc $3))} | {- empty -} { Nothing } -body :: { (AnnList +body :: { ([TrailingAnn] ,([LImportDecl GhcPs], [LHsDecl GhcPs]) ,LayoutInfo GhcPs) } - : '{' top '}' { (AnnList Nothing (Just $ moc $1) (Just $ mcc $3) [] (fst $2) - , snd $2, explicitBraces $1 $3) } - | vocurly top close { (AnnList Nothing Nothing Nothing [] (fst $2) - , snd $2, VirtualBraces (getVOCURLY $1)) } + : '{' top '}' { (fst $2, snd $2, explicitBraces $1 $3) } + | vocurly top close { (fst $2, snd $2, VirtualBraces (getVOCURLY $1)) } -body2 :: { (AnnList +body2 :: { ([TrailingAnn] ,([LImportDecl GhcPs], [LHsDecl GhcPs]) ,LayoutInfo GhcPs) } - : '{' top '}' { (AnnList Nothing (Just $ moc $1) (Just $ mcc $3) [] (fst $2) - , snd $2, explicitBraces $1 $3) } - | missing_module_keyword top close { (AnnList Nothing Nothing Nothing [] [], snd $2, VirtualBraces leftmostColumn) } + : '{' top '}' { (fst $2, snd $2, explicitBraces $1 $3) } + | missing_module_keyword top close { ([], snd $2, VirtualBraces leftmostColumn) } top :: { ([TrailingAnn] @@ -957,14 +954,14 @@ header :: { Located (HsModule GhcPs) } : 'module' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs (\cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] (AnnList Nothing Nothing Nothing [] []) Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) NoLayoutInfo $3 Nothing) (Just $2) $4 $6 [] ))) } | 'signature' modid maybemodwarning maybeexports 'where' header_body {% fileSrcSpan >>= \ loc -> acs (\cs -> (L loc (HsModule (XModulePs - (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] (AnnList Nothing Nothing Nothing [] []) Nothing) cs) + (EpAnn (spanAsAnchor loc) (AnnsModule [mj AnnModule $1,mj AnnWhere $5] [] Nothing) cs) NoLayoutInfo $3 Nothing) (Just $2) $4 $6 [] ))) } ===================================== testsuite/tests/ghc-api/exactprint/T22919.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T22919.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T22919.hs:1:29-33 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T22919.hs:3:1 } ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { Test20239.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20239.hs:1:18-22 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { Test20239.hs:8:1 } ===================================== testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { ZeroWidthSemi.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { ZeroWidthSemi.hs:1:22-26 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { ZeroWidthSemi.hs:9:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T17544.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544.hs:3:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) [] - []) (Just ((,) { T17544.hs:57:1 } ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T17544_kw.hs:11:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T17544_kw.hs:13:13-17 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) [] - []) (Just ((,) { T17544_kw.hs:25:1 } ===================================== testsuite/tests/module/mod185.stderr ===================================== @@ -11,12 +11,7 @@ (UnchangedAnchor)) (AnnsModule [] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { mod185.hs:6:1 } ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { DumpParsedAst.hs:5:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAst.hs:5:22-26 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { DumpParsedAst.hs:25:1 } ===================================== testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr ===================================== @@ -13,12 +13,7 @@ [(AddEpAnn AnnModule (EpaSpan { DumpParsedAstComments.hs:5:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpParsedAstComments.hs:5:30-34 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { DumpParsedAstComments.hs:20:1 } ===================================== testsuite/tests/parser/should_compile/DumpSemis.stderr ===================================== @@ -12,23 +12,18 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { DumpSemis.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { DumpSemis.hs:1:18-22 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - [(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:1 })) - ,(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:2 })) - ,(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:3 })) - ,(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:4 })) - ,(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:7 })) - ,(AddSemiAnn - (EpaSpan { DumpSemis.hs:4:8 }))]) + [(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:1 })) + ,(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:2 })) + ,(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:3 })) + ,(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:4 })) + ,(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:7 })) + ,(AddSemiAnn + (EpaSpan { DumpSemis.hs:4:8 }))] (Just ((,) { DumpSemis.hs:46:1 } ===================================== testsuite/tests/parser/should_compile/KindSigs.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { KindSigs.hs:6:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { KindSigs.hs:6:17-21 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { KindSigs.hs:36:1 } ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T15323.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T15323.hs:3:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T15323.hs:7:1 } ===================================== testsuite/tests/parser/should_compile/T20452.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T20452.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20452.hs:3:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T20452.hs:10:1 } ===================================== testsuite/tests/parser/should_compile/T20718.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T20718.hs:3:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718.hs:3:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T20718.hs:12:1 } ===================================== testsuite/tests/parser/should_compile/T20718b.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T20718b.hs:4:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20718b.hs:4:16-20 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T20718b.hs:8:1 } ===================================== testsuite/tests/parser/should_compile/T20846.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T20846.hs:1:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T20846.hs:1:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T20846.hs:5:1 } ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { T18791.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { T18791.hs:2:15-19 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { T18791.hs:6:1 } ===================================== testsuite/tests/printer/Test20297.stdout ===================================== @@ -12,12 +12,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { Test20297.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.hs:2:18-22 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { Test20297.hs:12:1 } @@ -357,12 +352,7 @@ (AnnsModule [(AddEpAnn AnnModule (EpaSpan { Test20297.ppr.hs:2:1-6 })) ,(AddEpAnn AnnWhere (EpaSpan { Test20297.ppr.hs:2:18-22 }))] - (AnnList - (Nothing) - (Nothing) - (Nothing) - [] - []) + [] (Just ((,) { Test20297.ppr.hs:9:25 } ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -1203,24 +1203,6 @@ markAnnListA reallyTrail an action = do debugM $ "markAnnListA: an5=" ++ showAst an return (an5, r) - -markAnnList' :: (Monad m, Monoid w) - => Bool -> EpAnn AnnList -> EP w m a -> EP w m (EpAnn AnnList, a) -markAnnList' reallyTrail an action = do - p <- getPosP - debugM $ "markAnnList : " ++ showPprUnsafe (p, an) - an0 <- markLensMAA an lal_open - an1 <- if (not reallyTrail) - then markTrailingL an0 lal_trailing - else return an0 - an2 <- markEpAnnAllL an1 lal_rest AnnSemi - r <- action - an3 <- markLensMAA an2 lal_close - an4 <- if reallyTrail - then markTrailingL an3 lal_trailing - else return an3 - return (an4, r) - -- --------------------------------------------------------------------- printComments :: (Monad m, Monoid w) => RealSrcSpan -> EP w m () @@ -1387,14 +1369,21 @@ instance ExactPrint (HsModule GhcPs) where return (an1, Just m', mdeprec', mexports') - let ann_decls = EpAnn (entry an) (am_decls $ anns an0) emptyComments - (ann_decls', (decls', imports')) <- markAnnList' False ann_decls $ do - imports' <- markTopLevelList imports - decls' <- markTopLevelList decls - return (decls', imports') - let am_decls' = case ann_decls' of - EpAnnNotUsed -> (am_decls $ anns an0) - EpAnn _ r _ -> r + lo0 <- case lo of + ExplicitBraces open close -> do + open' <- markToken open + return (ExplicitBraces open' close) + _ -> return lo + + am_decls' <- markTrailing (am_decls $ anns an0) + imports' <- markTopLevelList imports + decls' <- markTopLevelList decls + + lo1 <- case lo0 of + ExplicitBraces open close -> do + close' <- markToken close + return (ExplicitBraces open close') + _ -> return lo -- Print EOF case am_eof $ anns an of @@ -1406,7 +1395,7 @@ instance ExactPrint (HsModule GhcPs) where let anf = an0 { anns = (anns an0) { am_decls = am_decls' }} debugM $ "HsModule, anf=" ++ showAst anf - return (HsModule (XModulePs anf lo mdeprec' mbDoc') mmn' mexports' imports' decls') + return (HsModule (XModulePs anf lo1 mdeprec' mbDoc') mmn' mexports' imports' decls') -- --------------------------------------------------------------------- ===================================== utils/check-exact/Parsers.hs ===================================== @@ -276,16 +276,15 @@ fixModuleTrailingComments :: GHC.ParsedSource -> GHC.ParsedSource fixModuleTrailingComments (GHC.L l p) = GHC.L l p' where an' = case GHC.hsmodAnn $ GHC.hsmodExt p of - (GHC.EpAnn a an ocs) -> GHC.EpAnn a an (rebalance (GHC.am_decls an) ocs) + (GHC.EpAnn a an ocs) -> GHC.EpAnn a an (rebalance ocs) unused -> unused p' = p { GHC.hsmodExt = (GHC.hsmodExt p){ GHC.hsmodAnn = an' } } - -- p' = error $ "fixModuleTrailingComments: an'=" ++ showAst an' - rebalance :: GHC.AnnList -> GHC.EpAnnComments -> GHC.EpAnnComments - rebalance al cs = cs' + rebalance :: GHC.EpAnnComments -> GHC.EpAnnComments + rebalance cs = cs' where - cs' = case GHC.al_close al of - Just (GHC.AddEpAnn _ (GHC.EpaSpan ss _)) -> + cs' = case GHC.hsmodLayout $ GHC.hsmodExt p of + GHC.ExplicitBraces _ (GHC.L (GHC.TokenLoc (GHC.EpaSpan ss _)) _) -> let pc = GHC.priorComments cs fc = GHC.getFollowingComments cs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/052e2bb629abc97b394b9de2394eb36cbed9385f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/052e2bb629abc97b394b9de2394eb36cbed9385f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 19:11:59 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 26 Apr 2023 15:11:59 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] WIP: Do the right thing; needs documentation Message-ID: <6449777f90e7d_178e74e2b451bc1760683@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: b75b3f37 by Rodrigo Mesquita at 2023-04-26T20:11:54+01:00 WIP: Do the right thing; needs documentation - - - - - 1 changed file: - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -41,6 +41,7 @@ import GHC.Data.FastString import GHC.Types.Id import GHC.Types.Id.Info( CafInfo( NoCafRefs ) ) import GHC.Types.Name (isInternalName) +import GHC.Types.Var (varName) import GHC.Types.RepType (countConRepArgs) import GHC.Types.Literal import GHC.Builtin.Utils @@ -328,16 +329,10 @@ precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid St precomputedStaticConInfo_maybe cfg binder con [] -- Nullary constructors (list of nonvoid args is null) = assert (hasNoNonZeroWidthArgs con) $ - if isDataConWorkId binder && not (isNullaryRepDataCon con) - -- this data con worker (TODO: what about wrappers?) only has zero-width - -- args, so we point to its short con app closure instead of its - -- function ( rememeber, we generate 2 closures for a data con that only - -- has zero-width args: one for the function it actually is, another for - -- the precomputed static closure we can still have for it ) - then Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) - (CmmLabel (mkShortConAppLabel (dataConName con) NoCafRefs)) - else Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) - (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) + Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + (CmmLabel (mkClosureLabel (varName $ dataConWrapId con) NoCafRefs)) -- ROMES:TODO: note about this + -- the error was we now were falling in this branch for the wrappers too, but returning the dataConName instead of the wrapper. + -- If we always return 'dataConWrapId' this works. If there is a wrapper for the nullary constructor, it is what we want to use; otherwise, dataConWrapId falls back to the worker just as we needed precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS | intClosure || charClosure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b75b3f37312493ad0acadffe88dc1b38ca8614c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b75b3f37312493ad0acadffe88dc1b38ca8614c8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 22:21:03 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Wed, 26 Apr 2023 18:21:03 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 21 commits: More informative errors for bad imports (#21826) Message-ID: <6449a3cf574f0_178e74e61b532817951d8@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - f059f5e0 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 First steps killing unifyWanted - - - - - 05e89f64 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Fix a boo boo - - - - - c0e4579b by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Fix another error: missing kick-out - - - - - 79bd8a86 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Maybe working now - - - - - 57498cb1 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Wibbles - - - - - 585f2b92 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Stop loop - - - - - 0254f781 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Wibbles - - - - - 944158af by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 More wibbles - - - - - 89e05756 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 undo accidental change to GHC.Bits - - - - - 94cfd691 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Wibble error messages - - - - - 92be70fd by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Experimental change: coercion holes Experiment with making a constraint non-canonical if it has a coercion hole on the RHS. Simplifies T22707 a lot! - - - - - 6697584e by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 More wibbles - - - - - aee2f98c by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Priorities non-rewritten equalities in the work list Plus update error output - - - - - c305e5c7 by Simon Peyton Jones at 2023-04-26T23:22:45+01:00 Further wibbles Fix to defaulting in rules - - - - - 30 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/40cd1bddd39b881a3f0cde10570556916adcf4e9...c305e5c7e3d27e2325b5a71d6d8458cf697bff4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/40cd1bddd39b881a3f0cde10570556916adcf4e9...c305e5c7e3d27e2325b5a71d6d8458cf697bff4d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Apr 26 22:29:10 2023 From: gitlab at gitlab.haskell.org (Alan Zimmerman (@alanz)) Date: Wed, 26 Apr 2023 18:29:10 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/az/locateda-epa-improve-2023-03-27 Message-ID: <6449a5b633d07_178e74e63392081797012@gitlab.mail> Alan Zimmerman pushed new branch wip/az/locateda-epa-improve-2023-03-27 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/az/locateda-epa-improve-2023-03-27 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 08:05:38 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 27 Apr 2023 04:05:38 -0400 Subject: [Git][ghc/ghc][wip/T23083] 6 commits: More explicit strictness in GHC.Real Message-ID: <644a2cd2cb51_178e74efa776c418291ca@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 4668e195 by Sebastian Graf at 2023-04-27T10:05:31+02:00 More explicit strictness in GHC.Real - - - - - 2bd03456 by Sebastian Graf at 2023-04-27T10:05:31+02:00 exprIsTrivial: Factor out shared implementation The duplication between `exprIsTrivial` and `getIdFromTrivialExpr_maybe` has been bugging me for a long time. This patch introduces an inlinable worker function `trivial_expr_fold` acting as the single, shared decision procedure of triviality. It "returns" a Church-encoded `Maybe (Maybe Id)`, so when it is inlined, it fuses to similar code as before. (Better code, even, in the case of `getIdFromTrivialExpr` which presently allocates a `Just` constructor that cancels away after this patch.) - - - - - 2fb9b7d3 by Sebastian Graf at 2023-04-27T10:05:31+02:00 Simplify: Simplification of arguments in a single function The Simplifier had a function `simplArg` that wasn't called in `rebuildCall`, which seems to be the main way to simplify args. Hence I consolidated the code path to call `simplArg`, too, renaming to `simplLazyArg`. - - - - - ab26a3dc by Sebastian Graf at 2023-04-27T10:05:31+02:00 Core.Ppr: Omit case binder for empty case alternatives A minor improvement to pretty-printing - - - - - fe36a33c by Sebastian Graf at 2023-04-27T10:05:31+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - 084fb648 by Sebastian Graf at 2023-04-27T10:05:31+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e721cc6f460f3c44e2ff3c846e8ac60e4a980e01...084fb6480828ee322dd35c0d8559ea38d6a70f0d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e721cc6f460f3c44e2ff3c846e8ac60e4a980e01...084fb6480828ee322dd35c0d8559ea38d6a70f0d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 09:18:49 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 27 Apr 2023 05:18:49 -0400 Subject: [Git][ghc/ghc][wip/codebuffer-perftest] base/encoding: add an allocations performance test (#22946) Message-ID: <644a3df9ee9dc_178e74f0c75de418448c5@gitlab.mail> Josh Meredith pushed to branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC Commits: a622488d by Josh Meredith at 2023-04-27T09:18:36+00:00 base/encoding: add an allocations performance test (#22946) - - - - - 2 changed files: - libraries/base/tests/perf/all.T - + libraries/base/tests/perf/encodingAllocations.hs Changes: ===================================== libraries/base/tests/perf/all.T ===================================== @@ -3,3 +3,9 @@ #-------------------------------------- test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) + +#-------------------------------------- + +# We don't expect the code in test to vary at all, but the variance is set to +# 1% in case the constant allocations increase by other means. +test('encodingAllocations', collect_stats('bytes allocated', 1), compile_and_run, ['-O2']) ===================================== libraries/base/tests/perf/encodingAllocations.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -dno-typeable-binds -O2 #-} + +module Main (main) where + +import System.IO +import Data.Bits +import GHC.Int +import GHC.Exts +import System.Environment + +devnull :: FilePath +#if defined(mingw32_HOST_OS) +devnull = "NUL" +#else +devnull = "/dev/null" +#endif + +main :: IO () +main = withFile devnull WriteMode (loop 1000000) + +loop :: Int -> Handle -> IO () +loop 0 !_ = pure () +loop !n !h = do + hPutChar h $! dummy_char n + loop (n-1) h + +-- unsafe efficient version of `chr` +my_chr :: Int -> Char +my_chr (I# i) = C# (chr# i) + +-- return either a or b +dummy_char :: Int -> Char +dummy_char !i = my_chr ((i .&. 1) + 97) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a622488d8168cf9223cd705cac73ad115f095b2f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a622488d8168cf9223cd705cac73ad115f095b2f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 09:26:27 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 27 Apr 2023 05:26:27 -0400 Subject: [Git][ghc/ghc][wip/unitidset] WIP refactor `Set UnitId` to `UniqDSet UnitId` Message-ID: <644a3fc3b9e2d_178e74f139e620184740@gitlab.mail> Josh Meredith pushed to branch wip/unitidset at Glasgow Haskell Compiler / GHC Commits: 1a30871d by Josh Meredith at 2023-04-27T09:26:05+00:00 WIP refactor `Set UnitId` to `UniqDSet UnitId` - - - - - 21 changed files: - compiler/GHC.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Module/Deps.hs - compiler/GHC/Unit/Module/ModGuts.hs - compiler/GHC/Unit/State.hs - compiler/GHC/Unit/Types.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -395,6 +395,7 @@ import GHC.Types.Name.Ppr import GHC.Types.TypeEnv import GHC.Types.BreakInfo import GHC.Types.PkgQual +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -418,8 +419,6 @@ import Data.Typeable ( Typeable ) import Data.Word ( Word8 ) import qualified Data.Map.Strict as Map -import Data.Set (Set) -import qualified Data.Set as S import qualified Data.Sequence as Seq import System.Directory @@ -604,7 +603,7 @@ setSessionDynFlags dflags0 = do logger <- getLogger dflags <- checkNewDynFlags logger dflags0 let all_uids = hsc_all_home_unit_ids hsc_env - case S.toList all_uids of + case uniqDSetToList all_uids of [uid] -> do setUnitDynFlagsNoCheck uid dflags modifySession (hscUpdateLoggerFlags . hscSetActiveUnitId (homeUnitId_ dflags)) @@ -1379,7 +1378,7 @@ data ModuleInfo = ModuleInfo { -- | Request information about a loaded 'Module' getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo) -- XXX: Maybe X getModuleInfo mdl = withSession $ \hsc_env -> do - if moduleUnitId mdl `S.member` hsc_all_home_unit_ids hsc_env + if moduleUnitId mdl `elementOfUniqDSet` hsc_all_home_unit_ids hsc_env then liftIO $ getHomeModuleInfo hsc_env mdl else liftIO $ getPackageModuleInfo hsc_env mdl @@ -1756,7 +1755,7 @@ isModuleTrusted m = withSession $ \hsc_env -> liftIO $ hscCheckSafe hsc_env m noSrcSpan -- | Return if a module is trusted and the pkgs it depends on to be trusted. -moduleTrustReqs :: GhcMonad m => Module -> m (Bool, Set UnitId) +moduleTrustReqs :: GhcMonad m => Module -> m (Bool, UnitIdSet) moduleTrustReqs m = withSession $ \hsc_env -> liftIO $ hscGetSafe hsc_env m noSrcSpan ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -56,12 +56,11 @@ import GHC.Types.SrcLoc import GHC.Types.CostCentre import GHC.Types.ForeignStubs import GHC.Types.Unique.Supply ( mkSplitUniqSupply ) +import GHC.Types.Unique.DSet import System.Directory import System.FilePath import System.IO -import Data.Set (Set) -import qualified Data.Set as Set {- ************************************************************************ @@ -84,7 +83,7 @@ codeOutput -> (a -> ForeignStubs) -> [(ForeignSrcLang, FilePath)] -- ^ additional files to be compiled with the C compiler - -> Set UnitId -- ^ Dependencies + -> UnitIdSet -- ^ Dependencies -> Stream IO RawCmmGroup a -- Compiled C-- -> IO (FilePath, (Bool{-stub_h_exists-}, Maybe FilePath{-stub_c_exists-}), @@ -161,11 +160,11 @@ outputC :: Logger -> DynFlags -> FilePath -> Stream IO RawCmmGroup a - -> Set UnitId + -> UnitIdSet -> IO a outputC logger dflags filenm cmm_stream unit_deps = withTiming logger (text "C codegen") (\a -> seq a () {- FIXME -}) $ do - let pkg_names = map unitIdString (Set.toAscList unit_deps) + let pkg_names = map unitIdString (uniqDSetToAscList unit_deps) doOutput filenm $ \ h -> do hPutStr h ("/* GHC_PACKAGES " ++ unwords pkg_names ++ "\n*/\n") hPutStr h "#include \"Stg.h\"\n" ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -127,7 +127,7 @@ hsc_HUE = ue_currentHomeUnitEnv . hsc_unit_env hsc_HUG :: HscEnv -> HomeUnitGraph hsc_HUG = ue_home_unit_graph . hsc_unit_env -hsc_all_home_unit_ids :: HscEnv -> Set.Set UnitId +hsc_all_home_unit_ids :: HscEnv -> UnitIdSet hsc_all_home_unit_ids = unitEnv_keys . hsc_HUG hscUpdateHPT_lazy :: (HomePackageTable -> HomePackageTable) -> HscEnv -> HscEnv ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -245,6 +245,7 @@ import GHC.Types.Name.Ppr import GHC.Types.Name.Set (NonCaffySet) import GHC.Types.TyThing import GHC.Types.HpcInfo +import GHC.Types.Unique.DSet import GHC.Utils.Fingerprint ( Fingerprint ) import GHC.Utils.Panic @@ -274,7 +275,6 @@ import Data.IORef import System.FilePath as FilePath import System.Directory import qualified Data.Set as S -import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) import Data.Bifunctor (first) @@ -1457,15 +1457,15 @@ checkSafeImports tcg_env clearDiagnostics -- Check safe imports are correct - safePkgs <- S.fromList <$> mapMaybeM checkSafe safeImps + safePkgs <- mkUniqDSet <$> mapMaybeM checkSafe safeImps safeErrs <- getDiagnostics clearDiagnostics -- Check non-safe imports are correct if inferring safety -- See the Note [Safe Haskell Inference] (infErrs, infPkgs) <- case (safeInferOn dflags) of - False -> return (emptyMessages, S.empty) - True -> do infPkgs <- S.fromList <$> mapMaybeM checkSafe regImps + False -> return (emptyMessages, emptyUniqDSet) + True -> do infPkgs <- mkUniqDSet <$> mapMaybeM checkSafe regImps infErrs <- getDiagnostics clearDiagnostics return (infErrs, infPkgs) @@ -1516,12 +1516,12 @@ checkSafeImports tcg_env checkSafe (m, l, _) = fst `fmap` hscCheckSafe' m l -- what pkg's to add to our trust requirements - pkgTrustReqs :: DynFlags -> Set UnitId -> Set UnitId -> + pkgTrustReqs :: DynFlags -> UnitIdSet -> UnitIdSet -> Bool -> ImportAvails pkgTrustReqs dflags req inf infPassed | safeInferOn dflags && not (safeHaskellModeEnabled dflags) && infPassed = emptyImportAvails { - imp_trust_pkgs = req `S.union` inf + imp_trust_pkgs = req `unionUniqDSets` inf } pkgTrustReqs dflags _ _ _ | safeHaskell dflags == Sf_Unsafe = emptyImportAvails @@ -1540,12 +1540,12 @@ hscCheckSafe hsc_env m l = runHsc hsc_env $ do return $ isEmptyMessages errs -- | Return if a module is trusted and the pkgs it depends on to be trusted. -hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, Set UnitId) +hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, UnitIdSet) hscGetSafe hsc_env m l = runHsc hsc_env $ do (self, pkgs) <- hscCheckSafe' m l good <- isEmptyMessages `fmap` getDiagnostics clearDiagnostics -- don't want them printed... - let pkgs' | Just p <- self = S.insert p pkgs + let pkgs' | Just p <- self = addOneToUniqDSet pkgs p | otherwise = pkgs return (good, pkgs') @@ -1554,7 +1554,7 @@ hscGetSafe hsc_env m l = runHsc hsc_env $ do -- own package be trusted and a list of other packages required to be trusted -- (these later ones haven't been checked) but the own package trust has been. hscCheckSafe' :: Module -> SrcSpan - -> Hsc (Maybe UnitId, Set UnitId) + -> Hsc (Maybe UnitId, UnitIdSet) hscCheckSafe' m l = do hsc_env <- getHscEnv let home_unit = hsc_home_unit hsc_env @@ -1566,7 +1566,7 @@ hscCheckSafe' m l = do -- Not necessary if that is reflected in dependencies | otherwise -> return (Just $ toUnitId (moduleUnit m), pkgs) where - isModSafe :: HomeUnit -> Module -> SrcSpan -> Hsc (Bool, Set UnitId) + isModSafe :: HomeUnit -> Module -> SrcSpan -> Hsc (Bool, UnitIdSet) isModSafe home_unit m l = do hsc_env <- getHscEnv dflags <- getDynFlags @@ -1648,10 +1648,10 @@ hscCheckSafe' m l = do -- | Check the list of packages are trusted. -checkPkgTrust :: Set UnitId -> Hsc () +checkPkgTrust :: UnitIdSet -> Hsc () checkPkgTrust pkgs = do hsc_env <- getHscEnv - let errors = S.foldr go emptyBag pkgs + let errors = foldr go emptyBag $ uniqDSetToAscList pkgs state = hsc_units hsc_env go pkg acc | unitIsTrusted $ unsafeLookupUnitId state pkg @@ -1699,7 +1699,7 @@ markUnsafeInfer tcg_env whyUnsafe = do False -> return tcg_env where - wiped_trust = (tcg_imports tcg_env) { imp_trust_pkgs = S.empty } + wiped_trust = (tcg_imports tcg_env) { imp_trust_pkgs = emptyUniqDSet } pprMod = ppr $ moduleName $ tcg_mod tcg_env whyUnsafe' df = vcat [ quotes pprMod <+> text "has been inferred as unsafe!" , text "Reason:" @@ -2060,7 +2060,7 @@ hscCompileCmmFile hsc_env original_filename filename output_filename = runHsc hs in NoStubs `appendStubC` ip_init | otherwise = NoStubs (_output_filename, (_stub_h_exists, stub_c_exists), _foreign_fps, _caf_infos) - <- codeOutput logger tmpfs llvm_config dflags (hsc_units hsc_env) cmm_mod output_filename no_loc foreign_stubs [] S.empty + <- codeOutput logger tmpfs llvm_config dflags (hsc_units hsc_env) cmm_mod output_filename no_loc foreign_stubs [] emptyUniqDSet rawCmms return stub_c_exists where ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -107,6 +107,7 @@ import GHC.Types.SourceFile import GHC.Types.SourceError import GHC.Types.SrcLoc import GHC.Types.Unique.Map +import GHC.Types.Unique.DSet import GHC.Types.PkgQual import GHC.Unit @@ -490,7 +491,7 @@ load how_much = loadWithCache noIfaceCache how_much mkBatchMsg :: HscEnv -> Messager mkBatchMsg hsc_env = - if length (hsc_all_home_unit_ids hsc_env) > 1 + if sizeUniqDSet (hsc_all_home_unit_ids hsc_env) > 1 -- This also displays what unit each module is from. then batchMultiMsg else batchMsg @@ -1735,25 +1736,25 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- This function checks then important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -checkHomeUnitsClosed :: UnitEnv -> Set.Set UnitId -> [(UnitId, UnitId)] -> [DriverMessages] +checkHomeUnitsClosed :: UnitEnv -> UnitIdSet -> [(UnitId, UnitId)] -> [DriverMessages] -- Fast path, trivially closed. checkHomeUnitsClosed ue home_id_set home_imp_ids - | Set.size home_id_set == 1 = [] + | sizeUniqDSet home_id_set == 1 = [] | otherwise = - let res = foldMap loop home_imp_ids + let res = foldl' (\acc ids -> unionUniqDSets acc $ loop ids) emptyUniqDSet home_imp_ids -- Now check whether everything which transitively depends on a home_unit is actually a home_unit -- These units are the ones which we need to load as home packages but failed to do for some reason, -- it's a bug in the tool invoking GHC. - bad_unit_ids = Set.difference res home_id_set - in if Set.null bad_unit_ids + bad_unit_ids = res `minusUniqDSet` home_id_set + in if isEmptyUniqDSet bad_unit_ids then [] - else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (Set.toList bad_unit_ids)] + else [singleMessage $ mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (uniqDSetToAscList bad_unit_ids)] where rootLoc = mkGeneralSrcSpan (fsLit "") -- TODO: This could repeat quite a bit of work but I struggled to write this function. -- Which units transitively depend on a home unit - loop :: (UnitId, UnitId) -> Set.Set UnitId -- The units which transitively depend on a home unit + loop :: (UnitId, UnitId) -> UnitIdSet -- The units which transitively depend on a home unit loop (from_uid, uid) = let us = ue_findHomeUnitEnv from_uid ue in let um = unitInfoMap (homeUnitEnv_units us) in @@ -1761,20 +1762,21 @@ checkHomeUnitsClosed ue home_id_set home_imp_ids Nothing -> pprPanic "uid not found" (ppr uid) Just ui -> let depends = unitDepends ui - home_depends = Set.fromList depends `Set.intersection` home_id_set - other_depends = Set.fromList depends `Set.difference` home_id_set + home_depends = mkUniqDSet depends `intersectUniqDSets` home_id_set + other_depends = mkUniqDSet depends `minusUniqDSet` home_id_set in -- Case 1: The unit directly depends on a home_id - if not (null home_depends) + if not (isEmptyUniqDSet home_depends) then - let res = foldMap (loop . (from_uid,)) other_depends - in Set.insert uid res + let res :: UnitIdSet + res = foldl' (\acc ide -> acc `unionUniqDSets` loop (from_uid, ide)) emptyUniqDSet $ uniqDSetToList other_depends + in addOneToUniqDSet res uid -- Case 2: Check the rest of the dependencies, and then see if any of them depended on else - let res = foldMap (loop . (from_uid,)) other_depends + let res = foldl' (\acc ide -> acc `unionUniqDSets` loop (from_uid, ide)) emptyUniqDSet $ uniqDSetToList other_depends in - if not (Set.null res) - then Set.insert uid res + if not (isEmptyUniqDSet res) + then addOneToUniqDSet res uid else res -- | Update the every ModSummary that is depended on ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -108,6 +108,7 @@ import GHC.Types.Target import GHC.Types.SrcLoc import GHC.Types.SourceFile import GHC.Types.SourceError +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -125,7 +126,6 @@ import Control.Monad import qualified Control.Monad.Catch as MC (handle) import Data.Maybe import Data.Either ( partitionEithers ) -import qualified Data.Set as Set import Data.Time ( getCurrentTime ) import GHC.Iface.Recomp @@ -408,8 +408,8 @@ link' logger tmpfs dflags unit_env batch_attempt_linking mHscMessager hpt home_mod_infos = eltsHpt hpt -- the packages we depend on - pkg_deps = Set.toList - $ Set.unions + pkg_deps = uniqDSetToAscList + $ unionManyUniqDSets $ fmap (dep_direct_pkgs . mi_deps . hm_iface) $ home_mod_infos ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Utils.Monad import GHC.Types.Name import GHC.Types.Name.Set ( NameSet, allUses ) import GHC.Types.Unique.Set +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Env @@ -40,7 +41,6 @@ import Data.IORef import Data.List (sortBy) import Data.Map (Map) import qualified Data.Map as Map -import qualified Data.Set as Set import GHC.Linker.Types import GHC.Unit.Finder @@ -196,7 +196,7 @@ mkObjectUsage pit plugins fc hug th_links_needed th_pkgs_needed = do mk_mod_usage_info :: UsageConfig -> HomeUnit - -> Set.Set UnitId + -> UnitIdSet -> Module -> ImportedMods -> NameSet @@ -255,7 +255,7 @@ mk_mod_usage_info uc home_unit home_unit_ids this_mod direct_imports used_names -- (need to recompile if its export list changes: export_fprint) mkUsage :: Module -> ModIface -> Maybe Usage mkUsage mod iface - | toUnitId (moduleUnit mod) `Set.notMember` home_unit_ids + | not $ toUnitId (moduleUnit mod) `elementOfUniqDSet` home_unit_ids = Just $ UsagePackageModule{ usg_mod = mod, usg_mod_hash = mod_hash, usg_safe = imp_safe } ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -504,7 +504,7 @@ loadInterface doc_str mod from -- overlapping instances. ; massertPpr ((isOneShot (ghcMode (hsc_dflags hsc_env))) - || moduleUnitId mod `notElem` hsc_all_home_unit_ids hsc_env + || not (moduleUnitId mod `elementOfUniqDSet` hsc_all_home_unit_ids hsc_env) || mod == gHC_PRIM) (text "Attempting to load home package interface into the EPS" $$ ppr hug $$ doc_str $$ ppr mod $$ ppr (moduleUnitId mod)) ; ignore_prags <- goptM Opt_IgnoreInterfacePragmas ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Types.SrcLoc import GHC.Types.Unique.Set import GHC.Types.Fixity.Env import GHC.Types.Unique.Map +import GHC.Types.Unique.DSet import GHC.Unit.External import GHC.Unit.Finder import GHC.Unit.State @@ -617,8 +618,8 @@ checkDependencies hsc_env summary iface all_home_units = hsc_all_home_unit_ids hsc_env units = hsc_units hsc_env prev_dep_mods = map (second gwib_mod) $ Set.toAscList $ dep_direct_mods (mi_deps iface) - prev_dep_pkgs = Set.toAscList (Set.union (dep_direct_pkgs (mi_deps iface)) - (dep_plugin_pkgs (mi_deps iface))) + prev_dep_pkgs = uniqDSetToAscList (unionUniqDSets (dep_direct_pkgs (mi_deps iface)) + (dep_plugin_pkgs (mi_deps iface))) implicit_deps = map (fsLit "Implicit",) (implicitPackageDeps dflags) @@ -633,7 +634,7 @@ checkDependencies hsc_env summary iface classify _ (Found _ mod) - | (toUnitId $ moduleUnit mod) `elem` all_home_units = Right (Left ((toUnitId $ moduleUnit mod), moduleName mod)) + | (toUnitId $ moduleUnit mod) `elementOfUniqDSet` all_home_units = Right (Left ((toUnitId $ moduleUnit mod), moduleName mod)) | otherwise = Right (Right (moduleNameFS (moduleName mod), toUnitId $ moduleUnit mod)) classify reason _ = Left (RecompBecause reason) ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -324,20 +324,20 @@ loadCmdLineLibs interp hsc_env = do loadCmdLineLibs' :: Interp -> HscEnv -> LoaderState -> IO LoaderState loadCmdLineLibs' interp hsc_env pls = snd <$> foldM - (\(done', pls') cur_uid -> load done' cur_uid pls') - (Set.empty, pls) - (hsc_all_home_unit_ids hsc_env) + (\(done', pls') cur_uid -> load done' cur_uid pls') + (emptyUniqDSet, pls) + (uniqDSetToList $ hsc_all_home_unit_ids hsc_env) where - load :: Set.Set UnitId -> UnitId -> LoaderState -> IO (Set.Set UnitId, LoaderState) - load done uid pls | uid `Set.member` done = return (done, pls) + load :: UnitIdSet -> UnitId -> LoaderState -> IO (UnitIdSet, LoaderState) + load done uid pls | uid `elementOfUniqDSet` done = return (done, pls) load done uid pls = do let hsc' = hscSetActiveUnitId uid hsc_env -- Load potential dependencies first (done', pls') <- foldM (\(done', pls') uid -> load done' uid pls') (done, pls) - (homeUnitDepends (hsc_units hsc')) + (homeUnitDepends (hsc_units hsc')) pls'' <- loadCmdLineLibs'' interp hsc' pls' - return $ (Set.insert uid done', pls'') + return $ (addOneToUniqDSet done' uid, pls'') loadCmdLineLibs'' :: Interp @@ -685,7 +685,7 @@ getLinkDeps :: HscEnv -> Maybe FilePath -- replace object suffixes? -> SrcSpan -- for error messages -> [Module] -- If you need these - -> IO ([Linkable], [Linkable], [UnitId], UniqDSet UnitId) -- ... then link these first + -> IO ([Linkable], [Linkable], [UnitId], UnitIdSet) -- ... then link these first -- The module and package dependencies for the needed modules are returned. -- See Note [Object File Dependencies] -- Fails with an IO exception if it can't find enough files @@ -737,7 +737,7 @@ getLinkDeps hsc_env pls replace_osuf span mods -- It is also a matter of correctness to use the module graph so that dependencies between home units -- is resolved correctly. - make_deps_loop :: (UniqDSet UnitId, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UniqDSet UnitId, Set.Set NodeKey) + make_deps_loop :: (UnitIdSet, Set.Set NodeKey) -> [ModNodeKeyWithUid] -> (UnitIdSet, Set.Set NodeKey) make_deps_loop found [] = found make_deps_loop found@(found_units, found_mods) (nk:nexts) | NodeKey_Module nk `Set.member` found_mods = make_deps_loop found nexts @@ -766,7 +766,7 @@ getLinkDeps hsc_env pls replace_osuf span mods HsBootFile -> link_boot_mod_error (mi_module iface) _ -> return $ Just (mi_module iface) - in (mkUniqDSet $ Set.toList $ dep_direct_pkgs (mi_deps iface),) <$> mmod + in (dep_direct_pkgs (mi_deps iface),) <$> mmod Nothing -> let err = text "getLinkDeps: Home module not loaded" <+> ppr (gwib_mod gwib) <+> ppr uid in throwGhcExceptionIO (ProgramError (showSDoc dflags err)) @@ -780,9 +780,9 @@ getLinkDeps hsc_env pls replace_osuf span mods -- dependencies of that. Hence we need to traverse the dependency -- tree recursively. See bug #936, testcase ghci/prog007. follow_deps :: [Module] -- modules to follow - -> UniqDSet Module -- accum. module dependencies - -> UniqDSet UnitId -- accum. package dependencies - -> IO ([Module], UniqDSet UnitId) -- result + -> UniqDSet Module -- accum. module dependencies + -> UnitIdSet -- accum. package dependencies + -> IO ([Module], UnitIdSet) -- result follow_deps [] acc_mods acc_pkgs = return (uniqDSetToList acc_mods, acc_pkgs) follow_deps (mod:mods) acc_mods acc_pkgs @@ -814,7 +814,7 @@ getLinkDeps hsc_env pls replace_osuf span mods acc_mods' = case hsc_home_unit_maybe hsc_env of Nothing -> acc_mods Just home_unit -> addListToUniqDSet acc_mods (mod : map (mkHomeModule home_unit) mod_deps) - acc_pkgs' = addListToUniqDSet acc_pkgs (Set.toList pkg_deps) + acc_pkgs' = addListToUniqDSet acc_pkgs (uniqDSetToList pkg_deps) case hsc_home_unit_maybe hsc_env of Just home_unit | isHomeUnit home_unit pkg -> follow_deps (mod_deps' ++ mods) ===================================== compiler/GHC/Linker/Types.hs ===================================== @@ -37,7 +37,7 @@ module GHC.Linker.Types where import GHC.Prelude -import GHC.Unit ( UnitId, Module ) +import GHC.Unit ( UnitId, Module, UnitIdSet ) import GHC.ByteCode.Types ( ItblEnv, AddrEnv, CompiledByteCode ) import GHC.Fingerprint.Type ( Fingerprint ) import GHCi.RemoteTypes ( ForeignHValue ) @@ -53,7 +53,6 @@ import Control.Concurrent.MVar import Data.Time ( UTCTime ) import Data.Maybe import GHC.Unit.Module.Env -import GHC.Types.Unique.DSet import GHC.Types.Unique.DFM import GHC.Unit.Module.WholeCoreBindings @@ -146,7 +145,7 @@ data LoadedPkgInfo { loaded_pkg_uid :: !UnitId , loaded_pkg_hs_objs :: ![LibrarySpec] , loaded_pkg_non_hs_objs :: ![LibrarySpec] - , loaded_pkg_trans_deps :: UniqDSet UnitId + , loaded_pkg_trans_deps :: UnitIdSet } instance Outputable LoadedPkgInfo where ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -75,6 +75,7 @@ import GHC.Types.HpcInfo import GHC.Types.Error import GHC.Types.PkgQual import GHC.Types.GREInfo (ConInfo(..)) +import GHC.Types.Unique.DSet import GHC.Unit import GHC.Unit.Module.Warnings @@ -213,8 +214,8 @@ rnImports imports = do let merged_import_avail = clobberSourceImports imp_avails dflags <- getDynFlags let final_import_avail = - merged_import_avail { imp_dep_direct_pkgs = S.fromList (implicitPackageDeps dflags) - `S.union` imp_dep_direct_pkgs merged_import_avail} + merged_import_avail { imp_dep_direct_pkgs = mkUniqDSet (implicitPackageDeps dflags) + `unionUniqDSets` imp_dep_direct_pkgs merged_import_avail} return (decls, rdr_env, final_import_avail, hpc_usage) where @@ -494,7 +495,7 @@ renamePkgQual unit_env mn mb_pkg = case mb_pkg of -- | Calculate the 'ImportAvails' induced by an import of a particular -- interface, but without 'imp_mods'. calculateAvails :: HomeUnit - -> S.Set UnitId + -> UnitIdSet -> ModIface -> IsSafeImport -> IsBootInterface @@ -549,7 +550,7 @@ calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by -- Trusted packages are a lot like orphans. trusted_pkgs | mod_safe' = dep_trusted_pkgs deps - | otherwise = S.empty + | otherwise = emptyUniqDSet pkg = moduleUnit (mi_module iface) @@ -562,11 +563,11 @@ calculateAvails home_unit other_home_units iface mod_safe' want_boot imported_by | isHomeUnit home_unit pkg = ptrust | otherwise = False - dependent_pkgs = if toUnitId pkg `S.member` other_home_units - then S.empty - else S.singleton ipkg + dependent_pkgs = if toUnitId pkg `elementOfUniqDSet` other_home_units + then emptyUniqDSet + else unitUniqDSet ipkg - direct_mods = mkModDeps $ if toUnitId pkg `S.member` other_home_units + direct_mods = mkModDeps $ if toUnitId pkg `elementOfUniqDSet` other_home_units then S.singleton (moduleUnitId imp_mod, (GWIB (moduleName imp_mod) want_boot)) else S.empty ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -148,6 +148,7 @@ import GHC.Types.Id.Info( IdDetails(..) ) import GHC.Types.Var.Env import GHC.Types.TypeEnv import GHC.Types.Unique.FM +import GHC.Types.Unique.DSet import GHC.Types.Name import GHC.Types.Name.Env import GHC.Types.Name.Set @@ -185,7 +186,6 @@ import Data.List ( sortBy, sort ) import Data.List.NonEmpty ( NonEmpty (..) ) import qualified Data.List.NonEmpty as NE import Data.Ord -import qualified Data.Set as S import Data.Traversable ( for ) @@ -3134,7 +3134,7 @@ pprTcGblEnv (TcGblEnv { tcg_type_env = type_env, , text "Dependent modules:" <+> (ppr . sort . installedModuleEnvElts $ imp_direct_dep_mods imports) , text "Dependent packages:" <+> - ppr (S.toList $ imp_dep_direct_pkgs imports)] + ppr (uniqDSetToAscList $ imp_dep_direct_pkgs imports)] -- The use of sort is just to reduce unnecessary -- wobbling in testsuite output ===================================== compiler/GHC/Tc/Types.hs ===================================== @@ -142,6 +142,7 @@ import GHC.Types.SourceFile import GHC.Types.SrcLoc import GHC.Types.Var.Set import GHC.Types.Unique.FM +import GHC.Types.Unique.DSet import GHC.Types.Basic import GHC.Types.CostCentre.State import GHC.Types.HpcInfo @@ -1367,9 +1368,9 @@ plusModDeps = plusInstalledModuleEnv plus_mod_dep emptyImportAvails :: ImportAvails emptyImportAvails = ImportAvails { imp_mods = emptyModuleEnv, imp_direct_dep_mods = emptyInstalledModuleEnv, - imp_dep_direct_pkgs = S.empty, + imp_dep_direct_pkgs = emptyUniqDSet, imp_sig_mods = [], - imp_trust_pkgs = S.empty, + imp_trust_pkgs = emptyUniqDSet, imp_trust_own_pkg = False, imp_boot_mods = emptyInstalledModuleEnv, imp_orphs = [], @@ -1398,8 +1399,8 @@ plusImportAvails imp_orphs = orphs2, imp_finsts = finsts2 }) = ImportAvails { imp_mods = plusModuleEnv_C (++) mods1 mods2, imp_direct_dep_mods = ddmods1 `plusModDeps` ddmods2, - imp_dep_direct_pkgs = ddpkgs1 `S.union` ddpkgs2, - imp_trust_pkgs = tpkgs1 `S.union` tpkgs2, + imp_dep_direct_pkgs = ddpkgs1 `unionUniqDSets` ddpkgs2, + imp_trust_pkgs = tpkgs1 `unionUniqDSets` tpkgs2, imp_trust_own_pkg = tself1 || tself2, imp_boot_mods = srs1 `plusModDeps` srcs2, imp_sig_mods = unionListsOrd sig_mods1 sig_mods2, ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -32,6 +32,7 @@ module GHC.Types.Unique.DSet ( isEmptyUniqDSet, lookupUniqDSet, uniqDSetToList, + uniqDSetToAscList, partitionUniqDSet, mapUniqDSet ) where @@ -43,8 +44,11 @@ import GHC.Types.Unique.DFM import GHC.Types.Unique.Set import GHC.Types.Unique +import GHC.Utils.Binary + import Data.Coerce import Data.Data +import Data.List (sort) -- See Note [UniqSet invariant] in GHC.Types.Unique.Set for why we want a newtype here. -- Beyond preserving invariants, we may also want to 'override' typeclass @@ -120,6 +124,9 @@ lookupUniqDSet = lookupUDFM . getUniqDSet uniqDSetToList :: UniqDSet a -> [a] uniqDSetToList = eltsUDFM . getUniqDSet +uniqDSetToAscList :: Ord a => UniqDSet a -> [a] +uniqDSetToAscList = sort . uniqDSetToList + partitionUniqDSet :: (a -> Bool) -> UniqDSet a -> (UniqDSet a, UniqDSet a) partitionUniqDSet p = coerce . partitionUDFM p . getUniqDSet @@ -140,3 +147,7 @@ instance Outputable a => Outputable (UniqDSet a) where pprUniqDSet :: (a -> SDoc) -> UniqDSet a -> SDoc pprUniqDSet f = braces . pprWithCommas f . uniqDSetToList + +instance (Uniquable a, Binary a) => Binary (UniqDSet a) where + put_ bh = put_ bh . uniqDSetToList + get bh = mkUniqDSet <$> get bh ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -81,6 +81,7 @@ import GHC.Utils.Misc (HasDebugCallStack) import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Utils.Panic (pprPanic) +import GHC.Types.Unique.DSet import GHC.Unit.Module.ModIface import GHC.Unit.Module import qualified Data.Set as Set @@ -339,8 +340,8 @@ unitEnv_lookup_maybe u env = Map.lookup u (unitEnv_graph env) unitEnv_lookup :: UnitEnvGraphKey -> UnitEnvGraph v -> v unitEnv_lookup u env = fromJust $ unitEnv_lookup_maybe u env -unitEnv_keys :: UnitEnvGraph v -> Set.Set UnitEnvGraphKey -unitEnv_keys env = Map.keysSet (unitEnv_graph env) +unitEnv_keys :: UnitEnvGraph v -> UnitIdSet +unitEnv_keys env = mkUniqDSet $ Map.keys (unitEnv_graph env) unitEnv_elts :: UnitEnvGraph v -> [(UnitEnvGraphKey, v)] unitEnv_elts env = Map.toList (unitEnv_graph env) @@ -443,7 +444,7 @@ ue_unitHomeUnit_maybe uid ue_env = ue_unitHomeUnit :: UnitId -> UnitEnv -> HomeUnit ue_unitHomeUnit uid ue_env = homeUnitEnv_unsafeHomeUnit $ ue_findHomeUnitEnv uid ue_env -ue_all_home_unit_ids :: UnitEnv -> Set.Set UnitId +ue_all_home_unit_ids :: UnitEnv -> UnitIdSet ue_all_home_unit_ids = unitEnv_keys . ue_home_unit_graph -- ------------------------------------------------------- -- Query and modify the currently active unit ===================================== compiler/GHC/Unit/Module/Deps.hs ===================================== @@ -28,6 +28,7 @@ import GHC.Unit.Module.Imported import GHC.Unit.Module import GHC.Unit.Home import GHC.Unit.State +import GHC.Types.Unique.DSet import GHC.Utils.Fingerprint import GHC.Utils.Binary @@ -53,13 +54,13 @@ data Dependencies = Deps -- ^ All home-package modules which are directly imported by this one. -- This may include modules from other units when using multiple home units - , dep_direct_pkgs :: Set UnitId + , dep_direct_pkgs :: UnitIdSet -- ^ All packages directly imported by this module -- I.e. packages to which this module's direct imports belong. -- Does not include other home units when using multiple home units. -- Modules from these units will go in `dep_direct_mods` - , dep_plugin_pkgs :: Set UnitId + , dep_plugin_pkgs :: UnitIdSet -- ^ All units needed for plugins ------------------------------------ @@ -69,7 +70,7 @@ data Dependencies = Deps -- ^ Transitive closure of hsig files in the home package - , dep_trusted_pkgs :: Set UnitId + , dep_trusted_pkgs :: UnitIdSet -- Packages which we are required to trust -- when the module is imported as a safe import -- (Safe Haskell). See Note [Tracking Trust Transitively] in GHC.Rename.Names @@ -110,7 +111,7 @@ data Dependencies = Deps mkDependencies :: HomeUnit -> Module -> ImportAvails -> [Module] -> Dependencies mkDependencies home_unit mod imports plugin_mods = let (home_plugins, external_plugins) = partition (isHomeUnit home_unit . moduleUnit) plugin_mods - plugin_units = Set.fromList (map (toUnitId . moduleUnit) external_plugins) + plugin_units = mkUniqDSet (map (toUnitId . moduleUnit) external_plugins) all_direct_mods = foldr (\mn m -> extendInstalledModuleEnv m mn (GWIB (moduleName mn) NotBoot)) (imp_direct_dep_mods imports) (map (fmap toUnitId) home_plugins) @@ -197,12 +198,12 @@ instance Binary Dependencies where noDependencies :: Dependencies noDependencies = Deps - { dep_direct_mods = Set.empty - , dep_direct_pkgs = Set.empty - , dep_plugin_pkgs = Set.empty + { dep_direct_mods = mempty + , dep_direct_pkgs = emptyUniqDSet + , dep_plugin_pkgs = emptyUniqDSet , dep_sig_mods = [] - , dep_boot_mods = Set.empty - , dep_trusted_pkgs = Set.empty + , dep_boot_mods = mempty + , dep_trusted_pkgs = emptyUniqDSet , dep_orphs = [] , dep_finsts = [] } @@ -220,11 +221,11 @@ pprDeps unit_state (Deps { dep_direct_mods = dmods = pprWithUnitState unit_state $ vcat [text "direct module dependencies:" <+> ppr_set ppr_mod dmods, text "boot module dependencies:" <+> ppr_set ppr bmods, - text "direct package dependencies:" <+> ppr_set ppr pkgs, - text "plugin package dependencies:" <+> ppr_set ppr plgns, - if null tps + text "direct package dependencies:" <+> ppr_unitIdSet ppr pkgs, + text "plugin package dependencies:" <+> ppr_unitIdSet ppr plgns, + if isEmptyUniqDSet tps then empty - else text "trusted package dependencies:" <+> ppr_set ppr tps, + else text "trusted package dependencies:" <+> ppr_unitIdSet ppr tps, text "orphans:" <+> fsep (map ppr orphs), text "family instance modules:" <+> fsep (map ppr finsts) ] @@ -235,6 +236,9 @@ pprDeps unit_state (Deps { dep_direct_mods = dmods ppr_set :: Outputable a => (a -> SDoc) -> Set a -> SDoc ppr_set w = fsep . fmap w . Set.toAscList + ppr_unitIdSet :: (UnitId -> SDoc) -> UnitIdSet -> SDoc + ppr_unitIdSet w = fsep . fmap w . sort . uniqDSetToList + -- | Records modules for which changes may force recompilation of this module -- See wiki: https://gitlab.haskell.org/ghc/ghc/wikis/commentary/compiler/recompilation-avoidance -- @@ -491,7 +495,7 @@ data ImportAvails imp_direct_dep_mods :: InstalledModuleEnv ModuleNameWithIsBoot, -- ^ Home-package modules directly imported by the module being compiled. - imp_dep_direct_pkgs :: Set UnitId, + imp_dep_direct_pkgs :: UnitIdSet, -- ^ Packages directly needed by the module being compiled imp_trust_own_pkg :: Bool, @@ -502,7 +506,7 @@ data ImportAvails -- Transitive information below here - imp_trust_pkgs :: Set UnitId, + imp_trust_pkgs :: UnitIdSet, -- ^ This records the -- packages the current module needs to trust for Safe Haskell -- compilation to succeed. A package is required to be trusted if ===================================== compiler/GHC/Unit/Module/ModGuts.hs ===================================== @@ -37,8 +37,6 @@ import GHC.Types.SourceFile ( HscSource(..), hscSourceToIsBoot ) import GHC.Types.SrcLoc import GHC.Types.CostCentre -import Data.Set (Set) - -- | A ModGuts is carried through the compiler, accumulating stuff as it goes -- There is only one ModGuts at any time, the one for the module @@ -137,7 +135,7 @@ data CgGuts cg_ccs :: [CostCentre], -- List of cost centres used in bindings and rules cg_foreign :: !ForeignStubs, -- ^ Foreign export stubs cg_foreign_files :: ![(ForeignSrcLang, FilePath)], - cg_dep_pkgs :: !(Set UnitId), -- ^ Dependent packages, used to + cg_dep_pkgs :: !UnitIdSet, -- ^ Dependent packages, used to -- generate #includes for C code gen cg_hpc_info :: !HpcInfo, -- ^ Program coverage tick box information cg_modBreaks :: !(Maybe ModBreaks), -- ^ Module breakpoints ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -346,10 +346,10 @@ data UnitConfig = UnitConfig , unitConfigFlagsIgnored :: [IgnorePackageFlag] -- ^ Ignored units , unitConfigFlagsTrusted :: [TrustFlag] -- ^ Trusted units , unitConfigFlagsPlugins :: [PackageFlag] -- ^ Plugins exposed units - , unitConfigHomeUnits :: Set.Set UnitId + , unitConfigHomeUnits :: UnitIdSet } -initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> UnitConfig +initUnitConfig :: DynFlags -> Maybe [UnitDatabase UnitId] -> UnitIdSet -> UnitConfig initUnitConfig dflags cached_dbs home_units = let !hu_id = homeUnitId_ dflags !hu_instanceof = homeUnitInstanceOf_ dflags @@ -626,7 +626,7 @@ listUnitInfo state = nonDetEltsUniqMap (unitInfoMap state) -- 'initUnits' can be called again subsequently after updating the -- 'packageFlags' field of the 'DynFlags', and it will update the -- 'unitState' in 'DynFlags'. -initUnits :: Logger -> DynFlags -> Maybe [UnitDatabase UnitId] -> Set.Set UnitId -> IO ([UnitDatabase UnitId], UnitState, HomeUnit, Maybe PlatformConstants) +initUnits :: Logger -> DynFlags -> Maybe [UnitDatabase UnitId] -> UnitIdSet -> IO ([UnitDatabase UnitId], UnitState, HomeUnit, Maybe PlatformConstants) initUnits logger dflags cached_dbs home_units = do let forceUnitInfoMap (state, _) = unitInfoMap state `seq` () @@ -1362,7 +1362,7 @@ mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..] merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do debugTraceMsg logger 2 $ text "loading package database" <+> text db_path - forM_ (Set.toList override_set) $ \pkg -> + forM_ (uniqDSetToList override_set) $ \pkg -> debugTraceMsg logger 2 $ text "package" <+> ppr pkg <+> text "overrides a previously defined package" @@ -1374,9 +1374,9 @@ mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..] -- The set of UnitIds which appear in both db and pkgs. These are the -- ones that get overridden. Compute this just to give some -- helpful debug messages at -v2 - override_set :: Set UnitId - override_set = Set.intersection (nonDetUniqMapToKeySet db_map) - (nonDetUniqMapToKeySet pkg_map) + override_set :: UnitIdSet + override_set = intersectUniqDSets (mkUniqDSet $ nonDetKeysUniqMap db_map) + (mkUniqDSet $ nonDetKeysUniqMap pkg_map) -- Now merge the sets together (NB: in case of duplicate, -- first argument preferred) @@ -1688,7 +1688,7 @@ mkUnitState logger cfg = do let !state = UnitState { preloadUnits = dep_preload , explicitUnits = explicit_pkgs - , homeUnitDepends = Set.toList home_unit_deps + , homeUnitDepends = uniqDSetToList home_unit_deps , unitInfoMap = pkg_db , preloadClosure = emptyUniqSet , moduleNameProvidersMap = mod_map @@ -1701,15 +1701,15 @@ mkUnitState logger cfg = do } return (state, raw_dbs) -selectHptFlag :: Set.Set UnitId -> PackageFlag -> Bool -selectHptFlag home_units (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `Set.member` home_units = True +selectHptFlag :: UnitIdSet -> PackageFlag -> Bool +selectHptFlag home_units (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `elementOfUniqDSet` home_units = True selectHptFlag _ _ = False -selectHomeUnits :: Set.Set UnitId -> [PackageFlag] -> Set.Set UnitId -selectHomeUnits home_units flags = foldl' go Set.empty flags +selectHomeUnits :: UnitIdSet -> [PackageFlag] -> UnitIdSet +selectHomeUnits home_units flags = foldl' go emptyUniqDSet flags where - go :: Set.Set UnitId -> PackageFlag -> Set.Set UnitId - go cur (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `Set.member` home_units = Set.insert (toUnitId uid) cur + go :: UnitIdSet -> PackageFlag -> UnitIdSet + go cur (ExposePackage _ (UnitIdArg uid) _) | toUnitId uid `elementOfUniqDSet` home_units = addOneToUniqDSet cur (toUnitId uid) -- MP: This does not yet support thinning/renaming go cur _ = cur ===================================== compiler/GHC/Unit/Types.hs ===================================== @@ -33,6 +33,7 @@ module GHC.Unit.Types , GenInstantiatedUnit (..) , InstantiatedUnit , DefUnitId + , UnitIdSet , Instantiations , GenInstantiations , mkInstantiatedUnit @@ -538,6 +539,8 @@ pprUnitId (UnitId fs) = sdocOption sdocUnitIdForUser ($ fs) -- code for. type DefUnitId = Definite UnitId +type UnitIdSet = UniqDSet UnitId + unitIdString :: UnitId -> String unitIdString = unpackFS . unitIdFS ===================================== ghc/GHCi/UI.hs ===================================== @@ -105,6 +105,7 @@ import GHC.Utils.Misc import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Bag (unitBag) import qualified GHC.Data.Strict as Strict +import GHC.Types.Unique.DSet -- Haskell Libraries import System.Console.Haskeline as Haskeline @@ -125,7 +126,6 @@ import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef ) import Data.List ( elemIndices, find, intercalate, intersperse, minimumBy, isPrefixOf, isSuffixOf, nub, partition, sort, sortBy, (\\) ) import qualified Data.List.NonEmpty as NE -import qualified Data.Set as S import Data.Maybe import qualified Data.Map as M import Data.IntMap.Strict (IntMap) @@ -561,7 +561,7 @@ interactiveUI config srcs maybe_exprs = do -- Set to True because Prelude is implicitly imported. impDecl at ImportDecl{ideclExt=ext} -> impDecl{ideclExt = ext{ideclImplicit=True}} hsc_env <- GHC.getSession - let in_multi = length (hsc_all_home_unit_ids hsc_env) > 1 + let in_multi = sizeUniqDSet (hsc_all_home_unit_ids hsc_env) > 1 empty_cache <- liftIO newIfaceCache startGHCi (runGHCi srcs maybe_exprs) GHCiState{ progname = default_progname, @@ -2568,15 +2568,15 @@ isSafeModule m = do -- print info to user... liftIO $ putStrLn $ "Trust type is (Module: " ++ trust ++ ", Package: " ++ pkg ++ ")" liftIO $ putStrLn $ "Package Trust: " ++ (if packageTrustOn dflags then "On" else "Off") - when (not $ S.null good) + when (not $ isEmptyUniqDSet good) (liftIO $ putStrLn $ "Trusted package dependencies (trusted): " ++ - (intercalate ", " $ map (showPpr dflags) (S.toList good))) - case msafe && S.null bad of + (intercalate ", " $ map (showPpr dflags) (uniqDSetToList good))) + case msafe && isEmptyUniqDSet bad of True -> liftIO $ putStrLn $ mname ++ " is trusted!" False -> do - when (not $ null bad) + when (not $ isEmptyUniqDSet bad) (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): " - ++ (intercalate ", " $ map (showPpr dflags) (S.toList bad))) + ++ (intercalate ", " $ map (showPpr dflags) (uniqDSetToList bad))) liftIO $ putStrLn $ mname ++ " is NOT trusted!" where @@ -2586,8 +2586,8 @@ isSafeModule m = do | isHomeModule (hsc_home_unit hsc_env) md = True | otherwise = unitIsTrusted $ unsafeLookupUnit (hsc_units hsc_env) (moduleUnit md) - tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (S.empty, S.empty) - | otherwise = S.partition part deps + tallyPkgs hsc_env deps | not (packageTrustOn dflags) = (emptyUniqDSet, emptyUniqDSet) + | otherwise = partitionUniqDSet part deps where part pkg = unitIsTrusted $ unsafeLookupUnitId unit_state pkg unit_state = hsc_units hsc_env dflags = hsc_dflags hsc_env View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a30871d8bab7c4bbd77bc32563eeb4e7bcdb22f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a30871d8bab7c4bbd77bc32563eeb4e7bcdb22f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 10:36:43 2023 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Thu, 27 Apr 2023 06:36:43 -0400 Subject: [Git][ghc/ghc][wip/usage-env] linear types: Don't add external names to the usage env Message-ID: <644a503b9b29a_178e74f24feb2c186451@gitlab.mail> Krzysztof Gogolewski pushed to branch wip/usage-env at Glasgow Haskell Compiler / GHC Commits: 04ed536d by Krzysztof Gogolewski at 2023-04-27T12:36:11+02:00 linear types: Don't add external names to the usage env This has no observable effect, but avoids storing useless data. - - - - - 3 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/UsageEnv.hs - compiler/GHC/Tc/Gen/Head.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -3210,7 +3210,7 @@ varCallSiteUsage :: Id -> LintM UsageEnv varCallSiteUsage id = do m <- getUEAliases return $ case lookupNameEnv m (getName id) of - Nothing -> unitUE id OneTy + Nothing -> singleUsageUE id Just id_ue -> id_ue ensureEqTys :: LintedType -> LintedType -> SDoc -> LintM () ===================================== compiler/GHC/Core/UsageEnv.hs ===================================== @@ -10,13 +10,14 @@ module GHC.Core.UsageEnv , scaleUsage , supUE , supUEs - , unitUE + , singleUsageUE , zeroUE ) where import Data.Foldable import GHC.Prelude import GHC.Core.Multiplicity +import GHC.Types.Var import GHC.Types.Name import GHC.Types.Name.Env import GHC.Utils.Outputable @@ -54,8 +55,13 @@ scaleUsage x (MUsage y) = MUsage $ mkMultMul x y -- For now, we use extra multiplicity Bottom for empty case. data UsageEnv = UsageEnv !(NameEnv Mult) Bool -unitUE :: NamedThing n => n -> Mult -> UsageEnv -unitUE x w = UsageEnv (unitNameEnv (getName x) w) False +-- | Record a single usage of an Id, i.e. {n: 1} +-- Exception: We do not record external names (both GlobalIds and top-level LocalIds) +-- because they're not relevant to linearity checking. +singleUsageUE :: Id -> UsageEnv +singleUsageUE x | isExternalName n = zeroUE + | otherwise = UsageEnv (unitNameEnv n OneTy) False + where n = getName x zeroUE, bottomUE :: UsageEnv zeroUE = UsageEnv emptyNameEnv False ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -48,7 +48,7 @@ import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep_syntactic ) import GHC.Tc.Utils.Instantiate import GHC.Tc.Instance.Family ( tcLookupDataFamInst ) import GHC.Core.FamInstEnv ( FamInstEnvs ) -import GHC.Core.UsageEnv ( unitUE ) +import GHC.Core.UsageEnv ( singleUsageUE ) import GHC.Tc.Errors.Types import GHC.Tc.Solver ( InferMode(..), simplifyInfer ) import GHC.Tc.Utils.Env @@ -1091,7 +1091,7 @@ tc_infer_id id_name check_local_id :: Id -> TcM () check_local_id id = do { checkThLocalId id - ; tcEmitBindingUsage $ unitUE (idName id) OneTy } + ; tcEmitBindingUsage $ singleUsageUE id } check_naughty :: OccName -> TcId -> TcM () check_naughty lbl id View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04ed536d9dd91a77725ca2ae4485f6146f7d9a8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04ed536d9dd91a77725ca2ae4485f6146f7d9a8c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 11:10:26 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 27 Apr 2023 07:10:26 -0400 Subject: [Git][ghc/ghc][wip/codebuffer-perftest] lint Message-ID: <644a5822f32d6_178e74f2dee0d418719b1@gitlab.mail> Josh Meredith pushed to branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC Commits: 3215c93d by Josh Meredith at 2023-04-27T11:10:15+00:00 lint - - - - - 1 changed file: - libraries/base/tests/perf/all.T Changes: ===================================== libraries/base/tests/perf/all.T ===================================== @@ -8,4 +8,4 @@ test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) # We don't expect the code in test to vary at all, but the variance is set to # 1% in case the constant allocations increase by other means. -test('encodingAllocations', collect_stats('bytes allocated', 1), compile_and_run, ['-O2']) +test('encodingAllocations', [js_broken(23311), collect_stats('bytes allocated', 1)], compile_and_run, ['-O2']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3215c93defb5a984304ef2257a524cd91553be45 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3215c93defb5a984304ef2257a524cd91553be45 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 11:29:44 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 27 Apr 2023 07:29:44 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 16 commits: DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <644a5ca8f1ead_178e74f35203e818819c0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - 57844c82 by Cheng Shao at 2023-04-27T07:29:38-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 65daf26a by Cheng Shao at 2023-04-27T07:29:38-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - 0de93afe by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 596fd1b8 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - 02a7277b by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 2238d5ac by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - 0e5d0756 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - d98043b1 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - 99fd0ab6 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - 87501fb6 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - 6791eee1 by Cheng Shao at 2023-04-27T07:29:38-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 53815ac2 by Ben Orchard at 2023-04-27T07:29:39-04:00 Add sized primitive literal syntax Adds a new LANGUAGE pragma ExtendedLiterals, which enables defining unboxed numeric literals such as `0xFF#Word8 :: Word8#`. Implements GHC proposal 0451: https://github.com/ghc-proposals/ghc-proposals/blob/b384a538b34f79d18a0201455b7b3c473bc8c936/proposals/0451-sized-literals.rst Fixes #21422. Bumps haddock submodule. Co-authored-by: Krzysztof Gogolewski <krzysztof.gogolewski at tweag.io> - - - - - f0c6323c by Josh Meredith at 2023-04-27T07:29:39-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 30 changed files: - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/HsToCore/Match/Literal.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94d8b606c1df3230e1ceb1590f546588a2b448f7...f0c6323c8cb5568673f02e70e5192e94a4612a49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94d8b606c1df3230e1ceb1590f546588a2b448f7...f0c6323c8cb5568673f02e70e5192e94a4612a49 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 11:47:19 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 27 Apr 2023 07:47:19 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23312 Message-ID: <644a60c7f34ff_178e74f3a42ee8191099a@gitlab.mail> Ben Gamari pushed new branch wip/T23312 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23312 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 12:27:55 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Thu, 27 Apr 2023 08:27:55 -0400 Subject: [Git][ghc/ghc][wip/codebuffer-perftest] Apply 1 suggestion(s) to 1 file(s) Message-ID: <644a6a4b2197b_178e74f48085781921190@gitlab.mail> Sylvain Henry pushed to branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC Commits: 9ec71b2a by Sylvain Henry at 2023-04-27T12:27:52+00:00 Apply 1 suggestion(s) to 1 file(s) - - - - - 1 changed file: - libraries/base/tests/perf/encodingAllocations.hs Changes: ===================================== libraries/base/tests/perf/encodingAllocations.hs ===================================== @@ -18,7 +18,7 @@ devnull = "/dev/null" #endif main :: IO () -main = withFile devnull WriteMode (loop 1000000) +main = withFile devnull AppendMode (loop 1000000) loop :: Int -> Handle -> IO () loop 0 !_ = pure () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ec71b2ad6545d033348e4e0a04e27bc8eaba72a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ec71b2ad6545d033348e4e0a04e27bc8eaba72a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 12:39:39 2023 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 27 Apr 2023 08:39:39 -0400 Subject: [Git][ghc/ghc][wip/T23312] nonmoving: Account for mutator allocations in bytes_allocated Message-ID: <644a6d0b585ca_178e74f4b6fd88192393c@gitlab.mail> Ben Gamari pushed to branch wip/T23312 at Glasgow Haskell Compiler / GHC Commits: 5bfbff20 by Ben Gamari at 2023-04-27T08:39:32-04:00 nonmoving: Account for mutator allocations in bytes_allocated Previously we failed to account direct mutator allocations into the nonmoving heap against the mutator's allocation limit and `cap->total_allocated`. This only manifests during CAF evaluation (since we allocate the CAF's blackhole directly into the nonmoving heap). Fixes #23312. - - - - - 3 changed files: - rts/sm/NonMovingAllocate.c - rts/sm/Storage.c - rts/sm/Storage.h Changes: ===================================== rts/sm/NonMovingAllocate.c ===================================== @@ -253,5 +253,9 @@ void *nonmovingAllocateGC(Capability *cap, StgWord sz) GNUC_ATTR_HOT void *nonmovingAllocate(Capability *cap, StgWord sz) { + // Handle "bytes allocated" accounting in the same way we + // do in Storage.c:allocate. See #23312. + accountAllocation(cap, sz); + cap->total_allocated += sz; return nonmovingAllocate_(SM_LOCK, cap, sz); } ===================================== rts/sm/Storage.c ===================================== @@ -966,7 +966,7 @@ move_STACK (StgStack *src, StgStack *dest) dest->sp = (StgPtr)dest->sp + diff; } -STATIC_INLINE void +void accountAllocation(Capability *cap, W_ n) { TICK_ALLOC_HEAP_NOCTR(WDS(n)); ===================================== rts/sm/Storage.h ===================================== @@ -125,6 +125,8 @@ StgWord genLiveBlocks (generation *gen); StgWord calcTotalLargeObjectsW (void); StgWord calcTotalCompactW (void); +void accountAllocation(Capability *cap, W_ n); + /* ---------------------------------------------------------------------------- Storage manager internal APIs and globals ------------------------------------------------------------------------- */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bfbff20d9c867a50299c3ffd2b07da510cce31a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bfbff20d9c867a50299c3ffd2b07da510cce31a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 14:00:29 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 27 Apr 2023 10:00:29 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: ci: update ci.sh to actually run the entire testsuite for wasm backend Message-ID: <644a7ffd8368c_178e74f60e6a04194229c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fddd7634 by Cheng Shao at 2023-04-27T10:00:24-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 9372bf5b by Cheng Shao at 2023-04-27T10:00:24-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - cc913553 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 42403668 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - 5cc829f7 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - f04f74d3 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - 6ad08413 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - 47634cae by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - fc5592eb by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - a101d186 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - 1a71e7f0 by Cheng Shao at 2023-04-27T10:00:24-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 94b8119a by Josh Meredith at 2023-04-27T10:00:25-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 30 changed files: - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Monad.hs - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/tests/IO/all.T - libraries/base/tests/IO/openFile008.hs - libraries/base/tests/System/all.T - libraries/base/tests/all.T - libraries/hpc - libraries/process - testsuite/config/ghc - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/driver/testutil.py - testsuite/mk/test.mk - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/ffi/should_run/all.T - testsuite/tests/ghc-api/target-contents/all.T - testsuite/tests/lib/base/all.T - testsuite/tests/perf/compiler/all.T - testsuite/tests/profiling/should_run/all.T - testsuite/tests/rename/should_fail/all.T - testsuite/tests/rts/all.T - testsuite/tests/rts/flags/all.T - testsuite/tests/rts/linker/all.T - testsuite/tests/safeHaskell/check/pkg01/all.T - testsuite/tests/tcplugins/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0c6323c8cb5568673f02e70e5192e94a4612a49...94b8119a9038dd9f6bd0da600f11ac037fe59abb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0c6323c8cb5568673f02e70e5192e94a4612a49...94b8119a9038dd9f6bd0da600f11ac037fe59abb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 14:36:01 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 27 Apr 2023 10:36:01 -0400 Subject: [Git][ghc/ghc][wip/T23083] 5 commits: Inlining literals into boring contexts is OK Message-ID: <644a88515af9d_178e74f6f58d6c1951695@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: a2050f56 by Sebastian Graf at 2023-04-27T16:13:05+02:00 Inlining literals into boring contexts is OK - - - - - 09940bde by Sebastian Graf at 2023-04-27T16:13:12+02:00 Kill SetLevel.notWorthFloating.is_triv (#23270) We have had it since b84ba676034, when it operated on annotated expressions. Nowadays it operates on vanilla `CoreExpr` though, so we should just call `exprIsTrivial`; thus handling empty cases and string literals correctly. - - - - - 85d1fb59 by Sebastian Graf at 2023-04-27T16:34:32+02:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Fixes #23270. - - - - - b3916756 by Sebastian Graf at 2023-04-27T16:35:50+02:00 CorePrep: Do not eliminate EmptyCase, do it in StgToCmm instead We eliminate EmptyCase by way of `cgCase e _ _ [] = cgExpr e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and the `Bool` field of `CorePrepProv`. - - - - - e6893f0a by Sebastian Graf at 2023-04-27T16:35:50+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/core-to-stg/T23270.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/084fb6480828ee322dd35c0d8559ea38d6a70f0d...e6893f0a1eb36d59cbd7a1c13434b8216083f35b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/084fb6480828ee322dd35c0d8559ea38d6a70f0d...e6893f0a1eb36d59cbd7a1c13434b8216083f35b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 16:03:13 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Thu, 27 Apr 2023 12:03:13 -0400 Subject: [Git][ghc/ghc][wip/codebuffer-perftest] 4 commits: DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) Message-ID: <644a9cc159bc0_178e74f85a63941976180@gitlab.mail> Josh Meredith pushed to branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC Commits: c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - 06ac7bda by Josh Meredith at 2023-04-27T16:02:52+00:00 base/encoding: add an allocations performance test (#22946) - - - - - 30 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs.hs - compiler/GHC/Parser.y - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Debug.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/Stg/InferTags.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Lift.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Stg/Lift/Monad.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/Stg/Stats.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Expr.hs - compiler/GHC/StgToJS/Sinker.hs - compiler/GHC/StgToJS/StgUtils.hs - compiler/GHC/Types/Demand.hs - libraries/base/tests/perf/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ec71b2ad6545d033348e4e0a04e27bc8eaba72a...06ac7bdaa27948fc08f6ea2df08ef50c23fb46c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ec71b2ad6545d033348e4e0a04e27bc8eaba72a...06ac7bdaa27948fc08f6ea2df08ef50c23fb46c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 16:15:34 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 27 Apr 2023 12:15:34 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Eliminate EmptyCase in CoreToStg instead Message-ID: <644a9fa6c5985_178e74f8be1a741978253@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 3175ef37 by Sebastian Graf at 2023-04-27T18:13:20+02:00 CorePrep: Eliminate EmptyCase in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - 11351a75 by Sebastian Graf at 2023-04-27T18:15:15+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -717,9 +717,12 @@ this exhaustive list can be empty! its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils -* An empty case is replaced by its scrutinee during the CoreToStg - conversion; remember STG is un-typed, so there is no need for - the empty case to do the type conversion. +* We lower empty cases in GHC.CoreToStg to an eval on the scrutinee. + +Historical Note: We used to lower EmptyCase in CorePrep by way of an +unsafeCoercion on the scrutinee, but that yielded panics in CodeGen when +we were beginning to eta expand in arguments, plus required to mess with +heterogenously-kinded coercions. It's simpler to stick to it just a bit longer. Note [Join points] ~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -1390,7 +1390,7 @@ setNominalRole_maybe r co | case prov of PhantomProv _ -> False -- should always be phantom ProofIrrelProv _ -> True -- it's always safe PluginProv _ -> False -- who knows? This choice is conservative. - CorePrepProv _ -> True + CorePrepProv -> True = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1516,7 +1516,7 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco UnivCo (PluginProv _) _ _ _ -> mkKindCo co - UnivCo (CorePrepProv _) _ _ _ -> mkKindCo co + UnivCo CorePrepProv _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2339,7 +2339,7 @@ seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co seqProv (PluginProv _) = () -seqProv (CorePrepProv _) = () +seqProv CorePrepProv = () seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -622,7 +622,7 @@ opt_univ env sym prov role oty1 oty2 #endif ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco PluginProv _ -> prov - CorePrepProv _ -> prov + CorePrepProv -> prov ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,7 @@ orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co orphNamesOfProv (PluginProv _) = emptyNameSet -orphNamesOfProv (CorePrepProv _) = emptyNameSet +orphNamesOfProv CorePrepProv = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo @@ -798,4 +798,3 @@ freeVars = go go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) - ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2301,9 +2301,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) -- see #9122 for discussion of these checks checkTypes t1 t2 - | allow_ill_kinded_univ_co prov - = return () -- Skip kind checks - | otherwise = do { checkWarnL fixed_rep_1 (report "left-hand type does not have a fixed runtime representation") ; checkWarnL fixed_rep_2 @@ -2321,13 +2318,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) reps1 = typePrimRep t1 reps2 = typePrimRep t2 - -- CorePrep deliberately makes ill-kinded casts - -- e.g (case error @Int "blah" of {}) :: Int# - -- ==> (error @Int "blah") |> Unsafe Int Int# - -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - allow_ill_kinded_univ_co (CorePrepProv homo_kind) = not homo_kind - allow_ill_kinded_univ_co _ = False - validateCoercion :: PrimRep -> PrimRep -> LintM () validateCoercion rep1 rep2 = do { platform <- getPlatform @@ -2357,8 +2347,8 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov - lint_prov _ _ prov@(CorePrepProv _) = return prov + lint_prov _ _ prov@(PluginProv _) = return prov + lint_prov _ _ prov at CorePrepProv = return prov check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -661,7 +661,7 @@ tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc -tyCoFVsOfProv (CorePrepProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc +tyCoFVsOfProv CorePrepProv fv_cand in_scope acc = emptyFV fv_cand in_scope acc tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -731,8 +731,8 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True -almost_devoid_co_var_of_prov (CorePrepProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _) _ = True +almost_devoid_co_var_of_prov CorePrepProv _ = True almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1131,7 +1131,7 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyUniqSet - go_prov (CorePrepProv _) = emptyUniqSet + go_prov CorePrepProv = emptyUniqSet -- this last case can happen from the tyConsOfType used from -- checkTauTvUpdate @@ -1345,5 +1345,4 @@ occCheckExpand vs_to_avoid ty go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p - + go_prov _ p at CorePrepProv = return p ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1437,9 +1437,9 @@ data UnivCoProvenance | PluginProv String -- ^ From a plugin, which asserts that this coercion -- is sound. The string is for the use of the plugin. - | CorePrepProv -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - Bool -- True <=> the UnivCo must be homogeneously kinded - -- False <=> allow hetero-kinded, e.g. Int ~ Int# + | CorePrepProv -- ^ See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep + -- The UnivCo is always homogeneously kinded, e.g., it + -- disallows Int ~ Int# deriving Data.Data @@ -1447,7 +1447,7 @@ instance Outputable UnivCoProvenance where ppr (PhantomProv _) = text "(phantom)" ppr (ProofIrrelProv _) = text "(proof irrel.)" ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) - ppr (CorePrepProv _) = text "(CorePrep)" + ppr CorePrepProv = text "(CorePrep)" -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1760,7 +1760,7 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co go_prov _ (PluginProv _) = mempty - go_prov _ (CorePrepProv _) = mempty + go_prov _ CorePrepProv = mempty -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1826,7 +1826,7 @@ provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co provSize (PluginProv _) = 1 -provSize (CorePrepProv _) = 1 +provSize CorePrepProv = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -912,7 +912,7 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -252,7 +252,7 @@ tidyCo env@(_, subst) co go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p + go_prov p at CorePrepProv = p tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -580,7 +580,7 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) go_prov _ p@(PluginProv _) = p - go_prov _ p@(CorePrepProv _) = p + go_prov _ p at CorePrepProv = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -998,7 +998,7 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov env (PhantomProv co) = PhantomProv <$> go_co env co go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p + go_prov _ p at CorePrepProv = return p {- ********************************************************************* ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -1073,8 +1073,18 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial] go (Cast e _) = go e go (Case e _ _ []) = go e -- See Note [Empty case is trivial] + go (Case e b _ as) = is_trivial_unsafe_coerce e b as go _ = k_not_triv + is_trivial_unsafe_coerce scrut bndr alts + | [Alt _ _ rhs] <- alts + , isUnsafeEqualityProof scrut + , isDeadBinder bndr -- We can only discard the case if the case-binder is dead + -- It usually is, but see #18227 + = go rhs + | otherwise + = k_not_triv + exprIsTrivial :: CoreExpr -> Bool exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -321,7 +321,7 @@ toIfaceCoercionX fr co go_prov (PhantomProv co) = IfacePhantomProv (go co) go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) go_prov (PluginProv str) = IfacePluginProv str - go_prov (CorePrepProv b) = IfaceCorePrepProv b + go_prov CorePrepProv = IfaceCorePrepProv toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -19,8 +19,7 @@ module GHC.CoreToStg ( CoreToStgOpts (..), coreToStg ) where import GHC.Prelude import GHC.Core -import GHC.Core.Utils ( exprType, findDefault, isJoinBind - , exprIsTickedString_maybe ) +import GHC.Core.Utils import GHC.Core.Opt.Arity ( manifestArity ) import GHC.Core.Type import GHC.Core.TyCon @@ -49,7 +48,7 @@ import GHC.Unit.Module import GHC.Data.FastString import GHC.Platform ( Platform ) import GHC.Platform.Ways -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps import GHC.Utils.Outputable import GHC.Utils.Monad @@ -574,6 +573,11 @@ coreToStgApp f args ticks = do -- This is the guy that turns applications into A-normal form -- --------------------------------------------------------------------------- +getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e + where + panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] = return ([], []) @@ -586,42 +590,29 @@ coreToStgArgs (Coercion _ : args) -- Coercion argument; See Note [Coercion token = do { (args', ts) <- coreToStgArgs args ; return (StgVarArg coercionTokenId : args', ts) } -coreToStgArgs (Tick t e : args) - = assert (not (tickishIsCode t)) $ - do { (args', ts) <- coreToStgArgs (e : args) - ; let !t' = coreToStgTick (exprType e) t - ; return (args', t':ts) } - coreToStgArgs (arg : args) = do -- Non-type argument (stg_args, ticks) <- coreToStgArgs args - arg' <- coreToStgExpr arg - let - (aticks, arg'') = stripStgTicksTop tickishFloatable arg' - stg_arg = case arg'' of - StgApp v [] -> StgVarArg v - StgConApp con _ [] _ -> StgVarArg (dataConWorkId con) - StgOpApp (StgPrimOp op) [] _ -> StgVarArg (primOpWrapperId op) - StgLit lit -> StgLitArg lit - _ -> pprPanic "coreToStgArgs" (ppr arg $$ pprStgExpr panicStgPprOpts arg' $$ pprStgExpr panicStgPprOpts arg'') - - -- WARNING: what if we have an argument like (v `cast` co) - -- where 'co' changes the representation type? - -- (This really only happens if co is unsafe.) - -- Then all the getArgAmode stuff in CgBindery will set the - -- cg_rep of the CgIdInfo based on the type of v, rather - -- than the type of 'co'. - -- This matters particularly when the function is a primop - -- or foreign call. - -- Wanted: a better solution than this hacky warning - + -- We know that `arg` must be trivial, but it may contain Ticks. + -- Example from test case `decodeMyStack`: + -- $ @... ((src Data.Tuple.snd) @Int @[..]) + -- Note that unfortunately the Tick is not at the top. + -- So we'll traverse the expression twice: + -- * Once with `stripTicksT` (which collects *all* ticks from the expression) + -- * and another time with `getStgArgFromTrivialArg`. + -- Since the argument is trivial, the only place the Tick can occur is + -- somehow wrapping a variable (give or take type args, as above). platform <- getPlatform - let - arg_rep = typePrimRep (exprType arg) - stg_arg_rep = typePrimRep (stgArgType stg_arg) + let arg_ty = exprType arg + ticks' = map (coreToStgTick arg_ty) (stripTicksT (not . tickishIsCode) arg) + arg' = getStgArgFromTrivialArg arg + arg_rep = typePrimRep arg_ty + stg_arg_rep = typePrimRep (stgArgType arg') bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep) - warnPprTrace bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) $ - return (stg_arg : stg_args, ticks ++ aticks) + massertPpr (length ticks' <= 1) (text "More than one Tick in trivial arg:" <+> ppr arg) + warnPprTraceM bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) + + return (arg' : stg_args, ticks' ++ ticks) coreToStgTick :: Type -- type of the ticked expression -> CoreTickish @@ -959,6 +950,9 @@ myCollectBinders expr -- | If the argument expression is (potential chain of) 'App', return the head -- of the app chain, and collect ticks/args along the chain. +-- INVARIANT: If the app head is trivial, return the atomic Var/Lit that was +-- wrapped in casts, empty case, ticks, etc. +-- So keep in sync with 'exprIsTrivial'. myCollectArgs :: HasDebugCallStack => CoreExpr -> (CoreExpr, [CoreArg], [CoreTickish]) myCollectArgs expr = go expr [] [] @@ -970,8 +964,10 @@ myCollectArgs expr -- See Note [Ticks in applications] go e as (t:ts) -- ticks can appear in type apps go (Cast e _) as ts = go e as ts + go (Case e _ _ []) as ts = assertPpr (null as) (ppr e $$ ppr as $$ ppr expr) $ + go e [] ts -- NB: Empty case discards arguments go (Lam b e) as ts - | isTyVar b = go e as ts -- Note [Collect args] + | isTyVar b = go e (drop 1 as) ts -- Note [Collect args] go e as ts = (e, as, ts) {- Note [Collect args] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -40,12 +40,10 @@ import GHC.Core.Coercion import GHC.Core.TyCon import GHC.Core.DataCon import GHC.Core.Opt.OccurAnal -import GHC.Core.TyCo.Rep( UnivCoProvenance(..) ) import GHC.Data.Maybe import GHC.Data.OrdList import GHC.Data.FastString -import GHC.Data.Pair import GHC.Data.Graph.UnVar import GHC.Utils.Error @@ -71,7 +69,6 @@ import GHC.Types.TyThing import GHC.Types.Unique.Supply import Data.List ( unfoldr ) -import Data.Functor.Identity import Control.Monad {- @@ -142,7 +139,7 @@ The goal of this pass is to prepare for code generation. profiling mode. We have to do this here because we won't have unfoldings after this pass (see `trimUnfolding` and Note [Drop unfoldings and rules]. -12. Eliminate case clutter in favour of unsafe coercions. +12. Eliminate unsafeEqualityProof in favour of unsafe coercions. See Note [Unsafe coercions] 13. Eliminate some magic Ids, specifically @@ -159,45 +156,17 @@ any trivial or useless bindings. Note [Unsafe coercions] ~~~~~~~~~~~~~~~~~~~~~~~ -CorePrep does these two transformations: - -1. Convert empty case to cast with an unsafe coercion - (case e of {}) ===> e |> unsafe-co - See Note [Empty case alternatives] in GHC.Core: if the case - alternatives are empty, the scrutinee must diverge or raise an - exception, so we can just dive into it. - - Of course, if the scrutinee *does* return, we may get a seg-fault. - A belt-and-braces approach would be to persist empty-alternative - cases to code generator, and put a return point anyway that calls a - runtime system error function. - - Notice that eliminating empty case can lead to an ill-kinded coercion - case error @Int "foo" of {} :: Int# - ===> error @Int "foo" |> unsafe-co - where unsafe-co :: Int ~ Int# - But that's fine because the expression diverges anyway. And it's - no different to what happened before. - -2. Eliminate unsafeEqualityProof in favour of an unsafe coercion - case unsafeEqualityProof of UnsafeRefl g -> e - ===> e[unsafe-co/g] - See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce - - Note that this requires us to substitute 'unsafe-co' for 'g', and - that is the main (current) reason for cpe_tyco_env in CorePrepEnv. - Tiresome, but not difficult. - -These transformations get rid of "case clutter", leaving only casts. -We are doing no further significant transformations, so the reasons -for the case forms have disappeared. And it is extremely helpful for -the ANF-ery, CoreToStg, and backends, if trivial expressions really do -look trivial. #19700 was an example. - -In both cases, the "unsafe-co" is just (UnivCo ty1 ty2 (CorePrepProv b)), -The boolean 'b' says whether the unsafe coercion is supposed to be -kind-homogeneous (yes for (2), no for (1). This information is used -/only/ by Lint. +CorePrep eliminates unsafeEqualityProof in favour of an unsafe coercion + case unsafeEqualityProof of UnsafeRefl g -> e + ===> e[unsafe-co/g] +See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce. + +The "unsafe-co" is just (UnivCo ty1 ty2 CorePrepProv), +a coercion that is always kind-homogeneous (as checked by Lint). + +Note that this requires us to substitute 'unsafe-co' for 'g', and +that is the main (current) reason for cpe_tyco_env in CorePrepEnv. +Tiresome, but not difficult. Note [CorePrep invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -785,10 +754,10 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) -- For example -- f (g x) ===> ([v = g x], f v) -cpeRhsE env (Type ty) - = return (emptyFloats, Type (cpSubstTy env ty)) -cpeRhsE env (Coercion co) - = return (emptyFloats, Coercion (cpSubstCo env co)) +cpeRhsE _ (Type ty) + = return (emptyFloats, Type ty) +cpeRhsE _ (Coercion co) + = return (emptyFloats, Coercion co) cpeRhsE env expr@(Lit (LitNumber nt i)) = case cp_convertNumLit (cpe_config env) nt i of Nothing -> return (emptyFloats, expr) @@ -822,7 +791,7 @@ cpeRhsE env (Tick tickish expr) cpeRhsE env (Cast expr co) = do { (floats, expr') <- cpeRhsE env expr - ; return (floats, Cast expr' (cpSubstCo env co)) } + ; return (floats, Cast expr' co) } cpeRhsE env expr@(Lam {}) = do { let (bndrs,body) = collectBinders expr @@ -830,36 +799,6 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } --- Eliminate empty case --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut _ ty []) - = do { (floats, scrut') <- cpeRhsE env scrut - ; let ty' = cpSubstTy env ty - scrut_ty' = exprType scrut' - co' = mkUnivCo prov Representational scrut_ty' ty' - prov = CorePrepProv False - -- False says that the kinds of two types may differ - -- E.g. we might cast Int to Int#. This is fine - -- because the scrutinee is guaranteed to diverge - - ; return (floats, Cast scrut' co') } - -- This can give rise to - -- Warning: Unsafe coercion: between unboxed and boxed value - -- but it's fine because 'scrut' diverges - --- Eliminate unsafeEqualityProof --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut bndr _ alts) - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder - -- is dead. It usually is, but see #18227 - , [Alt _ [co_var] rhs] <- alts - , let Pair ty1 ty2 = coVarTypes co_var - the_co = mkUnivCo prov Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) - prov = CorePrepProv True -- True <=> kind homogeneous - env' = extendCoVarEnv env co_var the_co - = cpeRhsE env' rhs - cpeRhsE env (Case scrut bndr ty alts) = do { (floats, scrut') <- cpeBody env scrut ; (env', bndr2) <- cpCloneBndr env bndr @@ -1205,14 +1144,10 @@ cpeApp top_env expr in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) - -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth - where - arg_ty' = cpSubstTy env arg_ty + -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make @@ -1224,9 +1159,7 @@ cpeApp top_env expr rebuild_app' env as (App fun' arg') (fs `appendFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co - -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -1497,11 +1430,32 @@ cpeArg env dmd arg ; if exprIsTrivial arg2 then return (floats2, arg2) else do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1619,6 +1573,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1982,6 +1974,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1992,6 +1989,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- @@ -2005,8 +2003,6 @@ data CorePrepEnv -- see Note [lazyId magic], Note [Inlining in CorePrep] -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) - , cpe_tyco_env :: Maybe CpeTyCoEnv -- See Note [CpeTyCoEnv] - , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } @@ -2014,7 +2010,6 @@ mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg , cpe_env = emptyVarEnv - , cpe_tyco_env = Nothing , cpe_rec_ids = emptyUnVarSet } @@ -2041,117 +2036,6 @@ enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv enterRecGroupRHSs env grp = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } ------------------------------------------------------------------------------- --- CpeTyCoEnv --- --------------------------------------------------------------------------- - -{- Note [CpeTyCoEnv] -~~~~~~~~~~~~~~~~~~~~ -The cpe_tyco_env :: Maybe CpeTyCoEnv field carries a substitution -for type and coercion variables - -* We need the coercion substitution to support the elimination of - unsafeEqualityProof (see Note [Unsafe coercions]) - -* We need the type substitution in case one of those unsafe - coercions occurs in the kind of tyvar binder (sigh) - -We don't need an in-scope set because we don't clone any of these -binders at all, so no new capture can take place. - -The cpe_tyco_env is almost always empty -- it only gets populated -when we get under an usafeEqualityProof. Hence the Maybe CpeTyCoEnv, -which makes everything into a no-op in the common case. --} - -data CpeTyCoEnv = TCE TvSubstEnv CvSubstEnv - -emptyTCE :: CpeTyCoEnv -emptyTCE = TCE emptyTvSubstEnv emptyCvSubstEnv - -extend_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -> CpeTyCoEnv -extend_tce_cv (TCE tv_env cv_env) cv co - = TCE tv_env (extendVarEnv cv_env cv co) - -extend_tce_tv :: CpeTyCoEnv -> TyVar -> Type -> CpeTyCoEnv -extend_tce_tv (TCE tv_env cv_env) tv ty - = TCE (extendVarEnv tv_env tv ty) cv_env - -lookup_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -lookup_tce_cv (TCE _ cv_env) cv - = case lookupVarEnv cv_env cv of - Just co -> co - Nothing -> mkCoVarCo cv - -lookup_tce_tv :: CpeTyCoEnv -> TyVar -> Type -lookup_tce_tv (TCE tv_env _) tv - = case lookupVarEnv tv_env tv of - Just ty -> ty - Nothing -> mkTyVarTy tv - -extendCoVarEnv :: CorePrepEnv -> CoVar -> Coercion -> CorePrepEnv -extendCoVarEnv cpe@(CPE { cpe_tyco_env = mb_tce }) cv co - = cpe { cpe_tyco_env = Just (extend_tce_cv tce cv co) } - where - tce = mb_tce `orElse` emptyTCE - - -cpSubstTy :: CorePrepEnv -> Type -> Type -cpSubstTy (CPE { cpe_tyco_env = mb_env }) ty - = case mb_env of - Just env -> runIdentity (subst_ty env ty) - Nothing -> ty - -cpSubstCo :: CorePrepEnv -> Coercion -> Coercion -cpSubstCo (CPE { cpe_tyco_env = mb_env }) co - = case mb_env of - Just tce -> runIdentity (subst_co tce co) - Nothing -> co - -subst_tyco_mapper :: TyCoMapper CpeTyCoEnv Identity -subst_tyco_mapper = TyCoMapper - { tcm_tyvar = \env tv -> return (lookup_tce_tv env tv) - , tcm_covar = \env cv -> return (lookup_tce_cv env cv) - , tcm_hole = \_ hole -> pprPanic "subst_co_mapper:hole" (ppr hole) - , tcm_tycobinder = \env tcv _vis -> if isTyVar tcv - then return (subst_tv_bndr env tcv) - else return (subst_cv_bndr env tcv) - , tcm_tycon = \tc -> return tc } - -subst_ty :: CpeTyCoEnv -> Type -> Identity Type -subst_co :: CpeTyCoEnv -> Coercion -> Identity Coercion -(subst_ty, _, subst_co, _) = mapTyCoX subst_tyco_mapper - -cpSubstTyVarBndr :: CorePrepEnv -> TyVar -> (CorePrepEnv, TyVar) -cpSubstTyVarBndr env@(CPE { cpe_tyco_env = mb_env }) tv - = case mb_env of - Nothing -> (env, tv) - Just tce -> (env { cpe_tyco_env = Just tce' }, tv') - where - (tce', tv') = subst_tv_bndr tce tv - -subst_tv_bndr :: CpeTyCoEnv -> TyVar -> (CpeTyCoEnv, TyVar) -subst_tv_bndr tce tv - = (extend_tce_tv tce tv (mkTyVarTy tv'), tv') - where - tv' = mkTyVar (tyVarName tv) kind' - kind' = runIdentity $ subst_ty tce $ tyVarKind tv - -cpSubstCoVarBndr :: CorePrepEnv -> CoVar -> (CorePrepEnv, CoVar) -cpSubstCoVarBndr env@(CPE { cpe_tyco_env = mb_env }) cv - = case mb_env of - Nothing -> (env, cv) - Just tce -> (env { cpe_tyco_env = Just tce' }, cv') - where - (tce', cv') = subst_cv_bndr tce cv - -subst_cv_bndr :: CpeTyCoEnv -> CoVar -> (CpeTyCoEnv, CoVar) -subst_cv_bndr tce cv - = (extend_tce_cv tce cv (mkCoVarCo cv'), cv') - where - cv' = mkCoVar (varName cv) ty' - ty' = runIdentity (subst_ty tce $ varType cv) - ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2161,13 +2045,6 @@ cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) cpCloneBndr env bndr - | isTyVar bndr - = return (cpSubstTyVarBndr env bndr) - - | isCoVar bndr - = return (cpSubstCoVarBndr env bndr) - - | otherwise = do { bndr' <- clone_it bndr -- Drop (now-useless) rules/unfoldings @@ -2186,8 +2063,7 @@ cpCloneBndr env bndr clone_it bndr | isLocalId bndr = do { uniq <- getUniqueM - ; let ty' = cpSubstTy env (idType bndr) - ; return (setVarUnique (setIdType bndr ty') uniq) } + ; return (setVarUnique bndr uniq) } | otherwise -- Top level things, which we don't want -- to clone, have become GlobalIds by now ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1748,7 +1748,7 @@ freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co freeNamesIfProv (IfacePluginProv _) = emptyNameSet -freeNamesIfProv (IfaceCorePrepProv _) = emptyNameSet +freeNamesIfProv IfaceCorePrepProv = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -402,7 +402,7 @@ data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String - | IfaceCorePrepProv Bool -- See defn of CorePrepProv + | IfaceCorePrepProv -- See defn of CorePrepProv {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,7 +624,7 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) go_prov co@(IfacePluginProv _) = co - go_prov co@(IfaceCorePrepProv _) = co + go_prov co at IfaceCorePrepProv = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1860,7 +1860,7 @@ pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) -pprIfaceUnivCoProv (IfaceCorePrepProv _) +pprIfaceUnivCoProv IfaceCorePrepProv = text "CorePrep" ------------------- @@ -2229,9 +2229,8 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a) = do putByte bh 3 put_ bh a - put_ bh (IfaceCorePrepProv a) = do + put_ bh IfaceCorePrepProv = do putByte bh 4 - put_ bh a get bh = do tag <- getByte bh @@ -2242,8 +2241,7 @@ instance Binary IfaceUnivCoProv where return $ IfaceProofIrrelProv a 3 -> do a <- get bh return $ IfacePluginProv a - 4 -> do a <- get bh - return (IfaceCorePrepProv a) + 4 -> do return IfaceCorePrepProv _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1520,7 +1520,7 @@ tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceCorePrepProv b) = return $ CorePrepProv b +tcIfaceUnivCoProv IfaceCorePrepProv = return CorePrepProv {- ************************************************************************ ===================================== compiler/GHC/Stg/CSE.hs ===================================== @@ -447,7 +447,7 @@ stgCseRhs env bndr (StgRhsClosure ext ccs upd args body) mkStgCase :: StgExpr -> OutId -> AltType -> [StgAlt] -> StgExpr -mkStgCase scrut bndr ty alts | all isBndr alts = scrut +mkStgCase scrut bndr ty alts | all isBndr alts = scrut -- NB: Always true for empty Case! | otherwise = StgCase scrut bndr ty alts where ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -650,6 +650,9 @@ elimCase _ args bndr alt_ty alts -------------------------------------------------------------------------------- unariseAlts :: UnariseEnv -> AltType -> InId -> [StgAlt] -> UniqSM [StgAlt] +unariseAlts _ _ _ [] + = return [] -- See Note [Empty case alternatives] + unariseAlts rho (MultiValAlt n) bndr [GenStgAlt{ alt_con = DEFAULT , alt_bndrs = [] , alt_rhs = e}] ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -53,7 +53,6 @@ import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import Control.Monad ( unless, void ) import Control.Arrow ( first ) @@ -1028,7 +1027,7 @@ cgIdApp fun_id args = do (text "TagCheck failed on entry in" <+> ppr mod <+> text "- value:" <> ppr fun_id <+> pdoc platform fun)) fun - EnterIt -> assert (null args) $ -- Discarding arguments + EnterIt -> assertPpr (null args) (ppr fun_id $$ ppr args) $ -- Discarding arguments emitEnter fun SlowCall -> do -- A slow function call via the RTS apply routines ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -156,7 +156,7 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyNameEnv - go_prov (CorePrepProv _) = emptyNameEnv + go_prov CorePrepProv = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1578,7 +1578,7 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co go_prov dv (PluginProv _) = return dv - go_prov dv (CorePrepProv _) = return dv + go_prov dv CorePrepProv = return dv go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== compiler/GHC/Utils/Trace.hs ===================================== @@ -8,6 +8,7 @@ module GHC.Utils.Trace , pprSTrace , pprTraceException , warnPprTrace + , warnPprTraceM , pprTraceUserWarning , trace ) @@ -84,6 +85,9 @@ warnPprTrace True s msg x (text s $$ msg $$ withFrozenCallStack traceCallStackDoc ) x +warnPprTraceM :: (Applicative f, HasCallStack) => Bool -> String -> SDoc -> f () +warnPprTraceM b s doc = withFrozenCallStack warnPprTrace b s doc (pure ()) + -- | For when we want to show the user a non-fatal WARNING so that they can -- report a GHC bug, but don't want to panic. pprTraceUserWarning :: HasCallStack => SDoc -> a -> a ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,10 @@ +module T23083 where + +-- Just ($), but NOINLINE so that we don't inline it eagerly, subverting the +-- test case +($$) :: (a -> b) -> a -> b +($$) f x = f x +{-# NOINLINE ($$) #-} + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $$)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,47 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 34, types: 34, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 6, types: 5, coercions: 0, joins: 0/0} +(T23083.$$) [InlPrag=NOINLINE] :: forall a b. (a -> b) -> a -> b +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +(T23083.$$) = \ (@a) (@b) (f [Occ=Once1!] :: a -> b) (x [Occ=Once1] :: a) -> f x + +-- RHS size: {terms: 12, types: 12, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6893f0a1eb36d59cbd7a1c13434b8216083f35b...11351a752c4e9c3f19658bac5679d46243f09465 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e6893f0a1eb36d59cbd7a1c13434b8216083f35b...11351a752c4e9c3f19658bac5679d46243f09465 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 18:51:54 2023 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Thu, 27 Apr 2023 14:51:54 -0400 Subject: [Git][ghc/ghc][wip/expand-do] do not add a fail block for type syn pattern in do block expansion. cf.... Message-ID: <644ac44a4abc3_178e74fb4ca454199984f@gitlab.mail> Apoorv Ingle pushed to branch wip/expand-do at Glasgow Haskell Compiler / GHC Commits: 5cfe6f98 by Apoorv Ingle at 2023-04-27T13:50:49-05:00 do not add a fail block for type syn pattern in do block expansion. cf. typecheck/should/run/Typeable1.hs to avoid spurious overlapping warnings - - - - - 7 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/Pmc/Utils.hs - compiler/GHC/Tc/Gen/Match.hs - testsuite/tests/pmcheck/should_compile/DoubleMatch.hs - testsuite/tests/rebindable/T18324b.hs - testsuite/tests/rebindable/pattern-fails.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -1107,9 +1107,9 @@ data HsExpansion orig expanded -- | Just print the original expression (the @a@) with the expanded version (the @b@) instance (Outputable a, Outputable b) => Outputable (HsExpansion a b) where ppr (HsExpanded orig expanded) - = ifPprDebug (vcat [ppr orig, braces (text "Expansion:" <+> ppr expanded)]) - (ppr orig) - -- = braces (ppr orig) $$ braces (text "Expansion:" <+> ppr expanded) + -- = ifPprDebug (vcat [ppr orig, braces (text "Expansion:" <+> ppr expanded)]) + -- (ppr orig) + = braces (ppr orig) $$ braces (text "Expansion:" <+> ppr expanded) {- ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Hs.Syn.Type import GHC.Tc.Types.Evidence import GHC.Tc.Utils.Monad import GHC.HsToCore.Pmc +import GHC.HsToCore.Pmc.Utils import GHC.HsToCore.Pmc.Types ( Nablas, initNablas ) import GHC.HsToCore.Monad import GHC.HsToCore.Binds @@ -783,9 +784,9 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches -- Pattern match check warnings for /this match-group/. -- @rhss_nablas@ is a flat list of covered Nablas for each RHS. -- Each Match will split off one Nablas for its RHSs from this. - -- ; tracePm "matchWrapper" (vcat [ppr ctxt - -- , text "matchPmChecked" - -- , ppr $ isMatchContextPmChecked dflags origin ctxt]) + ; tracePm "matchWrapper" (vcat [ ppr ctxt + , text "matches group" <+> ppr matches + , text "matchPmChecked" <+> ppr (isMatchContextPmChecked dflags origin ctxt)]) ; matches_nablas <- if isMatchContextPmChecked dflags origin ctxt then addHsScrutTmCs (concat scrs) new_vars $ -- See Note [Long-distance information] ===================================== compiler/GHC/HsToCore/Pmc/Utils.hs ===================================== @@ -108,9 +108,8 @@ arrowMatchContextExhaustiveWarningFlag = \ case -- 'HsMatchContext' (does not matter whether it is the redundancy check or the -- exhaustiveness check). isMatchContextPmChecked :: DynFlags -> Origin -> HsMatchContext id -> Bool -isMatchContextPmChecked _ origin LambdaExpr - | isGenerated origin - = True +isMatchContextPmChecked _ origin LambdaExpr -- It is likely that this is generated by expanding do stmts + = isGenerated origin isMatchContextPmChecked dflags origin kind | isGenerated origin = False ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Tc.Types.Evidence import GHC.Core.Multiplicity import GHC.Core.UsageEnv +import GHC.Core.ConLike import GHC.Core.TyCon -- Create chunkified tuple types for monad comprehensions import GHC.Core.Make @@ -327,7 +328,7 @@ tcDoStmts doExpr@(DoExpr _) (L l stmts) res_ty (unLoc expand_expr) -- Do expansion on the fly ; traceTc "tcDoStmts do" (vcat [ text "original:" <+> ppr expand_do_expr - , text "expnd:" <+> ppr expand_expr + , text "expanded:" <+> ppr expand_expr ]) ; tcExpr expand_do_expr res_ty } @@ -1375,10 +1376,13 @@ mk_failable_lexpr_tcm pat lexpr fail_op = do { ((tc_pat, _), _) <- tcInferPat (FRRBindStmt DoNotation) PatBindRhs pat $ return id -- whatever ; dflags <- getDynFlags - ; if isIrrefutableHsPat dflags tc_pat + ; if isIrrefutableHsPat dflags tc_pat -- don't decorate with fail statement if the pattern is irrefutable + || (isPatSynCon (unLoc tc_pat)) -- pattern syns always get a fail block while desugaring so skip then return $ mkHsLam [pat] lexpr else mk_fail_lexpr pat lexpr fail_op } + where isPatSynCon (ConPat {pat_con = L _ (PatSynCon _)}) = True + isPatSynCon _ = False -- makes the fail block -- TODO: check the discussion around MonadFail.fail type signature. ===================================== testsuite/tests/pmcheck/should_compile/DoubleMatch.hs ===================================== @@ -16,3 +16,27 @@ doingThing handler = do Handler1 -> 1 return action return v + +-- doingThing123 :: Handler -> IO Int +-- doingThing123 handler = (>>=) +-- (case handler of +-- Default -> return 0 +-- _other_handler -> do +-- asdf <- return 1 +-- let action = case handler of +-- Handler1 -> 1 +-- return action) +-- (\v -> return v) + + +-- doingThing123 :: Handler -> IO Int +-- doingThing123 handler = (>>=) +-- (case handler of +-- Default -> return 0 +-- _other_handler -> +-- (>>=)(return 1) (\asdf -> +-- let action = case handler of +-- Handler1 -> 1 +-- in +-- return action)) +-- (\v -> return v) ===================================== testsuite/tests/rebindable/T18324b.hs ===================================== @@ -1,15 +1,6 @@ {-# LANGUAGE GADTs, TypeFamilies, TypeFamilyDependencies #-} -{-# LANGUAGE AllowAmbiguousTypes #-} -- for unXRec, etc. -{-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE EmptyCase #-} -{-# LANGUAGE EmptyDataDeriving #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} @@ -23,11 +14,11 @@ unLoc (L _ e) = e data B = B +type family Anno a = b type family XRec p a = r | r -> a type instance XRec (GhcPass p) a = L (Anno a) a -type family Anno a = b data GhcPass (pass :: Pass) data Pass = Rn @@ -38,14 +29,9 @@ type family IdGhcP (pass :: Pass) where type GhcRn = GhcPass 'Rn -data LHsType pass data ClsInstDecl pass = - ClsInstDecl - { -- cid_tyfam_insts :: [LTyFamInstDecl pass] - -- , - cid_datafam_insts :: [LDataFamInstDecl pass] - } + ClsInstDecl { cid_datafam_insts :: LDataFamInstDecl pass } -- type LTyFamInstDecl pass = XRec pass (TyFamInstDecl pass) @@ -66,16 +52,9 @@ data FamEqn pass rhs fffggg :: ClsInstDecl GhcRn -> [Int] fffggg ddd = -- let - -- data_fams = do - [FamEqn { feqn_tycon = L l _ - , feqn_rhs = defn }] <- unLoc <$> cid_datafam_insts ddd + FamEqn { feqn_tycon = L _ _ + , feqn_rhs = _ } {-:: FamEqn GhcRn (HsDataDefn GhcRn)-} <- unLoc $ cid_datafam_insts ddd [ 0 ] - -- in - -- data_fams - -- ty_fams = do - -- TyFamInstDecl { tfid_eqn = FamEqn { feqn_tycon = L l _ } } <- unLoc <$> cid_tyfam_insts ddd - -- [ 0 ] - -- in data_fams ++ ty_fams ===================================== testsuite/tests/rebindable/pattern-fails.hs ===================================== @@ -10,9 +10,6 @@ qqq ts = do { (a:b:as) <- Just ts newtype ST a b = ST (a, b) -emptyST :: Maybe (ST Int Int) -emptyST = Just $ ST (0, 0) - ppp :: Maybe (ST Int Int) -> Maybe (ST Int Int) ppp st = do { ST (x, y) <- st ; return $ ST (x+1, y+1)} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5cfe6f983533ac824770121a47694e0c47a56727 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5cfe6f983533ac824770121a47694e0c47a56727 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 20:00:51 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 27 Apr 2023 16:00:51 -0400 Subject: [Git][ghc/ghc][master] 11 commits: ci: update ci.sh to actually run the entire testsuite for wasm backend Message-ID: <644ad47316996_178e74fc827e5c20082ae@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 30 changed files: - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/tests/IO/all.T - libraries/base/tests/IO/openFile008.hs - libraries/base/tests/System/all.T - libraries/base/tests/all.T - libraries/hpc - libraries/process - testsuite/config/ghc - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/driver/testutil.py - testsuite/mk/test.mk - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/concurrent/should_run/all.T - testsuite/tests/ffi/should_run/all.T - testsuite/tests/ghc-api/target-contents/all.T - testsuite/tests/lib/base/all.T - testsuite/tests/perf/compiler/all.T - testsuite/tests/profiling/should_run/all.T - testsuite/tests/rename/should_fail/all.T - testsuite/tests/rts/all.T - testsuite/tests/rts/flags/all.T - testsuite/tests/rts/linker/all.T - testsuite/tests/safeHaskell/check/pkg01/all.T - testsuite/tests/tcplugins/all.T - testsuite/tests/type-data/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/052e2bb629abc97b394b9de2394eb36cbed9385f...bd2bfdecc8040a9a70478cd8d646a34b5fa77c35 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/052e2bb629abc97b394b9de2394eb36cbed9385f...bd2bfdecc8040a9a70478cd8d646a34b5fa77c35 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 20:01:27 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 27 Apr 2023 16:01:27 -0400 Subject: [Git][ghc/ghc][master] JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) Message-ID: <644ad497a1bd8_178e74fc9d48a4201171c@gitlab.mail> Spam detection software, running on the system "mail.haskell.org", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) [...] Content analysis details: (5.6 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 1.1 URI_HEX URI: URI hostname has long hexadecimal sequence 5.0 UNWANTED_LANGUAGE_BODY BODY: Message written in an undesired language 0.0 HTML_MESSAGE BODY: HTML included in message -0.5 BAYES_05 BODY: Bayes spam probability is 1 to 5% [score: 0.0123] 0.0 T_DKIM_INVALID DKIM-Signature header exists but is not valid The original message was not completely plain text, and may be unsafe to open with some email clients; in particular, it may contain a virus, or confirm that your address can receive spam. If you wish to view it, it may be safer to save it to a file and open it with an editor. -------------- next part -------------- An embedded message was scrubbed... From: "Marge Bot (@marge-bot)" Subject: [Git][ghc/ghc][master] JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) Date: Thu, 27 Apr 2023 16:01:27 -0400 Size: 152822 URL: From gitlab at gitlab.haskell.org Thu Apr 27 20:50:14 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 27 Apr 2023 16:50:14 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead Message-ID: <644ae00691edd_178e74fdc2456820159bf@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 691b2c35 by Sebastian Graf at 2023-04-27T22:49:53+02:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - 04f15edf by Sebastian Graf at 2023-04-27T22:50:07+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - libraries/base/Unsafe/Coerce.hs - + testsuite/tests/simplCore/should_compile/T23083.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11351a752c4e9c3f19658bac5679d46243f09465...04f15edf0973c3a0c395a2152609ca7432fe2816 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11351a752c4e9c3f19658bac5679d46243f09465...04f15edf0973c3a0c395a2152609ca7432fe2816 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 21:08:10 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Thu, 27 Apr 2023 17:08:10 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead Message-ID: <644ae43a9f859_178e74fe0bb5b820168da@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 567b1240 by Sebastian Graf at 2023-04-27T23:08:05+02:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - 67b0a06f by Sebastian Graf at 2023-04-27T23:08:05+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/CSE.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - libraries/base/Unsafe/Coerce.hs - + testsuite/tests/simplCore/should_compile/T23083.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04f15edf0973c3a0c395a2152609ca7432fe2816...67b0a06fd9e43d7ce59f0d81484f3b9e583af0d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04f15edf0973c3a0c395a2152609ca7432fe2816...67b0a06fd9e43d7ce59f0d81484f3b9e583af0d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 23:29:30 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 27 Apr 2023 19:29:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23307 Message-ID: <644b055af6b0_178e7410063a9882024488@gitlab.mail> Simon Peyton Jones pushed new branch wip/T23307 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23307 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Apr 27 23:34:04 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 27 Apr 2023 19:34:04 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 27 commits: ci: update ci.sh to actually run the entire testsuite for wasm backend Message-ID: <644b066ce9358_178e741006edeac202642d@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 406378c5 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 First steps killing unifyWanted - - - - - 46a1407f by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Fix a boo boo - - - - - f6f2418e by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Fix another error: missing kick-out - - - - - d66cbdc4 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Maybe working now - - - - - 029d9caf by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Wibbles - - - - - 08d84459 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Stop loop - - - - - abfe5da8 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Wibbles - - - - - 40507864 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 More wibbles - - - - - 2368b137 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 undo accidental change to GHC.Bits - - - - - c11ba931 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Wibble error messages - - - - - b65bb9ed by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Experimental change: coercion holes Experiment with making a constraint non-canonical if it has a coercion hole on the RHS. Simplifies T22707 a lot! - - - - - 278c7fe4 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 More wibbles - - - - - 560df2ae by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Priorities non-rewritten equalities in the work list Plus update error output - - - - - cb660f21 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Further wibbles Fix to defaulting in rules - - - - - 096a1f74 by Simon Peyton Jones at 2023-04-28T00:35:42+01:00 Improved error messages - - - - - 30 changed files: - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/HsToCore.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/StgToJS/Monad.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Rewrite.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/tests/IO/all.T - libraries/base/tests/IO/openFile008.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c305e5c7e3d27e2325b5a71d6d8458cf697bff4d...096a1f74c2de10b1c8d0b0e74ea775db0afcae64 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c305e5c7e3d27e2325b5a71d6d8458cf697bff4d...096a1f74c2de10b1c8d0b0e74ea775db0afcae64 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 08:05:56 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 28 Apr 2023 04:05:56 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead Message-ID: <644b7e642aef9_178e74108c0d9d420640bf@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 0c2a57c1 by Sebastian Graf at 2023-04-28T10:05:22+02:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - 17b0d150 by Sebastian Graf at 2023-04-28T10:05:22+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - libraries/base/Unsafe/Coerce.hs - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -717,9 +717,12 @@ this exhaustive list can be empty! its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils -* An empty case is replaced by its scrutinee during the CoreToStg - conversion; remember STG is un-typed, so there is no need for - the empty case to do the type conversion. +* We lower empty cases in GHC.CoreToStg to an eval on the scrutinee. + +Historical Note: We used to lower EmptyCase in CorePrep by way of an +unsafeCoercion on the scrutinee, but that yielded panics in CodeGen when +we were beginning to eta expand in arguments, plus required to mess with +heterogenously-kinded coercions. It's simpler to stick to it just a bit longer. Note [Join points] ~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -1390,7 +1390,6 @@ setNominalRole_maybe r co | case prov of PhantomProv _ -> False -- should always be phantom ProofIrrelProv _ -> True -- it's always safe PluginProv _ -> False -- who knows? This choice is conservative. - CorePrepProv _ -> True = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1516,7 +1515,6 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco UnivCo (PluginProv _) _ _ _ -> mkKindCo co - UnivCo (CorePrepProv _) _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2339,7 +2337,6 @@ seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co seqProv (PluginProv _) = () -seqProv (CorePrepProv _) = () seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -622,7 +622,6 @@ opt_univ env sym prov role oty1 oty2 #endif ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco PluginProv _ -> prov - CorePrepProv _ -> prov ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,6 @@ orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co orphNamesOfProv (PluginProv _) = emptyNameSet -orphNamesOfProv (CorePrepProv _) = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo @@ -798,4 +797,3 @@ freeVars = go go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) - ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2301,9 +2301,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) -- see #9122 for discussion of these checks checkTypes t1 t2 - | allow_ill_kinded_univ_co prov - = return () -- Skip kind checks - | otherwise = do { checkWarnL fixed_rep_1 (report "left-hand type does not have a fixed runtime representation") ; checkWarnL fixed_rep_2 @@ -2321,13 +2318,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) reps1 = typePrimRep t1 reps2 = typePrimRep t2 - -- CorePrep deliberately makes ill-kinded casts - -- e.g (case error @Int "blah" of {}) :: Int# - -- ==> (error @Int "blah") |> Unsafe Int Int# - -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - allow_ill_kinded_univ_co (CorePrepProv homo_kind) = not homo_kind - allow_ill_kinded_univ_co _ = False - validateCoercion :: PrimRep -> PrimRep -> LintM () validateCoercion rep1 rep2 = do { platform <- getPlatform @@ -2357,8 +2347,7 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov - lint_prov _ _ prov@(CorePrepProv _) = return prov + lint_prov _ _ prov@(PluginProv _) = return prov check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -661,7 +661,6 @@ tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc -tyCoFVsOfProv (CorePrepProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -731,8 +730,7 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True -almost_devoid_co_var_of_prov (CorePrepProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _) _ = True almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1131,9 +1129,6 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyUniqSet - go_prov (CorePrepProv _) = emptyUniqSet - -- this last case can happen from the tyConsOfType used from - -- checkTauTvUpdate go_cos cos = foldr (unionUniqSets . go_co) emptyUniqSet cos @@ -1345,5 +1340,3 @@ occCheckExpand vs_to_avoid ty go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p - ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1437,17 +1437,12 @@ data UnivCoProvenance | PluginProv String -- ^ From a plugin, which asserts that this coercion -- is sound. The string is for the use of the plugin. - | CorePrepProv -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - Bool -- True <=> the UnivCo must be homogeneously kinded - -- False <=> allow hetero-kinded, e.g. Int ~ Int# - deriving Data.Data instance Outputable UnivCoProvenance where ppr (PhantomProv _) = text "(phantom)" ppr (ProofIrrelProv _) = text "(proof irrel.)" ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) - ppr (CorePrepProv _) = text "(CorePrep)" -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1760,7 +1755,6 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co go_prov _ (PluginProv _) = mempty - go_prov _ (CorePrepProv _) = mempty -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1826,7 +1820,6 @@ provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co provSize (PluginProv _) = 1 -provSize (CorePrepProv _) = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -912,7 +912,6 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -252,7 +252,6 @@ tidyCo env@(_, subst) co go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -580,7 +580,6 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) go_prov _ p@(PluginProv _) = p - go_prov _ p@(CorePrepProv _) = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -998,7 +997,6 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov env (PhantomProv co) = PhantomProv <$> go_co env co go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p {- ********************************************************************* ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -249,8 +249,11 @@ inlineBoringOk e , exprIsTrivial a = go (credit-1) f go credit (Tick _ e) = go credit e -- dubious go credit (Cast e _) = go credit e - go credit (Case scrut _ _ [Alt _ _ rhs]) -- See Note [Inline unsafeCoerce] - | isUnsafeEqualityProof scrut = go credit rhs + go credit (Case e b _ alts) + | null alts + = go credit e -- EmptyCase is like e + | Just rhs <- isUnsafeEqualityCase e b alts + = go credit rhs -- See Note [Inline unsafeCoerce] go _ (Var {}) = boringCxtOk go _ (Lit l) = litIsTrivial l && boringCxtOk go _ _ = boringCxtNotOk @@ -304,7 +307,7 @@ calcUnfoldingGuidance opts is_top_bottoming expr We really want to inline unsafeCoerce, even when applied to boring arguments. It doesn't look as if its RHS is smaller than the call unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x -but that case is discarded -- see Note [Implementing unsafeCoerce] +but that case is discarded in CoreToStg -- see Note [Implementing unsafeCoerce] in base:Unsafe.Coerce. Moreover, if we /don't/ inline it, we may be left with @@ -312,7 +315,9 @@ Moreover, if we /don't/ inline it, we may be left with which will build a thunk -- bad, bad, bad. Conclusion: we really want inlineBoringOk to be True of the RHS of -unsafeCoerce. This is (U4) in Note [Implementing unsafeCoerce]. +unsafeCoerce. And it really is, because we regard + case unsafeEqualityProof @a @b of UnsafeRefl -> rhs +as trivial iff rhs is. This is (U4) in Note [Implementing unsafeCoerce]. Note [Computing the size of an expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -59,7 +59,7 @@ module GHC.Core.Utils ( mkStrictFieldSeqs, shouldStrictifyIdForCbv, shouldUseCbvForId, -- * unsafeEqualityProof - isUnsafeEqualityProof, + isUnsafeEqualityCase, -- * Dumping stuff dumpIdInfoOfProgram @@ -79,7 +79,7 @@ import GHC.Core.Reduction import GHC.Core.TyCon import GHC.Core.Multiplicity -import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofIdKey ) +import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofIdKey, unsafeReflDataConKey ) import GHC.Builtin.PrimOps import GHC.Types.Var @@ -1072,7 +1072,11 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go go (Lam b e) | not (isRuntimeVar b) = go e go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial] go (Cast e _) = go e - go (Case e _ _ []) = go e -- See Note [Empty case is trivial] + go (Case e b _ as) + | null as + = go e -- See Note [Empty case is trivial] + | Just rhs <- isUnsafeEqualityCase e b as + = go rhs -- See (U2) of Note [Implementing unsafeCoerce] in base:Unsafe.Coerce go _ = k_not_triv exprIsTrivial :: CoreExpr -> Bool @@ -2707,11 +2711,19 @@ wantCbvForId cbv_for_strict v * * ********************************************************************* -} -isUnsafeEqualityProof :: CoreExpr -> Bool +isUnsafeEqualityCase :: CoreExpr -> Id -> [CoreAlt] -> Maybe CoreExpr -- See (U3) and (U4) in -- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce -isUnsafeEqualityProof e - | Var v `App` Type _ `App` Type _ `App` Type _ <- e - = v `hasKey` unsafeEqualityProofIdKey - | otherwise - = False +isUnsafeEqualityCase scrut bndr [Alt ac _ rhs] + | DataAlt dc <- ac + , not (dc `hasKey` unsafeReflDataConKey) + = Nothing -- fast path for DataAlt + + | isDeadBinder bndr -- We can only discard the case if the case-binder is dead + -- It usually is, but see #18227 + , Var v `App` Type _ `App` Type _ `App` Type _ <- scrut + , v `hasKey` unsafeEqualityProofIdKey + = Just rhs + +isUnsafeEqualityCase _ _ _ + = Nothing ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -321,7 +321,6 @@ toIfaceCoercionX fr co go_prov (PhantomProv co) = IfacePhantomProv (go co) go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) go_prov (PluginProv str) = IfacePluginProv str - go_prov (CorePrepProv b) = IfaceCorePrepProv b toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -19,8 +19,7 @@ module GHC.CoreToStg ( CoreToStgOpts (..), coreToStg ) where import GHC.Prelude import GHC.Core -import GHC.Core.Utils ( exprType, findDefault, isJoinBind - , exprIsTickedString_maybe ) +import GHC.Core.Utils import GHC.Core.Opt.Arity ( manifestArity ) import GHC.Core.Type import GHC.Core.TyCon @@ -49,7 +48,7 @@ import GHC.Unit.Module import GHC.Data.FastString import GHC.Platform ( Platform ) import GHC.Platform.Ways -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps import GHC.Utils.Outputable import GHC.Utils.Monad @@ -431,7 +430,6 @@ coreToStgExpr (Cast expr _) -- Cases require a little more real work. -{- coreToStgExpr (Case scrut _ _ []) = coreToStgExpr scrut -- See Note [Empty case alternatives] in GHC.Core If the case @@ -443,17 +441,12 @@ coreToStgExpr (Case scrut _ _ []) -- code generator, and put a return point anyway that calls a -- runtime system error function. -coreToStgExpr e0@(Case scrut bndr _ [alt]) = do - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder is dead - -- It usually is, but see #18227 - , (_,_,rhs) <- alt - = coreToStgExpr rhs - -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce --} - -- The normal case for case-expressions coreToStgExpr (Case scrut bndr _ alts) + | Just rhs <- isUnsafeEqualityCase scrut bndr alts + = coreToStgExpr rhs + -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce + | otherwise = do { scrut2 <- coreToStgExpr scrut ; alts2 <- extendVarEnvCts [(bndr, LambdaBound)] (mapM vars_alt alts) ; return (StgCase scrut2 bndr (mkStgAltType bndr alts) alts2) } @@ -574,6 +567,11 @@ coreToStgApp f args ticks = do -- This is the guy that turns applications into A-normal form -- --------------------------------------------------------------------------- +getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e + where + panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] = return ([], []) @@ -586,42 +584,29 @@ coreToStgArgs (Coercion _ : args) -- Coercion argument; See Note [Coercion token = do { (args', ts) <- coreToStgArgs args ; return (StgVarArg coercionTokenId : args', ts) } -coreToStgArgs (Tick t e : args) - = assert (not (tickishIsCode t)) $ - do { (args', ts) <- coreToStgArgs (e : args) - ; let !t' = coreToStgTick (exprType e) t - ; return (args', t':ts) } - coreToStgArgs (arg : args) = do -- Non-type argument (stg_args, ticks) <- coreToStgArgs args - arg' <- coreToStgExpr arg - let - (aticks, arg'') = stripStgTicksTop tickishFloatable arg' - stg_arg = case arg'' of - StgApp v [] -> StgVarArg v - StgConApp con _ [] _ -> StgVarArg (dataConWorkId con) - StgOpApp (StgPrimOp op) [] _ -> StgVarArg (primOpWrapperId op) - StgLit lit -> StgLitArg lit - _ -> pprPanic "coreToStgArgs" (ppr arg $$ pprStgExpr panicStgPprOpts arg' $$ pprStgExpr panicStgPprOpts arg'') - - -- WARNING: what if we have an argument like (v `cast` co) - -- where 'co' changes the representation type? - -- (This really only happens if co is unsafe.) - -- Then all the getArgAmode stuff in CgBindery will set the - -- cg_rep of the CgIdInfo based on the type of v, rather - -- than the type of 'co'. - -- This matters particularly when the function is a primop - -- or foreign call. - -- Wanted: a better solution than this hacky warning - + -- We know that `arg` must be trivial, but it may contain Ticks. + -- Example from test case `decodeMyStack`: + -- $ @... ((src Data.Tuple.snd) @Int @[..]) + -- Note that unfortunately the Tick is not at the top. + -- So we'll traverse the expression twice: + -- * Once with `stripTicksT` (which collects *all* ticks from the expression) + -- * and another time with `getStgArgFromTrivialArg`. + -- Since the argument is trivial, the only place the Tick can occur is + -- somehow wrapping a variable (give or take type args, as above). platform <- getPlatform - let - arg_rep = typePrimRep (exprType arg) - stg_arg_rep = typePrimRep (stgArgType stg_arg) + let arg_ty = exprType arg + ticks' = map (coreToStgTick arg_ty) (stripTicksT (not . tickishIsCode) arg) + arg' = getStgArgFromTrivialArg arg + arg_rep = typePrimRep arg_ty + stg_arg_rep = typePrimRep (stgArgType arg') bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep) - warnPprTrace bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) $ - return (stg_arg : stg_args, ticks ++ aticks) + massertPpr (length ticks' <= 1) (text "More than one Tick in trivial arg:" <+> ppr arg) + warnPprTraceM bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) + + return (arg' : stg_args, ticks' ++ ticks) coreToStgTick :: Type -- type of the ticked expression -> CoreTickish @@ -959,6 +944,9 @@ myCollectBinders expr -- | If the argument expression is (potential chain of) 'App', return the head -- of the app chain, and collect ticks/args along the chain. +-- INVARIANT: If the app head is trivial, return the atomic Var/Lit that was +-- wrapped in casts, empty case, ticks, etc. +-- So keep in sync with 'exprIsTrivial'. myCollectArgs :: HasDebugCallStack => CoreExpr -> (CoreExpr, [CoreArg], [CoreTickish]) myCollectArgs expr = go expr [] [] @@ -970,8 +958,14 @@ myCollectArgs expr -- See Note [Ticks in applications] go e as (t:ts) -- ticks can appear in type apps go (Cast e _) as ts = go e as ts + go (Case e b _ alts) as ts + | null alts + = assertPpr (null as) (ppr e $$ ppr as $$ ppr expr) $ + go e [] ts -- NB: Empty case discards arguments + | Just rhs <- isUnsafeEqualityCase e b alts + = go rhs as ts -- Discards unsafeCoerce in App heads go (Lam b e) as ts - | isTyVar b = go e as ts -- Note [Collect args] + | isTyVar b = go e (drop 1 as) ts -- Note [Collect args] go e as ts = (e, as, ts) {- Note [Collect args] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -40,12 +40,10 @@ import GHC.Core.Coercion import GHC.Core.TyCon import GHC.Core.DataCon import GHC.Core.Opt.OccurAnal -import GHC.Core.TyCo.Rep( UnivCoProvenance(..) ) import GHC.Data.Maybe import GHC.Data.OrdList import GHC.Data.FastString -import GHC.Data.Pair import GHC.Data.Graph.UnVar import GHC.Utils.Error @@ -71,7 +69,6 @@ import GHC.Types.TyThing import GHC.Types.Unique.Supply import Data.List ( unfoldr ) -import Data.Functor.Identity import Control.Monad {- @@ -142,10 +139,7 @@ The goal of this pass is to prepare for code generation. profiling mode. We have to do this here because we won't have unfoldings after this pass (see `trimUnfolding` and Note [Drop unfoldings and rules]. -12. Eliminate case clutter in favour of unsafe coercions. - See Note [Unsafe coercions] - -13. Eliminate some magic Ids, specifically +12. Eliminate some magic Ids, specifically runRW# (\s. e) ==> e[readWorldId/s] lazy e ==> e (see Note [lazyId magic] in GHC.Types.Id.Make) noinline e ==> e @@ -157,48 +151,6 @@ This is all done modulo type applications and abstractions, so that when type erasure is done for conversion to STG, we don't end up with any trivial or useless bindings. -Note [Unsafe coercions] -~~~~~~~~~~~~~~~~~~~~~~~ -CorePrep does these two transformations: - -1. Convert empty case to cast with an unsafe coercion - (case e of {}) ===> e |> unsafe-co - See Note [Empty case alternatives] in GHC.Core: if the case - alternatives are empty, the scrutinee must diverge or raise an - exception, so we can just dive into it. - - Of course, if the scrutinee *does* return, we may get a seg-fault. - A belt-and-braces approach would be to persist empty-alternative - cases to code generator, and put a return point anyway that calls a - runtime system error function. - - Notice that eliminating empty case can lead to an ill-kinded coercion - case error @Int "foo" of {} :: Int# - ===> error @Int "foo" |> unsafe-co - where unsafe-co :: Int ~ Int# - But that's fine because the expression diverges anyway. And it's - no different to what happened before. - -2. Eliminate unsafeEqualityProof in favour of an unsafe coercion - case unsafeEqualityProof of UnsafeRefl g -> e - ===> e[unsafe-co/g] - See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce - - Note that this requires us to substitute 'unsafe-co' for 'g', and - that is the main (current) reason for cpe_tyco_env in CorePrepEnv. - Tiresome, but not difficult. - -These transformations get rid of "case clutter", leaving only casts. -We are doing no further significant transformations, so the reasons -for the case forms have disappeared. And it is extremely helpful for -the ANF-ery, CoreToStg, and backends, if trivial expressions really do -look trivial. #19700 was an example. - -In both cases, the "unsafe-co" is just (UnivCo ty1 ty2 (CorePrepProv b)), -The boolean 'b' says whether the unsafe coercion is supposed to be -kind-homogeneous (yes for (2), no for (1). This information is used -/only/ by Lint. - Note [CorePrep invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is the syntax of the Core produced by CorePrep: @@ -785,10 +737,10 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) -- For example -- f (g x) ===> ([v = g x], f v) -cpeRhsE env (Type ty) - = return (emptyFloats, Type (cpSubstTy env ty)) -cpeRhsE env (Coercion co) - = return (emptyFloats, Coercion (cpSubstCo env co)) +cpeRhsE _ (Type ty) + = return (emptyFloats, Type ty) +cpeRhsE _ (Coercion co) + = return (emptyFloats, Coercion co) cpeRhsE env expr@(Lit (LitNumber nt i)) = case cp_convertNumLit (cpe_config env) nt i of Nothing -> return (emptyFloats, expr) @@ -822,7 +774,7 @@ cpeRhsE env (Tick tickish expr) cpeRhsE env (Cast expr co) = do { (floats, expr') <- cpeRhsE env expr - ; return (floats, Cast expr' (cpSubstCo env co)) } + ; return (floats, Cast expr' co) } cpeRhsE env expr@(Lam {}) = do { let (bndrs,body) = collectBinders expr @@ -830,36 +782,6 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } --- Eliminate empty case --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut _ ty []) - = do { (floats, scrut') <- cpeRhsE env scrut - ; let ty' = cpSubstTy env ty - scrut_ty' = exprType scrut' - co' = mkUnivCo prov Representational scrut_ty' ty' - prov = CorePrepProv False - -- False says that the kinds of two types may differ - -- E.g. we might cast Int to Int#. This is fine - -- because the scrutinee is guaranteed to diverge - - ; return (floats, Cast scrut' co') } - -- This can give rise to - -- Warning: Unsafe coercion: between unboxed and boxed value - -- but it's fine because 'scrut' diverges - --- Eliminate unsafeEqualityProof --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut bndr _ alts) - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder - -- is dead. It usually is, but see #18227 - , [Alt _ [co_var] rhs] <- alts - , let Pair ty1 ty2 = coVarTypes co_var - the_co = mkUnivCo prov Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) - prov = CorePrepProv True -- True <=> kind homogeneous - env' = extendCoVarEnv env co_var the_co - = cpeRhsE env' rhs - cpeRhsE env (Case scrut bndr ty alts) = do { (floats, scrut') <- cpeBody env scrut ; (env', bndr2) <- cpCloneBndr env bndr @@ -1205,14 +1127,10 @@ cpeApp top_env expr in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) - -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth - where - arg_ty' = cpSubstTy env arg_ty + -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make @@ -1224,9 +1142,7 @@ cpeApp top_env expr rebuild_app' env as (App fun' arg') (fs `appendFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co - -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -1497,11 +1413,32 @@ cpeArg env dmd arg ; if exprIsTrivial arg2 then return (floats2, arg2) else do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1619,6 +1556,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1982,6 +1957,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1992,6 +1972,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- @@ -2005,8 +1986,6 @@ data CorePrepEnv -- see Note [lazyId magic], Note [Inlining in CorePrep] -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) - , cpe_tyco_env :: Maybe CpeTyCoEnv -- See Note [CpeTyCoEnv] - , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } @@ -2014,7 +1993,6 @@ mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg , cpe_env = emptyVarEnv - , cpe_tyco_env = Nothing , cpe_rec_ids = emptyUnVarSet } @@ -2041,117 +2019,6 @@ enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv enterRecGroupRHSs env grp = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } ------------------------------------------------------------------------------- --- CpeTyCoEnv --- --------------------------------------------------------------------------- - -{- Note [CpeTyCoEnv] -~~~~~~~~~~~~~~~~~~~~ -The cpe_tyco_env :: Maybe CpeTyCoEnv field carries a substitution -for type and coercion variables - -* We need the coercion substitution to support the elimination of - unsafeEqualityProof (see Note [Unsafe coercions]) - -* We need the type substitution in case one of those unsafe - coercions occurs in the kind of tyvar binder (sigh) - -We don't need an in-scope set because we don't clone any of these -binders at all, so no new capture can take place. - -The cpe_tyco_env is almost always empty -- it only gets populated -when we get under an usafeEqualityProof. Hence the Maybe CpeTyCoEnv, -which makes everything into a no-op in the common case. --} - -data CpeTyCoEnv = TCE TvSubstEnv CvSubstEnv - -emptyTCE :: CpeTyCoEnv -emptyTCE = TCE emptyTvSubstEnv emptyCvSubstEnv - -extend_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -> CpeTyCoEnv -extend_tce_cv (TCE tv_env cv_env) cv co - = TCE tv_env (extendVarEnv cv_env cv co) - -extend_tce_tv :: CpeTyCoEnv -> TyVar -> Type -> CpeTyCoEnv -extend_tce_tv (TCE tv_env cv_env) tv ty - = TCE (extendVarEnv tv_env tv ty) cv_env - -lookup_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -lookup_tce_cv (TCE _ cv_env) cv - = case lookupVarEnv cv_env cv of - Just co -> co - Nothing -> mkCoVarCo cv - -lookup_tce_tv :: CpeTyCoEnv -> TyVar -> Type -lookup_tce_tv (TCE tv_env _) tv - = case lookupVarEnv tv_env tv of - Just ty -> ty - Nothing -> mkTyVarTy tv - -extendCoVarEnv :: CorePrepEnv -> CoVar -> Coercion -> CorePrepEnv -extendCoVarEnv cpe@(CPE { cpe_tyco_env = mb_tce }) cv co - = cpe { cpe_tyco_env = Just (extend_tce_cv tce cv co) } - where - tce = mb_tce `orElse` emptyTCE - - -cpSubstTy :: CorePrepEnv -> Type -> Type -cpSubstTy (CPE { cpe_tyco_env = mb_env }) ty - = case mb_env of - Just env -> runIdentity (subst_ty env ty) - Nothing -> ty - -cpSubstCo :: CorePrepEnv -> Coercion -> Coercion -cpSubstCo (CPE { cpe_tyco_env = mb_env }) co - = case mb_env of - Just tce -> runIdentity (subst_co tce co) - Nothing -> co - -subst_tyco_mapper :: TyCoMapper CpeTyCoEnv Identity -subst_tyco_mapper = TyCoMapper - { tcm_tyvar = \env tv -> return (lookup_tce_tv env tv) - , tcm_covar = \env cv -> return (lookup_tce_cv env cv) - , tcm_hole = \_ hole -> pprPanic "subst_co_mapper:hole" (ppr hole) - , tcm_tycobinder = \env tcv _vis -> if isTyVar tcv - then return (subst_tv_bndr env tcv) - else return (subst_cv_bndr env tcv) - , tcm_tycon = \tc -> return tc } - -subst_ty :: CpeTyCoEnv -> Type -> Identity Type -subst_co :: CpeTyCoEnv -> Coercion -> Identity Coercion -(subst_ty, _, subst_co, _) = mapTyCoX subst_tyco_mapper - -cpSubstTyVarBndr :: CorePrepEnv -> TyVar -> (CorePrepEnv, TyVar) -cpSubstTyVarBndr env@(CPE { cpe_tyco_env = mb_env }) tv - = case mb_env of - Nothing -> (env, tv) - Just tce -> (env { cpe_tyco_env = Just tce' }, tv') - where - (tce', tv') = subst_tv_bndr tce tv - -subst_tv_bndr :: CpeTyCoEnv -> TyVar -> (CpeTyCoEnv, TyVar) -subst_tv_bndr tce tv - = (extend_tce_tv tce tv (mkTyVarTy tv'), tv') - where - tv' = mkTyVar (tyVarName tv) kind' - kind' = runIdentity $ subst_ty tce $ tyVarKind tv - -cpSubstCoVarBndr :: CorePrepEnv -> CoVar -> (CorePrepEnv, CoVar) -cpSubstCoVarBndr env@(CPE { cpe_tyco_env = mb_env }) cv - = case mb_env of - Nothing -> (env, cv) - Just tce -> (env { cpe_tyco_env = Just tce' }, cv') - where - (tce', cv') = subst_cv_bndr tce cv - -subst_cv_bndr :: CpeTyCoEnv -> CoVar -> (CpeTyCoEnv, CoVar) -subst_cv_bndr tce cv - = (extend_tce_cv tce cv (mkCoVarCo cv'), cv') - where - cv' = mkCoVar (varName cv) ty' - ty' = runIdentity (subst_ty tce $ varType cv) - ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2161,13 +2028,6 @@ cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) cpCloneBndr env bndr - | isTyVar bndr - = return (cpSubstTyVarBndr env bndr) - - | isCoVar bndr - = return (cpSubstCoVarBndr env bndr) - - | otherwise = do { bndr' <- clone_it bndr -- Drop (now-useless) rules/unfoldings @@ -2186,8 +2046,7 @@ cpCloneBndr env bndr clone_it bndr | isLocalId bndr = do { uniq <- getUniqueM - ; let ty' = cpSubstTy env (idType bndr) - ; return (setVarUnique (setIdType bndr ty') uniq) } + ; return (setVarUnique bndr uniq) } | otherwise -- Top level things, which we don't want -- to clone, have become GlobalIds by now ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1748,7 +1748,6 @@ freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co freeNamesIfProv (IfacePluginProv _) = emptyNameSet -freeNamesIfProv (IfaceCorePrepProv _) = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -402,7 +402,6 @@ data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String - | IfaceCorePrepProv Bool -- See defn of CorePrepProv {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,7 +623,6 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) go_prov co@(IfacePluginProv _) = co - go_prov co@(IfaceCorePrepProv _) = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1860,8 +1858,6 @@ pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) -pprIfaceUnivCoProv (IfaceCorePrepProv _) - = text "CorePrep" ------------------- instance Outputable IfaceTyCon where @@ -2229,9 +2225,6 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a) = do putByte bh 3 put_ bh a - put_ bh (IfaceCorePrepProv a) = do - putByte bh 4 - put_ bh a get bh = do tag <- getByte bh @@ -2242,8 +2235,6 @@ instance Binary IfaceUnivCoProv where return $ IfaceProofIrrelProv a 3 -> do a <- get bh return $ IfacePluginProv a - 4 -> do a <- get bh - return (IfaceCorePrepProv a) _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1520,7 +1520,6 @@ tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceCorePrepProv b) = return $ CorePrepProv b {- ************************************************************************ ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -53,7 +53,6 @@ import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import Control.Monad ( unless, void ) import Control.Arrow ( first ) @@ -1028,7 +1027,7 @@ cgIdApp fun_id args = do (text "TagCheck failed on entry in" <+> ppr mod <+> text "- value:" <> ppr fun_id <+> pdoc platform fun)) fun - EnterIt -> assert (null args) $ -- Discarding arguments + EnterIt -> assertPpr (null args) (ppr fun_id $$ ppr args) $ -- Discarding arguments emitEnter fun SlowCall -> do -- A slow function call via the RTS apply routines ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -156,7 +156,6 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyNameEnv - go_prov (CorePrepProv _) = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1578,7 +1578,6 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co go_prov dv (PluginProv _) = return dv - go_prov dv (CorePrepProv _) = return dv go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== compiler/GHC/Utils/Trace.hs ===================================== @@ -8,6 +8,7 @@ module GHC.Utils.Trace , pprSTrace , pprTraceException , warnPprTrace + , warnPprTraceM , pprTraceUserWarning , trace ) @@ -84,6 +85,9 @@ warnPprTrace True s msg x (text s $$ msg $$ withFrozenCallStack traceCallStackDoc ) x +warnPprTraceM :: (Applicative f, HasCallStack) => Bool -> String -> SDoc -> f () +warnPprTraceM b s doc = withFrozenCallStack warnPprTrace b s doc (pure ()) + -- | For when we want to show the user a non-fatal WARNING so that they can -- report a GHC bug, but don't want to panic. pprTraceUserWarning :: HasCallStack => SDoc -> a -> a ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== libraries/base/Unsafe/Coerce.hs ===================================== @@ -88,13 +88,13 @@ several ways (U1) unsafeEqualityProof is /never/ inlined. -(U2) In CoreToStg.Prep, we transform +(U2) In CoreToStg, we transform case unsafeEqualityProof of UnsafeRefl g -> blah ==> - blah[unsafe-co/g] + blah - This eliminates the overhead of evaluating the unsafe - equality proof. + This eliminates the overhead of evaluating the unsafe equality proof. + (It follows that the Case is trivial iff `blah` is.) Any /other/ occurrence of unsafeEqualityProof is left alone. For example you could write @@ -131,9 +131,11 @@ several ways Floating the case is OK here, even though it broadens the scope, because we are done with simplification. -(U4) Ditto GHC.Core.Unfold.inlineBoringOk we want to treat - the RHS of unsafeCoerce as very small; see - Note [Inline unsafeCoerce] in that module. +(U4) We regard `case unsafeEqualityProof of UnsafeRefl -> rhs` as trivial iff + `rhs` is. One reason is that we want to treat the RHS of unsafeCoerce as + very small; see Note [Inline unsafeCoerce] in that module. + Another is that we do not want to allocate a thunk in CorePrep when we + wouldn't do so for `rhs`, because we discard the case in CoreToStg anyway. (U5) The definition of unsafeEqualityProof in Unsafe.Coerce looks very strange: ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,10 @@ +module T23083 where + +-- Just ($), but NOINLINE so that we don't inline it eagerly, subverting the +-- test case +($$) :: (a -> b) -> a -> b +($$) f x = f x +{-# NOINLINE ($$) #-} + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $$)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,47 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 34, types: 34, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 6, types: 5, coercions: 0, joins: 0/0} +(T23083.$$) [InlPrag=NOINLINE] :: forall a b. (a -> b) -> a -> b +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +(T23083.$$) = \ (@a) (@b) (f [Occ=Once1!] :: a -> b) (x [Occ=Once1] :: a) -> f x + +-- RHS size: {terms: 12, types: 12, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/67b0a06fd9e43d7ce59f0d81484f3b9e583af0d5...17b0d150ceb7b22bc28593fea40fa8188ecc2138 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/67b0a06fd9e43d7ce59f0d81484f3b9e583af0d5...17b0d150ceb7b22bc28593fea40fa8188ecc2138 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 09:16:04 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 05:16:04 -0400 Subject: [Git][ghc/ghc][wip/romes/fix-docs] docs: Remove mentions of ArrayArray# from unlifted FFI section Message-ID: <644b8ed4d8358_178e74109fd7e4c20723eb@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/fix-docs at Glasgow Haskell Compiler / GHC Commits: ccccfd60 by Rodrigo Mesquita at 2023-04-28T10:15:40+01:00 docs: Remove mentions of ArrayArray# from unlifted FFI section Fixes #23277 - - - - - 1 changed file: - docs/users_guide/exts/ffi.rst Changes: ===================================== docs/users_guide/exts/ffi.rst ===================================== @@ -126,7 +126,7 @@ types may be used as arguments to FFI calls, subject to these restrictions: * Valid arguments for ``foreign import unsafe`` FFI calls: ``Array#``, - ``SmallArray#``, ``ArrayArray#``, ``ByteArray#``, and the mutable + ``SmallArray#``, ``ByteArray#``, and the mutable counterparts of these types. * Valid arguments for ``foreign import safe`` FFI calls: ``ByteArray#`` and ``MutableByteArray#``. The byte array must be @@ -174,10 +174,6 @@ are: +--------------------------------+-----------+-------------+-----------+---------------+ | ``MutableSmallArray#`` | Unsound | Unsound | Sound | Unsound | +--------------------------------+-----------+-------------+-----------+---------------+ - | ``ArrayArray#`` | Unsound | Unsound | Sound | Unsound | - +--------------------------------+-----------+-------------+-----------+---------------+ - | ``MutableArrayArray#`` | Unsound | Unsound | Sound | Unsound | - +--------------------------------+-----------+-------------+-----------+---------------+ | unpinned ``ByteArray#`` | Unsound | Unsound | Sound | Unsound | +--------------------------------+-----------+-------------+-----------+---------------+ | unpinned ``MutableByteArray#`` | Unsound | Unsound | Sound | Sound | @@ -210,32 +206,32 @@ anything from ``Rts.h``:: In other situations, the C function may need knowledge of the RTS closure types. The following example sums the first element of each ``ByteArray#`` (interpreting the bytes as an array of ``CInt``) -element of an ``ArrayArray##`` [3]_:: +element of an ``Array# ByteArray#`` [3]_:: // C source, must include the RTS to make the struct StgArrBytes - // available along with its fields: ptrs and payload. + // available along with its fields, such as `payload`. #include "Rts.h" - int sum_first (StgArrBytes **bufs) { - StgArrBytes **bufs = (StgArrBytes**)bufsTmp; + int sum_first (StgArrBytes **bufs, StgWord sz) { int res = 0; - for(StgWord ix = 0;ix < arr->ptrs;ix++) { + for(StgWord ix = 0; ix < sz; ix++) { res = res + ((int*)(bufs[ix]->payload))[0]; } return res; } - -- Haskell source, all elements in the argument array must be - -- either ByteArray# or MutableByteArray#. This is not enforced - -- by the type system in this example since ArrayArray is untyped. + -- Haskell source foreign import ccall unsafe "sum_first" - sumFirst :: ArrayArray# -> IO CInt + sumFirst :: Array# ByteArray# -> CInt -> IO CInt + + sumFirst' :: Array# ByteArray# -> IO CInt + sumFirst' arr = sumFirst arr (sizeofArray# arr) -Although GHC allows the user to pass all unlifted boxed types to -foreign functions, some of them are not amenable to useful work. -Although ``Array#`` is unlifted, the elements in its payload are -lifted, and a foreign C function cannot safely force thunks. Consequently, -a foreign C function may not dereference any of the addresses that comprise -the payload of the ``Array#``. +Although GHC allows the user to pass all unlifted boxed types to foreign +functions, some of them are not amenable to useful work. Although ``Array#`` +is unlifted, the elements in its payload can be lifted, and a foreign C +function cannot safely force thunks. Consequently, a foreign C function may not +dereference any of the addresses that comprise the payload of ``Array# a`` if +``a`` has a lifted representation. .. _ffi-newtype-io: @@ -1136,4 +1132,5 @@ byte array can be pinned as a result of three possible causes: as reading bytes from a ``MutableByteArray#``. Users should prefer ``GHC.Exts.readWord8Array#`` for this. .. [3] As in [2]_, the FFI is not actually needed for this. ``GHC.Exts`` - includes primitives for reading from on ``ArrayArray#``. + includes primitives for reading from an ``Array# a``, such as + ``GHC.Exts.indexArray#``. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ccccfd608383a084c873f3d6bb33203bb25e86fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ccccfd608383a084c873f3d6bb33203bb25e86fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 10:42:22 2023 From: gitlab at gitlab.haskell.org (Josh Meredith (@JoshMeredith)) Date: Fri, 28 Apr 2023 06:42:22 -0400 Subject: [Git][ghc/ghc][wip/codebuffer-perftest] base/encoding: add an allocations performance test (#22946) Message-ID: <644ba30e5c04f_178e7410b5df8d420897d3@gitlab.mail> Josh Meredith pushed to branch wip/codebuffer-perftest at Glasgow Haskell Compiler / GHC Commits: 3c4460eb by Josh Meredith at 2023-04-28T10:42:13+00:00 base/encoding: add an allocations performance test (#22946) - - - - - 2 changed files: - libraries/base/tests/perf/all.T - + libraries/base/tests/perf/encodingAllocations.hs Changes: ===================================== libraries/base/tests/perf/all.T ===================================== @@ -1,5 +1,16 @@ +# .stats files aren't yet supported in the JS backend +setTestOpts(js_skip) + #-------------------------------------- # Check specialization of elem via rules #-------------------------------------- test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) + +#-------------------------------------- + +# We don't expect the code in test to vary at all, but the variance is set to +# 1% in case the constant allocations increase by other means. +# +# The JavaScript +test('encodingAllocations', [only_ways(['normal']), collect_stats('bytes allocated', 1)], compile_and_run, ['-O2']) ===================================== libraries/base/tests/perf/encodingAllocations.hs ===================================== @@ -0,0 +1,36 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE CPP #-} +{-# OPTIONS_GHC -dno-typeable-binds -O2 #-} + +module Main (main) where + +import System.IO +import Data.Bits +import GHC.Int +import GHC.Exts +import System.Environment +import Distribution.Simple.Utils + +devnull :: FilePath +#if defined(mingw32_HOST_OS) +devnull = "NUL" +#else +devnull = "/dev/null" +#endif + +main :: IO () +main = withTempFile "." "encodingAllocations.tmp" (const $ loop 1000000) + +loop :: Int -> Handle -> IO () +loop 0 !_ = pure () +loop !n !h = do + hPutChar h $! dummy_char n + loop (n-1) h + +-- unsafe efficient version of `chr` +my_chr :: Int -> Char +my_chr (I# i) = C# (chr# i) + +-- return either a or b +dummy_char :: Int -> Char +dummy_char !i = my_chr ((i .&. 1) + 97) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c4460eb7afe13b24b156f3da7980c29c6aef6a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c4460eb7afe13b24b156f3da7980c29c6aef6a4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 10:49:02 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 28 Apr 2023 06:49:02 -0400 Subject: [Git][ghc/ghc][wip/T23083] 2 commits: CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead Message-ID: <644ba49eceb99_178e7410b4c6a9c2090168@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 50b72e99 by Sebastian Graf at 2023-04-28T12:48:42+02:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - cd7b0b2a by Sebastian Graf at 2023-04-28T12:48:42+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - libraries/base/Unsafe/Coerce.hs - + testsuite/tests/simplCore/should_compile/T23083.hs - + testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -717,9 +717,12 @@ this exhaustive list can be empty! its scrutinee is (see GHC.Core.Utils.exprIsTrivial). This is actually important; see Note [Empty case is trivial] in GHC.Core.Utils -* An empty case is replaced by its scrutinee during the CoreToStg - conversion; remember STG is un-typed, so there is no need for - the empty case to do the type conversion. +* We lower empty cases in GHC.CoreToStg to an eval on the scrutinee. + +Historical Note: We used to lower EmptyCase in CorePrep by way of an +unsafeCoercion on the scrutinee, but that yielded panics in CodeGen when +we were beginning to eta expand in arguments, plus required to mess with +heterogenously-kinded coercions. It's simpler to stick to it just a bit longer. Note [Join points] ~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -1390,7 +1390,6 @@ setNominalRole_maybe r co | case prov of PhantomProv _ -> False -- should always be phantom ProofIrrelProv _ -> True -- it's always safe PluginProv _ -> False -- who knows? This choice is conservative. - CorePrepProv _ -> True = Just $ UnivCo prov Nominal co1 co2 setNominalRole_maybe_helper _ = Nothing @@ -1516,7 +1515,6 @@ promoteCoercion co = case co of UnivCo (PhantomProv kco) _ _ _ -> kco UnivCo (ProofIrrelProv kco) _ _ _ -> kco UnivCo (PluginProv _) _ _ _ -> mkKindCo co - UnivCo (CorePrepProv _) _ _ _ -> mkKindCo co SymCo g -> mkSymCo (promoteCoercion g) @@ -2339,7 +2337,6 @@ seqProv :: UnivCoProvenance -> () seqProv (PhantomProv co) = seqCo co seqProv (ProofIrrelProv co) = seqCo co seqProv (PluginProv _) = () -seqProv (CorePrepProv _) = () seqCos :: [Coercion] -> () seqCos [] = () ===================================== compiler/GHC/Core/Coercion/Opt.hs ===================================== @@ -622,7 +622,6 @@ opt_univ env sym prov role oty1 oty2 #endif ProofIrrelProv kco -> ProofIrrelProv $ opt_co4_wrap env sym False Nominal kco PluginProv _ -> prov - CorePrepProv _ -> prov ------------- opt_transList :: HasDebugCallStack => InScopeSet -> [NormalCo] -> [NormalCo] -> [NormalCo] ===================================== compiler/GHC/Core/FVs.hs ===================================== @@ -410,7 +410,6 @@ orphNamesOfProv :: UnivCoProvenance -> NameSet orphNamesOfProv (PhantomProv co) = orphNamesOfCo co orphNamesOfProv (ProofIrrelProv co) = orphNamesOfCo co orphNamesOfProv (PluginProv _) = emptyNameSet -orphNamesOfProv (CorePrepProv _) = emptyNameSet orphNamesOfCos :: [Coercion] -> NameSet orphNamesOfCos = orphNamesOfThings orphNamesOfCo @@ -798,4 +797,3 @@ freeVars = go go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty) go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) - ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2301,9 +2301,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) -- see #9122 for discussion of these checks checkTypes t1 t2 - | allow_ill_kinded_univ_co prov - = return () -- Skip kind checks - | otherwise = do { checkWarnL fixed_rep_1 (report "left-hand type does not have a fixed runtime representation") ; checkWarnL fixed_rep_2 @@ -2321,13 +2318,6 @@ lintCoercion co@(UnivCo prov r ty1 ty2) reps1 = typePrimRep t1 reps2 = typePrimRep t2 - -- CorePrep deliberately makes ill-kinded casts - -- e.g (case error @Int "blah" of {}) :: Int# - -- ==> (error @Int "blah") |> Unsafe Int Int# - -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - allow_ill_kinded_univ_co (CorePrepProv homo_kind) = not homo_kind - allow_ill_kinded_univ_co _ = False - validateCoercion :: PrimRep -> PrimRep -> LintM () validateCoercion rep1 rep2 = do { platform <- getPlatform @@ -2357,8 +2347,7 @@ lintCoercion co@(UnivCo prov r ty1 ty2) ; check_kinds kco k1 k2 ; return (ProofIrrelProv kco') } - lint_prov _ _ prov@(PluginProv _) = return prov - lint_prov _ _ prov@(CorePrepProv _) = return prov + lint_prov _ _ prov@(PluginProv _) = return prov check_kinds kco k1 k2 = do { let Pair k1' k2' = coercionKind kco ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -661,7 +661,6 @@ tyCoFVsOfProv :: UnivCoProvenance -> FV tyCoFVsOfProv (PhantomProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (ProofIrrelProv co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in_scope acc tyCoFVsOfProv (PluginProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc -tyCoFVsOfProv (CorePrepProv _) fv_cand in_scope acc = emptyFV fv_cand in_scope acc tyCoFVsOfCos :: [Coercion] -> FV tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc @@ -731,8 +730,7 @@ almost_devoid_co_var_of_prov (PhantomProv co) cv = almost_devoid_co_var_of_co co cv almost_devoid_co_var_of_prov (ProofIrrelProv co) cv = almost_devoid_co_var_of_co co cv -almost_devoid_co_var_of_prov (PluginProv _) _ = True -almost_devoid_co_var_of_prov (CorePrepProv _) _ = True +almost_devoid_co_var_of_prov (PluginProv _) _ = True almost_devoid_co_var_of_type :: Type -> CoVar -> Bool almost_devoid_co_var_of_type (TyVarTy _) _ = True @@ -1131,9 +1129,6 @@ tyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyUniqSet - go_prov (CorePrepProv _) = emptyUniqSet - -- this last case can happen from the tyConsOfType used from - -- checkTauTvUpdate go_cos cos = foldr (unionUniqSets . go_co) emptyUniqSet cos @@ -1345,5 +1340,3 @@ occCheckExpand vs_to_avoid ty go_prov cxt (PhantomProv co) = PhantomProv <$> go_co cxt co go_prov cxt (ProofIrrelProv co) = ProofIrrelProv <$> go_co cxt co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p - ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1437,17 +1437,12 @@ data UnivCoProvenance | PluginProv String -- ^ From a plugin, which asserts that this coercion -- is sound. The string is for the use of the plugin. - | CorePrepProv -- See Note [Unsafe coercions] in GHC.Core.CoreToStg.Prep - Bool -- True <=> the UnivCo must be homogeneously kinded - -- False <=> allow hetero-kinded, e.g. Int ~ Int# - deriving Data.Data instance Outputable UnivCoProvenance where ppr (PhantomProv _) = text "(phantom)" ppr (ProofIrrelProv _) = text "(proof irrel.)" ppr (PluginProv str) = parens (text "plugin" <+> brackets (text str)) - ppr (CorePrepProv _) = text "(CorePrep)" -- | A coercion to be filled in by the type-checker. See Note [Coercion holes] data CoercionHole @@ -1760,7 +1755,6 @@ foldTyCo (TyCoFolder { tcf_view = view go_prov env (PhantomProv co) = go_co env co go_prov env (ProofIrrelProv co) = go_co env co go_prov _ (PluginProv _) = mempty - go_prov _ (CorePrepProv _) = mempty -- | A view function that looks through nothing. noView :: Type -> Maybe Type @@ -1826,7 +1820,6 @@ provSize :: UnivCoProvenance -> Int provSize (PhantomProv co) = 1 + coercionSize co provSize (ProofIrrelProv co) = 1 + coercionSize co provSize (PluginProv _) = 1 -provSize (CorePrepProv _) = 1 {- ************************************************************************ ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -912,7 +912,6 @@ subst_co subst co go_prov (PhantomProv kco) = PhantomProv (go kco) go_prov (ProofIrrelProv kco) = ProofIrrelProv (go kco) go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p -- See Note [Substituting in a coercion hole] go_hole h@(CoercionHole { ch_co_var = cv }) ===================================== compiler/GHC/Core/TyCo/Tidy.hs ===================================== @@ -252,7 +252,6 @@ tidyCo env@(_, subst) co go_prov (PhantomProv co) = PhantomProv $! go co go_prov (ProofIrrelProv co) = ProofIrrelProv $! go co go_prov p@(PluginProv _) = p - go_prov p@(CorePrepProv _) = p tidyCos :: TidyEnv -> [Coercion] -> [Coercion] tidyCos env = strictMap (tidyCo env) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -580,7 +580,6 @@ expandTypeSynonyms ty go_prov subst (PhantomProv co) = PhantomProv (go_co subst co) go_prov subst (ProofIrrelProv co) = ProofIrrelProv (go_co subst co) go_prov _ p@(PluginProv _) = p - go_prov _ p@(CorePrepProv _) = p -- the "False" and "const" are to accommodate the type of -- substForAllCoBndrUsing, which is general enough to @@ -998,7 +997,6 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar go_prov env (PhantomProv co) = PhantomProv <$> go_co env co go_prov env (ProofIrrelProv co) = ProofIrrelProv <$> go_co env co go_prov _ p@(PluginProv _) = return p - go_prov _ p@(CorePrepProv _) = return p {- ********************************************************************* ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -249,8 +249,11 @@ inlineBoringOk e , exprIsTrivial a = go (credit-1) f go credit (Tick _ e) = go credit e -- dubious go credit (Cast e _) = go credit e - go credit (Case scrut _ _ [Alt _ _ rhs]) -- See Note [Inline unsafeCoerce] - | isUnsafeEqualityProof scrut = go credit rhs + go credit (Case e b _ alts) + | null alts + = go credit e -- EmptyCase is like e + | Just rhs <- isUnsafeEqualityCase e b alts + = go credit rhs -- See Note [Inline unsafeCoerce] go _ (Var {}) = boringCxtOk go _ (Lit l) = litIsTrivial l && boringCxtOk go _ _ = boringCxtNotOk @@ -304,7 +307,7 @@ calcUnfoldingGuidance opts is_top_bottoming expr We really want to inline unsafeCoerce, even when applied to boring arguments. It doesn't look as if its RHS is smaller than the call unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x -but that case is discarded -- see Note [Implementing unsafeCoerce] +but that case is discarded in CoreToStg -- see Note [Implementing unsafeCoerce] in base:Unsafe.Coerce. Moreover, if we /don't/ inline it, we may be left with @@ -312,7 +315,9 @@ Moreover, if we /don't/ inline it, we may be left with which will build a thunk -- bad, bad, bad. Conclusion: we really want inlineBoringOk to be True of the RHS of -unsafeCoerce. This is (U4) in Note [Implementing unsafeCoerce]. +unsafeCoerce. And it really is, because we regard + case unsafeEqualityProof @a @b of UnsafeRefl -> rhs +as trivial iff rhs is. This is (U4) in Note [Implementing unsafeCoerce]. Note [Computing the size of an expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -59,7 +59,7 @@ module GHC.Core.Utils ( mkStrictFieldSeqs, shouldStrictifyIdForCbv, shouldUseCbvForId, -- * unsafeEqualityProof - isUnsafeEqualityProof, + isUnsafeEqualityCase, -- * Dumping stuff dumpIdInfoOfProgram @@ -79,7 +79,7 @@ import GHC.Core.Reduction import GHC.Core.TyCon import GHC.Core.Multiplicity -import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofIdKey ) +import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofIdKey, unsafeReflDataConKey ) import GHC.Builtin.PrimOps import GHC.Types.Var @@ -1072,7 +1072,11 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go go (Lam b e) | not (isRuntimeVar b) = go e go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial] go (Cast e _) = go e - go (Case e _ _ []) = go e -- See Note [Empty case is trivial] + go (Case e b _ as) + | null as + = go e -- See Note [Empty case is trivial] + | Just rhs <- isUnsafeEqualityCase e b as + = go rhs -- See (U2) of Note [Implementing unsafeCoerce] in base:Unsafe.Coerce go _ = k_not_triv exprIsTrivial :: CoreExpr -> Bool @@ -2707,11 +2711,22 @@ wantCbvForId cbv_for_strict v * * ********************************************************************* -} -isUnsafeEqualityProof :: CoreExpr -> Bool +isUnsafeEqualityCase :: CoreExpr -> Id -> [CoreAlt] -> Maybe CoreExpr -- See (U3) and (U4) in -- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce -isUnsafeEqualityProof e - | Var v `App` Type _ `App` Type _ `App` Type _ <- e - = v `hasKey` unsafeEqualityProofIdKey - | otherwise - = False +isUnsafeEqualityCase scrut bndr [Alt ac _ rhs] + | DataAlt dc <- ac + , not (dc `hasKey` unsafeReflDataConKey) + = Nothing -- fast path for DataAlt + + | isDeadBinder bndr + -- We can only discard the case if the case-binder is dead + -- It usually is, but see #18227 + , Var v `App` _ `App` _ `App` _ <- scrut + , v `hasKey` unsafeEqualityProofIdKey + -- Check that the scrutinee really is unsafeEqualityProof + -- and not, say, error + = Just rhs + +isUnsafeEqualityCase _ _ _ + = Nothing ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -321,7 +321,6 @@ toIfaceCoercionX fr co go_prov (PhantomProv co) = IfacePhantomProv (go co) go_prov (ProofIrrelProv co) = IfaceProofIrrelProv (go co) go_prov (PluginProv str) = IfacePluginProv str - go_prov (CorePrepProv b) = IfaceCorePrepProv b toIfaceTcArgs :: TyCon -> [Type] -> IfaceAppArgs toIfaceTcArgs = toIfaceTcArgsX emptyVarSet ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -19,8 +19,7 @@ module GHC.CoreToStg ( CoreToStgOpts (..), coreToStg ) where import GHC.Prelude import GHC.Core -import GHC.Core.Utils ( exprType, findDefault, isJoinBind - , exprIsTickedString_maybe ) +import GHC.Core.Utils import GHC.Core.Opt.Arity ( manifestArity ) import GHC.Core.Type import GHC.Core.TyCon @@ -49,7 +48,7 @@ import GHC.Unit.Module import GHC.Data.FastString import GHC.Platform ( Platform ) import GHC.Platform.Ways -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps import GHC.Utils.Outputable import GHC.Utils.Monad @@ -430,30 +429,23 @@ coreToStgExpr (Cast expr _) = coreToStgExpr expr -- Cases require a little more real work. - -{- -coreToStgExpr (Case scrut _ _ []) +coreToStgExpr (Case scrut bndr _ alts) + | null alts + -- See Note [Empty case alternatives] in GHC.Core If the case + -- alternatives are empty, the scrutinee must diverge or raise an + -- exception, so we can just dive into it. + -- + -- Of course this may seg-fault if the scrutinee *does* return. A + -- belt-and-braces approach would be to move this case into the + -- code generator, and put a return point anyway that calls a + -- runtime system error function. = coreToStgExpr scrut - -- See Note [Empty case alternatives] in GHC.Core If the case - -- alternatives are empty, the scrutinee must diverge or raise an - -- exception, so we can just dive into it. - -- - -- Of course this may seg-fault if the scrutinee *does* return. A - -- belt-and-braces approach would be to move this case into the - -- code generator, and put a return point anyway that calls a - -- runtime system error function. - -coreToStgExpr e0@(Case scrut bndr _ [alt]) = do - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder is dead - -- It usually is, but see #18227 - , (_,_,rhs) <- alt + + | Just rhs <- isUnsafeEqualityCase scrut bndr alts + -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce = coreToStgExpr rhs - -- See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce --} --- The normal case for case-expressions -coreToStgExpr (Case scrut bndr _ alts) + | otherwise = do { scrut2 <- coreToStgExpr scrut ; alts2 <- extendVarEnvCts [(bndr, LambdaBound)] (mapM vars_alt alts) ; return (StgCase scrut2 bndr (mkStgAltType bndr alts) alts2) } @@ -574,6 +566,15 @@ coreToStgApp f args ticks = do -- This is the guy that turns applications into A-normal form -- --------------------------------------------------------------------------- +getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg +-- A (non-erased) trivial CoreArg corresponds to an atomic StgArg. +-- CoreArgs may not immediately look trivial, e.g., `case e of {}` or +-- `case unsafeequalityProof of UnsafeRefl -> e` might intervene. +-- Good thing we can just call `trivial_expr_fold` here. +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e + where + panic = pprPanic "getStgArgFromTrivialArg" (ppr e) + coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish]) coreToStgArgs [] = return ([], []) @@ -586,42 +587,29 @@ coreToStgArgs (Coercion _ : args) -- Coercion argument; See Note [Coercion token = do { (args', ts) <- coreToStgArgs args ; return (StgVarArg coercionTokenId : args', ts) } -coreToStgArgs (Tick t e : args) - = assert (not (tickishIsCode t)) $ - do { (args', ts) <- coreToStgArgs (e : args) - ; let !t' = coreToStgTick (exprType e) t - ; return (args', t':ts) } - coreToStgArgs (arg : args) = do -- Non-type argument (stg_args, ticks) <- coreToStgArgs args - arg' <- coreToStgExpr arg - let - (aticks, arg'') = stripStgTicksTop tickishFloatable arg' - stg_arg = case arg'' of - StgApp v [] -> StgVarArg v - StgConApp con _ [] _ -> StgVarArg (dataConWorkId con) - StgOpApp (StgPrimOp op) [] _ -> StgVarArg (primOpWrapperId op) - StgLit lit -> StgLitArg lit - _ -> pprPanic "coreToStgArgs" (ppr arg $$ pprStgExpr panicStgPprOpts arg' $$ pprStgExpr panicStgPprOpts arg'') - - -- WARNING: what if we have an argument like (v `cast` co) - -- where 'co' changes the representation type? - -- (This really only happens if co is unsafe.) - -- Then all the getArgAmode stuff in CgBindery will set the - -- cg_rep of the CgIdInfo based on the type of v, rather - -- than the type of 'co'. - -- This matters particularly when the function is a primop - -- or foreign call. - -- Wanted: a better solution than this hacky warning - + -- We know that `arg` must be trivial, but it may contain Ticks. + -- Example from test case `decodeMyStack`: + -- $ @... ((src Data.Tuple.snd) @Int @[..]) + -- Note that unfortunately the Tick is not at the top. + -- So we'll traverse the expression twice: + -- * Once with `stripTicksT` (which collects *all* ticks from the expression) + -- * and another time with `getStgArgFromTrivialArg`. + -- Since the argument is trivial, the only place the Tick can occur is + -- somehow wrapping a variable (give or take type args, as above). platform <- getPlatform - let - arg_rep = typePrimRep (exprType arg) - stg_arg_rep = typePrimRep (stgArgType stg_arg) + let arg_ty = exprType arg + ticks' = map (coreToStgTick arg_ty) (stripTicksT (not . tickishIsCode) arg) + arg' = getStgArgFromTrivialArg arg + arg_rep = typePrimRep arg_ty + stg_arg_rep = typePrimRep (stgArgType arg') bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep) - warnPprTrace bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) $ - return (stg_arg : stg_args, ticks ++ aticks) + massertPpr (length ticks' <= 1) (text "More than one Tick in trivial arg:" <+> ppr arg) + warnPprTraceM bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg) + + return (arg' : stg_args, ticks' ++ ticks) coreToStgTick :: Type -- type of the ticked expression -> CoreTickish @@ -959,6 +947,9 @@ myCollectBinders expr -- | If the argument expression is (potential chain of) 'App', return the head -- of the app chain, and collect ticks/args along the chain. +-- INVARIANT: If the app head is trivial, return the atomic Var/Lit that was +-- wrapped in casts, empty case, ticks, etc. +-- So keep in sync with 'exprIsTrivial'. myCollectArgs :: HasDebugCallStack => CoreExpr -> (CoreExpr, [CoreArg], [CoreTickish]) myCollectArgs expr = go expr [] [] @@ -970,8 +961,14 @@ myCollectArgs expr -- See Note [Ticks in applications] go e as (t:ts) -- ticks can appear in type apps go (Cast e _) as ts = go e as ts + go (Case e b _ alts) as ts + | null alts + = assertPpr (null as) (ppr e $$ ppr as $$ ppr expr) $ + go e [] ts -- NB: Empty case discards arguments + | Just rhs <- isUnsafeEqualityCase e b alts + = go rhs as ts -- Discards unsafeCoerce in App heads go (Lam b e) as ts - | isTyVar b = go e as ts -- Note [Collect args] + | isTyVar b = go e (drop 1 as) ts -- Note [Collect args] go e as ts = (e, as, ts) {- Note [Collect args] ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -40,12 +40,10 @@ import GHC.Core.Coercion import GHC.Core.TyCon import GHC.Core.DataCon import GHC.Core.Opt.OccurAnal -import GHC.Core.TyCo.Rep( UnivCoProvenance(..) ) import GHC.Data.Maybe import GHC.Data.OrdList import GHC.Data.FastString -import GHC.Data.Pair import GHC.Data.Graph.UnVar import GHC.Utils.Error @@ -71,7 +69,6 @@ import GHC.Types.TyThing import GHC.Types.Unique.Supply import Data.List ( unfoldr ) -import Data.Functor.Identity import Control.Monad {- @@ -142,10 +139,7 @@ The goal of this pass is to prepare for code generation. profiling mode. We have to do this here because we won't have unfoldings after this pass (see `trimUnfolding` and Note [Drop unfoldings and rules]. -12. Eliminate case clutter in favour of unsafe coercions. - See Note [Unsafe coercions] - -13. Eliminate some magic Ids, specifically +12. Eliminate some magic Ids, specifically runRW# (\s. e) ==> e[readWorldId/s] lazy e ==> e (see Note [lazyId magic] in GHC.Types.Id.Make) noinline e ==> e @@ -157,48 +151,6 @@ This is all done modulo type applications and abstractions, so that when type erasure is done for conversion to STG, we don't end up with any trivial or useless bindings. -Note [Unsafe coercions] -~~~~~~~~~~~~~~~~~~~~~~~ -CorePrep does these two transformations: - -1. Convert empty case to cast with an unsafe coercion - (case e of {}) ===> e |> unsafe-co - See Note [Empty case alternatives] in GHC.Core: if the case - alternatives are empty, the scrutinee must diverge or raise an - exception, so we can just dive into it. - - Of course, if the scrutinee *does* return, we may get a seg-fault. - A belt-and-braces approach would be to persist empty-alternative - cases to code generator, and put a return point anyway that calls a - runtime system error function. - - Notice that eliminating empty case can lead to an ill-kinded coercion - case error @Int "foo" of {} :: Int# - ===> error @Int "foo" |> unsafe-co - where unsafe-co :: Int ~ Int# - But that's fine because the expression diverges anyway. And it's - no different to what happened before. - -2. Eliminate unsafeEqualityProof in favour of an unsafe coercion - case unsafeEqualityProof of UnsafeRefl g -> e - ===> e[unsafe-co/g] - See (U2) in Note [Implementing unsafeCoerce] in base:Unsafe.Coerce - - Note that this requires us to substitute 'unsafe-co' for 'g', and - that is the main (current) reason for cpe_tyco_env in CorePrepEnv. - Tiresome, but not difficult. - -These transformations get rid of "case clutter", leaving only casts. -We are doing no further significant transformations, so the reasons -for the case forms have disappeared. And it is extremely helpful for -the ANF-ery, CoreToStg, and backends, if trivial expressions really do -look trivial. #19700 was an example. - -In both cases, the "unsafe-co" is just (UnivCo ty1 ty2 (CorePrepProv b)), -The boolean 'b' says whether the unsafe coercion is supposed to be -kind-homogeneous (yes for (2), no for (1). This information is used -/only/ by Lint. - Note [CorePrep invariants] ~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is the syntax of the Core produced by CorePrep: @@ -785,10 +737,10 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) -- For example -- f (g x) ===> ([v = g x], f v) -cpeRhsE env (Type ty) - = return (emptyFloats, Type (cpSubstTy env ty)) -cpeRhsE env (Coercion co) - = return (emptyFloats, Coercion (cpSubstCo env co)) +cpeRhsE _ (Type ty) + = return (emptyFloats, Type ty) +cpeRhsE _ (Coercion co) + = return (emptyFloats, Coercion co) cpeRhsE env expr@(Lit (LitNumber nt i)) = case cp_convertNumLit (cpe_config env) nt i of Nothing -> return (emptyFloats, expr) @@ -822,7 +774,7 @@ cpeRhsE env (Tick tickish expr) cpeRhsE env (Cast expr co) = do { (floats, expr') <- cpeRhsE env expr - ; return (floats, Cast expr' (cpSubstCo env co)) } + ; return (floats, Cast expr' co) } cpeRhsE env expr@(Lam {}) = do { let (bndrs,body) = collectBinders expr @@ -830,36 +782,6 @@ cpeRhsE env expr@(Lam {}) ; body' <- cpeBodyNF env' body ; return (emptyFloats, mkLams bndrs' body') } --- Eliminate empty case --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut _ ty []) - = do { (floats, scrut') <- cpeRhsE env scrut - ; let ty' = cpSubstTy env ty - scrut_ty' = exprType scrut' - co' = mkUnivCo prov Representational scrut_ty' ty' - prov = CorePrepProv False - -- False says that the kinds of two types may differ - -- E.g. we might cast Int to Int#. This is fine - -- because the scrutinee is guaranteed to diverge - - ; return (floats, Cast scrut' co') } - -- This can give rise to - -- Warning: Unsafe coercion: between unboxed and boxed value - -- but it's fine because 'scrut' diverges - --- Eliminate unsafeEqualityProof --- See Note [Unsafe coercions] -cpeRhsE env (Case scrut bndr _ alts) - | isUnsafeEqualityProof scrut - , isDeadBinder bndr -- We can only discard the case if the case-binder - -- is dead. It usually is, but see #18227 - , [Alt _ [co_var] rhs] <- alts - , let Pair ty1 ty2 = coVarTypes co_var - the_co = mkUnivCo prov Nominal (cpSubstTy env ty1) (cpSubstTy env ty2) - prov = CorePrepProv True -- True <=> kind homogeneous - env' = extendCoVarEnv env co_var the_co - = cpeRhsE env' rhs - cpeRhsE env (Case scrut bndr ty alts) = do { (floats, scrut') <- cpeBody env scrut ; (env', bndr2) <- cpCloneBndr env bndr @@ -1205,14 +1127,10 @@ cpeApp top_env expr in rebuild_app' env (a : as) tick_fun floats ss rt_ticks req_depth CpeApp (Type arg_ty) - -> rebuild_app' env as (App fun' (Type arg_ty')) floats ss rt_ticks req_depth - where - arg_ty' = cpSubstTy env arg_ty + -> rebuild_app' env as (App fun' (Type arg_ty)) floats ss rt_ticks req_depth CpeApp (Coercion co) - -> rebuild_app' env as (App fun' (Coercion co')) floats (drop 1 ss) rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (App fun' (Coercion co)) floats (drop 1 ss) rt_ticks req_depth CpeApp arg -> do let (ss1, ss_rest) -- See Note [lazyId magic] in GHC.Types.Id.Make @@ -1224,9 +1142,7 @@ cpeApp top_env expr rebuild_app' env as (App fun' arg') (fs `appendFloats` floats) ss_rest rt_ticks (req_depth-1) CpeCast co - -> rebuild_app' env as (Cast fun' co') floats ss rt_ticks req_depth - where - co' = cpSubstCo env co + -> rebuild_app' env as (Cast fun' co) floats ss rt_ticks req_depth -- See Note [Ticks and mandatory eta expansion] CpeTick tickish | tickishPlace tickish == PlaceRuntime @@ -1497,11 +1413,32 @@ cpeArg env dmd arg ; if exprIsTrivial arg2 then return (floats2, arg2) else do { v <- newVar arg_ty - ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 + -- See Note [Eta expansion of arguments in CorePrep] + ; let arity | Just ao <- cp_arityOpts (cpe_config env) -- Just <=> -O2 + , not (is_join_head arg2) + -- See Note [Eta expansion for join points] + -- Eta expanding the join point would + -- introduce crap that we can't generate + -- code for + = case exprEtaExpandArity ao arg2 of + Nothing -> 0 + Just at -> arityTypeArity at + | otherwise + = exprArity arg2 -- this is cheap enough for -O0 and -O1 + arg3 = cpeEtaExpand arity arg2 arg_float = mkFloat env dmd is_unlifted v arg3 ; return (addFloat floats2 arg_float, varToCoreExpr v) } } +is_join_head :: CoreExpr -> Bool +-- ^ Identify the cases where our mishandling described in +-- Note [Eta expansion for join points] would generate crap +is_join_head (Let bs e) = isJoinBind bs || is_join_head e +is_join_head (Cast e _) = is_join_head e +is_join_head (Tick _ e) = is_join_head e +is_join_head (Case _ _ _ alts) = any is_join_head (rhssOfAlts alts) +is_join_head _ = False + {- Note [Floating unlifted arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1619,6 +1556,44 @@ and now we do NOT want eta expansion to give Instead GHC.Core.Opt.Arity.etaExpand gives f = /\a -> \y -> let s = h 3 in g s y +Note [Eta expansion of arguments in CorePrep] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to + + let t = g x + in f t + +We really don't want that `t` to be a thunk! That just wastes runtime, updating +a thunk with a PAP etc. The code generator could in principle allocate a PAP, +but in fact it does not know how to do that -- it's easier just to eta-expand: + + let t = \y. g x y + in f t + +To what arity should we eta-expand the argument? `cpeArg` uses two strategies, +governed by the presence of `-fdo-clever-arg-eta-expansion` (implied by -O): + + 1. Cheap, with -O0: just use `exprArity`. + 2. More clever but expensive, with -O1 -O2: use `exprEtaExpandArity`, + same function the Simplifier uses to eta expand RHSs and lambda bodies. + +The only reason for using (1) rather than (2) is to keep compile times down. +Using (2) in -O0 bumped up compiler allocations by 2-3% in tests T4801 and +T5321*. However, Plan (2) catches cases that (1) misses. +For example (#23083, assuming -fno-pedantic-bottoms): + + let t = case z of __DEFAULT -> g x + in f t + +to + + let t = \y -> case z of __DEFAULT -> g x y + in f t + +Note that there is a missed opportunity in eta expanding `t` earlier, in the +Simplifier: It would allow us to inline `g`, potentially enabling further +simplification. But then we could have inlined `g` into the PAP to begin with, +and that is discussed in #23150; hence we needn't worry about that in CorePrep. -} cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs @@ -1982,6 +1957,11 @@ data CorePrepConfig = CorePrepConfig , cp_convertNumLit :: !(LitNumType -> Integer -> Maybe CoreExpr) -- ^ Convert some numeric literals (Integer, Natural) into their final -- Core form. + + , cp_arityOpts :: !(Maybe ArityOpts) + -- ^ Configuration for arity analysis ('exprEtaExpandArity'). + -- See Note [Eta expansion of arguments in CorePrep] + -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead } data CorePrepEnv @@ -1992,6 +1972,7 @@ data CorePrepEnv -- enabled we instead produce an 'error' expression to catch -- the case where a function we think should bottom -- unexpectedly returns. + , cpe_env :: IdEnv CoreExpr -- Clone local Ids -- ^ This environment is used for three operations: -- @@ -2005,8 +1986,6 @@ data CorePrepEnv -- see Note [lazyId magic], Note [Inlining in CorePrep] -- and Note [CorePrep inlines trivial CoreExpr not Id] (#12076) - , cpe_tyco_env :: Maybe CpeTyCoEnv -- See Note [CpeTyCoEnv] - , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] } @@ -2014,7 +1993,6 @@ mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg , cpe_env = emptyVarEnv - , cpe_tyco_env = Nothing , cpe_rec_ids = emptyUnVarSet } @@ -2041,117 +2019,6 @@ enterRecGroupRHSs :: CorePrepEnv -> [OutId] -> CorePrepEnv enterRecGroupRHSs env grp = env { cpe_rec_ids = extendUnVarSetList grp (cpe_rec_ids env) } ------------------------------------------------------------------------------- --- CpeTyCoEnv --- --------------------------------------------------------------------------- - -{- Note [CpeTyCoEnv] -~~~~~~~~~~~~~~~~~~~~ -The cpe_tyco_env :: Maybe CpeTyCoEnv field carries a substitution -for type and coercion variables - -* We need the coercion substitution to support the elimination of - unsafeEqualityProof (see Note [Unsafe coercions]) - -* We need the type substitution in case one of those unsafe - coercions occurs in the kind of tyvar binder (sigh) - -We don't need an in-scope set because we don't clone any of these -binders at all, so no new capture can take place. - -The cpe_tyco_env is almost always empty -- it only gets populated -when we get under an usafeEqualityProof. Hence the Maybe CpeTyCoEnv, -which makes everything into a no-op in the common case. --} - -data CpeTyCoEnv = TCE TvSubstEnv CvSubstEnv - -emptyTCE :: CpeTyCoEnv -emptyTCE = TCE emptyTvSubstEnv emptyCvSubstEnv - -extend_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -> CpeTyCoEnv -extend_tce_cv (TCE tv_env cv_env) cv co - = TCE tv_env (extendVarEnv cv_env cv co) - -extend_tce_tv :: CpeTyCoEnv -> TyVar -> Type -> CpeTyCoEnv -extend_tce_tv (TCE tv_env cv_env) tv ty - = TCE (extendVarEnv tv_env tv ty) cv_env - -lookup_tce_cv :: CpeTyCoEnv -> CoVar -> Coercion -lookup_tce_cv (TCE _ cv_env) cv - = case lookupVarEnv cv_env cv of - Just co -> co - Nothing -> mkCoVarCo cv - -lookup_tce_tv :: CpeTyCoEnv -> TyVar -> Type -lookup_tce_tv (TCE tv_env _) tv - = case lookupVarEnv tv_env tv of - Just ty -> ty - Nothing -> mkTyVarTy tv - -extendCoVarEnv :: CorePrepEnv -> CoVar -> Coercion -> CorePrepEnv -extendCoVarEnv cpe@(CPE { cpe_tyco_env = mb_tce }) cv co - = cpe { cpe_tyco_env = Just (extend_tce_cv tce cv co) } - where - tce = mb_tce `orElse` emptyTCE - - -cpSubstTy :: CorePrepEnv -> Type -> Type -cpSubstTy (CPE { cpe_tyco_env = mb_env }) ty - = case mb_env of - Just env -> runIdentity (subst_ty env ty) - Nothing -> ty - -cpSubstCo :: CorePrepEnv -> Coercion -> Coercion -cpSubstCo (CPE { cpe_tyco_env = mb_env }) co - = case mb_env of - Just tce -> runIdentity (subst_co tce co) - Nothing -> co - -subst_tyco_mapper :: TyCoMapper CpeTyCoEnv Identity -subst_tyco_mapper = TyCoMapper - { tcm_tyvar = \env tv -> return (lookup_tce_tv env tv) - , tcm_covar = \env cv -> return (lookup_tce_cv env cv) - , tcm_hole = \_ hole -> pprPanic "subst_co_mapper:hole" (ppr hole) - , tcm_tycobinder = \env tcv _vis -> if isTyVar tcv - then return (subst_tv_bndr env tcv) - else return (subst_cv_bndr env tcv) - , tcm_tycon = \tc -> return tc } - -subst_ty :: CpeTyCoEnv -> Type -> Identity Type -subst_co :: CpeTyCoEnv -> Coercion -> Identity Coercion -(subst_ty, _, subst_co, _) = mapTyCoX subst_tyco_mapper - -cpSubstTyVarBndr :: CorePrepEnv -> TyVar -> (CorePrepEnv, TyVar) -cpSubstTyVarBndr env@(CPE { cpe_tyco_env = mb_env }) tv - = case mb_env of - Nothing -> (env, tv) - Just tce -> (env { cpe_tyco_env = Just tce' }, tv') - where - (tce', tv') = subst_tv_bndr tce tv - -subst_tv_bndr :: CpeTyCoEnv -> TyVar -> (CpeTyCoEnv, TyVar) -subst_tv_bndr tce tv - = (extend_tce_tv tce tv (mkTyVarTy tv'), tv') - where - tv' = mkTyVar (tyVarName tv) kind' - kind' = runIdentity $ subst_ty tce $ tyVarKind tv - -cpSubstCoVarBndr :: CorePrepEnv -> CoVar -> (CorePrepEnv, CoVar) -cpSubstCoVarBndr env@(CPE { cpe_tyco_env = mb_env }) cv - = case mb_env of - Nothing -> (env, cv) - Just tce -> (env { cpe_tyco_env = Just tce' }, cv') - where - (tce', cv') = subst_cv_bndr tce cv - -subst_cv_bndr :: CpeTyCoEnv -> CoVar -> (CpeTyCoEnv, CoVar) -subst_cv_bndr tce cv - = (extend_tce_cv tce cv (mkCoVarCo cv'), cv') - where - cv' = mkCoVar (varName cv) ty' - ty' = runIdentity (subst_ty tce $ varType cv) - ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2161,12 +2028,8 @@ cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar) cpCloneBndr env bndr - | isTyVar bndr - = return (cpSubstTyVarBndr env bndr) - - | isCoVar bndr - = return (cpSubstCoVarBndr env bndr) - + | isTyCoVar bndr + = return (env, bndr) | otherwise = do { bndr' <- clone_it bndr @@ -2186,8 +2049,7 @@ cpCloneBndr env bndr clone_it bndr | isLocalId bndr = do { uniq <- getUniqueM - ; let ty' = cpSubstTy env (idType bndr) - ; return (setVarUnique (setIdType bndr ty') uniq) } + ; return (setVarUnique bndr uniq) } | otherwise -- Top level things, which we don't want -- to clone, have become GlobalIds by now ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -9,6 +9,7 @@ import GHC.Core.Opt.Pipeline.Types ( CoreToDo(..) ) import GHC.Driver.Env import GHC.Driver.Session import GHC.Driver.Config.Core.Lint +import GHC.Driver.Config.Core.Opt.Arity import GHC.Tc.Utils.Env import GHC.Types.Var import GHC.Utils.Outputable ( alwaysQualify ) @@ -17,14 +18,18 @@ import GHC.CoreToStg.Prep initCorePrepConfig :: HscEnv -> IO CorePrepConfig initCorePrepConfig hsc_env = do + let dflags = hsc_dflags hsc_env convertNumLit <- do - let platform = targetPlatform $ hsc_dflags hsc_env + let platform = targetPlatform dflags home_unit = hsc_home_unit hsc_env lookup_global = lookupGlobal hsc_env mkConvertNumLiteral platform home_unit lookup_global return $ CorePrepConfig - { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases $ hsc_dflags hsc_env + { cp_catchNonexhaustiveCases = gopt Opt_CatchNonexhaustiveCases dflags , cp_convertNumLit = convertNumLit + , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags + then Just (initArityOpts dflags) + else Nothing } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -262,6 +262,7 @@ data GeneralFlag | Opt_SpecConstr | Opt_SpecConstrKeen | Opt_DoLambdaEtaExpansion + | Opt_DoCleverArgEtaExpansion -- More sophisticated eta expansion of arguments in CorePrep | Opt_IgnoreAsserts | Opt_DoEtaReduction | Opt_CaseMerge ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3467,6 +3467,7 @@ fFlagsDeps = [ Opt_DmdTxDictSel "effect is now unconditionally enabled", flagSpec "do-eta-reduction" Opt_DoEtaReduction, flagSpec "do-lambda-eta-expansion" Opt_DoLambdaEtaExpansion, + flagSpec "do-clever-arg-eta-expansion" Opt_DoCleverArgEtaExpansion, flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "embed-manifest" Opt_EmbedManifest, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, @@ -4059,6 +4060,7 @@ optLevelFlags :: [([Int], GeneralFlag)] -- Default settings of flags, before any command-line overrides optLevelFlags -- see Note [Documenting optimisation flags] = [ ([0,1,2], Opt_DoLambdaEtaExpansion) + , ([1,2], Opt_DoCleverArgEtaExpansion) , ([0,1,2], Opt_DoEtaReduction) -- See Note [Eta-reduction in -O0] , ([0,1,2], Opt_LlvmTBAA) , ([0,1,2], Opt_ProfManualCcs ) ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -1748,7 +1748,6 @@ freeNamesIfProv :: IfaceUnivCoProv -> NameSet freeNamesIfProv (IfacePhantomProv co) = freeNamesIfCoercion co freeNamesIfProv (IfaceProofIrrelProv co) = freeNamesIfCoercion co freeNamesIfProv (IfacePluginProv _) = emptyNameSet -freeNamesIfProv (IfaceCorePrepProv _) = emptyNameSet freeNamesIfVarBndr :: VarBndr IfaceBndr vis -> NameSet freeNamesIfVarBndr (Bndr bndr _) = freeNamesIfBndr bndr ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -402,7 +402,6 @@ data IfaceUnivCoProv = IfacePhantomProv IfaceCoercion | IfaceProofIrrelProv IfaceCoercion | IfacePluginProv String - | IfaceCorePrepProv Bool -- See defn of CorePrepProv {- Note [Holes in IfaceCoercion] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,7 +623,6 @@ substIfaceType env ty go_prov (IfacePhantomProv co) = IfacePhantomProv (go_co co) go_prov (IfaceProofIrrelProv co) = IfaceProofIrrelProv (go_co co) go_prov co@(IfacePluginProv _) = co - go_prov co@(IfaceCorePrepProv _) = co substIfaceAppArgs :: IfaceTySubst -> IfaceAppArgs -> IfaceAppArgs substIfaceAppArgs env args @@ -1860,8 +1858,6 @@ pprIfaceUnivCoProv (IfaceProofIrrelProv co) = text "irrel" <+> pprParendIfaceCoercion co pprIfaceUnivCoProv (IfacePluginProv s) = text "plugin" <+> doubleQuotes (text s) -pprIfaceUnivCoProv (IfaceCorePrepProv _) - = text "CorePrep" ------------------- instance Outputable IfaceTyCon where @@ -2229,9 +2225,6 @@ instance Binary IfaceUnivCoProv where put_ bh (IfacePluginProv a) = do putByte bh 3 put_ bh a - put_ bh (IfaceCorePrepProv a) = do - putByte bh 4 - put_ bh a get bh = do tag <- getByte bh @@ -2242,8 +2235,6 @@ instance Binary IfaceUnivCoProv where return $ IfaceProofIrrelProv a 3 -> do a <- get bh return $ IfacePluginProv a - 4 -> do a <- get bh - return (IfaceCorePrepProv a) _ -> panic ("get IfaceUnivCoProv " ++ show tag) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -1520,7 +1520,6 @@ tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceCorePrepProv b) = return $ CorePrepProv b {- ************************************************************************ ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -53,7 +53,6 @@ import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Utils.Panic.Plain import Control.Monad ( unless, void ) import Control.Arrow ( first ) @@ -1028,7 +1027,7 @@ cgIdApp fun_id args = do (text "TagCheck failed on entry in" <+> ppr mod <+> text "- value:" <> ppr fun_id <+> pdoc platform fun)) fun - EnterIt -> assert (null args) $ -- Discarding arguments + EnterIt -> assertPpr (null args) (ppr fun_id $$ ppr args) $ -- Discarding arguments emitEnter fun SlowCall -> do -- A slow function call via the RTS apply routines ===================================== compiler/GHC/Tc/TyCl/Utils.hs ===================================== @@ -156,7 +156,6 @@ synonymTyConsOfType ty go_prov (PhantomProv co) = go_co co go_prov (ProofIrrelProv co) = go_co co go_prov (PluginProv _) = emptyNameEnv - go_prov (CorePrepProv _) = emptyNameEnv go_tc tc | isTypeSynonymTyCon tc = unitNameEnv (tyConName tc) tc | otherwise = emptyNameEnv ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -1578,7 +1578,6 @@ collect_cand_qtvs_co orig_ty cur_lvl bound = go_co go_prov dv (PhantomProv co) = go_co dv co go_prov dv (ProofIrrelProv co) = go_co dv co go_prov dv (PluginProv _) = return dv - go_prov dv (CorePrepProv _) = return dv go_cv :: CandidatesQTvs -> CoVar -> TcM CandidatesQTvs go_cv dv@(DV { dv_cvs = cvs }) cv ===================================== compiler/GHC/Utils/Trace.hs ===================================== @@ -8,6 +8,7 @@ module GHC.Utils.Trace , pprSTrace , pprTraceException , warnPprTrace + , warnPprTraceM , pprTraceUserWarning , trace ) @@ -84,6 +85,9 @@ warnPprTrace True s msg x (text s $$ msg $$ withFrozenCallStack traceCallStackDoc ) x +warnPprTraceM :: (Applicative f, HasCallStack) => Bool -> String -> SDoc -> f () +warnPprTraceM b s doc = withFrozenCallStack warnPprTrace b s doc (pure ()) + -- | For when we want to show the user a non-fatal WARNING so that they can -- report a GHC bug, but don't want to panic. pprTraceUserWarning :: HasCallStack => SDoc -> a -> a ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -467,6 +467,17 @@ by saying ``-fno-wombat``. Eta-expand let-bindings to increase their arity. +.. ghc-flag:: -fdo-clever-arg-eta-expansion + :shortdesc: Enable sophisticated argument eta-expansion. Implied by :ghc-flag:`-O2`. + :type: dynamic + :reverse: -fno-do-clever-arg-eta-expansion + :category: + + :default: off + + Eta-expand arguments to increase their arity to avoid allocating unnecessary + thunks for them. + .. ghc-flag:: -feager-blackholing :shortdesc: Turn on :ref:`eager blackholing ` :type: dynamic ===================================== libraries/base/Unsafe/Coerce.hs ===================================== @@ -88,13 +88,13 @@ several ways (U1) unsafeEqualityProof is /never/ inlined. -(U2) In CoreToStg.Prep, we transform +(U2) In CoreToStg, we transform case unsafeEqualityProof of UnsafeRefl g -> blah ==> - blah[unsafe-co/g] + blah - This eliminates the overhead of evaluating the unsafe - equality proof. + This eliminates the overhead of evaluating the unsafe equality proof. + (It follows that the Case is trivial iff `blah` is.) Any /other/ occurrence of unsafeEqualityProof is left alone. For example you could write @@ -131,9 +131,11 @@ several ways Floating the case is OK here, even though it broadens the scope, because we are done with simplification. -(U4) Ditto GHC.Core.Unfold.inlineBoringOk we want to treat - the RHS of unsafeCoerce as very small; see - Note [Inline unsafeCoerce] in that module. +(U4) We regard `case unsafeEqualityProof of UnsafeRefl -> rhs` as trivial iff + `rhs` is. One reason is that we want to treat the RHS of unsafeCoerce as + very small; see Note [Inline unsafeCoerce] in that module. + Another is that we do not want to allocate a thunk in CorePrep when we + wouldn't do so for `rhs`, because we discard the case in CoreToStg anyway. (U5) The definition of unsafeEqualityProof in Unsafe.Coerce looks very strange: ===================================== testsuite/tests/simplCore/should_compile/T23083.hs ===================================== @@ -0,0 +1,10 @@ +module T23083 where + +-- Just ($), but NOINLINE so that we don't inline it eagerly, subverting the +-- test case +($$) :: (a -> b) -> a -> b +($$) f x = f x +{-# NOINLINE ($$) #-} + +g :: ((Integer -> Integer) -> Integer) -> (Integer -> Integer) -> Integer +g f h = f (h `seq` (h $$)) ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -0,0 +1,47 @@ + +==================== CorePrep ==================== +Result size of CorePrep = {terms: 34, types: 34, coercions: 0, joins: 0/1} + +-- RHS size: {terms: 6, types: 5, coercions: 0, joins: 0/0} +(T23083.$$) [InlPrag=NOINLINE] :: forall a b. (a -> b) -> a -> b +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +(T23083.$$) = \ (@a) (@b) (f [Occ=Once1!] :: a -> b) (x [Occ=Once1] :: a) -> f x + +-- RHS size: {terms: 12, types: 12, coercions: 0, joins: 0/1} +T23083.g :: ((GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) -> (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer +[GblId, Arity=2, Str=<1C(1,L)>, Unf=OtherCon []] +T23083.g + = \ (f [Occ=Once1!] :: (GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> GHC.Num.Integer.Integer) (h [Occ=OnceL1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer) -> + let { + sat [Occ=Once1] :: GHC.Num.Integer.Integer -> GHC.Num.Integer.Integer + [LclId] + sat = \ (eta [Occ=Once1] :: GHC.Num.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Num.Integer.Integer @GHC.Num.Integer.Integer h1 eta } } in + f sat + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule3 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule3 = GHC.Types.TrNameS T23083.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=OtherCon []] +T23083.$trModule2 = "T23083"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule1 :: GHC.Types.TrName +[GblId, Unf=OtherCon []] +T23083.$trModule1 = GHC.Types.TrNameS T23083.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T23083.$trModule :: GHC.Types.Module +[GblId, Unf=OtherCon []] +T23083.$trModule = GHC.Types.Module T23083.$trModule3 T23083.$trModule1 + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -477,3 +477,4 @@ test('T23012', normal, compile, ['-O']) test('RewriteHigherOrderPatterns', normal, compile, ['-O -ddump-rule-rewrites -dsuppress-all -dsuppress-uniques']) test('T23024', normal, multimod_compile, ['T23024', '-O -v0']) test('T23026', normal, compile, ['-O']) +test('T23083', [ grep_errmsg(r'eta.+::.+Integer') ], compile, ['-O -ddump-prep -dsuppress-uniques -dppr-cols=99999']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17b0d150ceb7b22bc28593fea40fa8188ecc2138...cd7b0b2a9519eae24c2973d28dacc108e5a17968 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/17b0d150ceb7b22bc28593fea40fa8188ecc2138...cd7b0b2a9519eae24c2973d28dacc108e5a17968 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 11:06:30 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 07:06:30 -0400 Subject: [Git][ghc/ghc][wip/T23146] Make LFInfos for DataCons on construction Message-ID: <644ba8b6f3c0f_178e7410bde805820908f@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 1e173d64 by Rodrigo Mesquita at 2023-04-28T12:00:55+01:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 3 changed files: - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -96,6 +96,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc +import GHC.Data.Maybe (isNothing) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -255,130 +256,65 @@ mkApLFInfo id upd_flag arity (mightBeFunTy (idType id)) ------------- +-- | Make a 'LambdaFormInfo' for an imported Id. +-- See Note [The LFInfo of Imported Ids] mkLFImported :: Id -> LambdaFormInfo mkLFImported id = -- See Note [Conveying CAF-info and LFInfo between modules] in -- GHC.StgToCmm.Types case idLFInfo_maybe id of Just lf_info -> - -- Use the LambdaFormInfo from the interface + -- Use the existing LambdaFormInfo lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. - -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + -- Doesn't have a LambdaFormInfo, but we know it must be 'LFReEntrant' from its arity | arity > 0 -> LFReEntrant TopLevel arity True ArgUnknown - | Just con <- isDataConId_maybe id - -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types - -- and Note [The LFInfo of Imported Ids] below - -> assert (hasNoNonZeroWidthArgs con) $ - LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - + -- We can't be sure of the LambdaFormInfo of this imported Id, + -- so make a conservative one from the type. | otherwise - -> mkLFArgument id -- Not sure of exact arity + -> assert (isNothing (isDataConId_maybe id)) $ -- See Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make + mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As explained in Note [Conveying CAF-info and LFInfo between modules] and -Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the -LambdaFormInfo records the details of a closure representation and is often, -when optimisations are enabled, serialized to the interface of a module. - -In particular, the `lfInfo` field of the `IdInfo` field of an `Id` -* For Ids defined in this module: is `Nothing` -* For imported Ids: +As explained in Note [Conveying CAF-info and LFInfo between modules] +the LambdaFormInfo records the details of a closure representation and is +often, when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id`: +* For DataCon workers and wrappers is populated as described in +Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make +* For other Ids defined in this module: is `Nothing` +* For other imported Ids: * is (Just lf_info) if the LFInfo was serialised into the interface file (typically, when the exporting module was compiled with -O) * is Nothing if it wasn't serialised -However, when an interface doesn't have a LambdaFormInfo for some imported Id -(so that its `lfInfo` field is `Nothing`), we can conservatively create one -using `mkLFImported`. - The LambdaFormInfo we give an Id is used in determining how to tag its pointer -(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as -faithfully as possible or otherwise risk having pointers incorrectly tagged, -which can lead to performance issues and even segmentation faults (see #23231 -and #23146). In particular, saturated data constructor applications *must* be -unambiguously given `LFCon`, and the invariant - - If the LFInfo (serialised or built with mkLFImported) says LFCon, then it - really is a static data constructor, and similar for LFReEntrant - -must be upheld. - -In `mkLFImported`, we make a conservative approximation to the real -LambdaFormInfo as follows: - -(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are -tagged (by `litIdInfo`) with the corresponding arity. - - This is also true of data con wrappers and workers with arity > 0, - regardless of the runtime relevance of the arguments - - For example, `Just :: a -> Maybe a` is given `LFReEntrant` - and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too - -(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because -they are fully saturated data constructor applications and pointers to them -should be tagged with the constructor index. - -(2.1) A datacon *wrapper* with zero arity must be a fully saturated application -of the worker to zero-width arguments only (which are dropped after unarisation) - -(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes -no arguments whatsoever (not even zero-width args) - -To ensure we properly give `LFReEntrant` to data constructors with some arity, -and `LFCon` only to data constructors with zero arity, we must first check for -`arity > 0` and only afterwards `isDataConId` -- the order of the guards in -`mkLFImported` is quite important. - -As an example, consider the following data constructors: - - data T1 a where - TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a - - data T2 a where - TCon2 :: {-# UNPACK #-} !() -> T2 a - - data T3 a where - TCon3 :: T3 '[] - -`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while -the worker has an unlifted equality argument, which is zero-width. - -`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, -while the worker has no arguments. - -`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; -their Core representation: - - $WTCon3 :: T3 '[] - $WTCon3 = TCon3 @[] - - TCon3 :: forall (a :: * -> *). (a ~# []) => T a - TCon3 = /\a. \(co :: a~#[]). TCon3 co - -For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they -both have arity == 1. - -For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 -while the worker is `LFCon` since its arity == 0 - -For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the -worker `LFReEntrant` since its arity == 1 - -One might think we could give *workers* with only zero-width-args the `LFCon` -LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. -However, these workers, albeit rarely used, are unambiguously functions --- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. -See also the discussion in #23158. +(see `litIdInfo`). Therefore, it's crucial we attribute a correct +LambdaFormInfo to imported Ids, or otherwise risk having pointers incorrectly +tagged which can lead to performance issues and even segmentation faults (see +#23231 and #23146). In particular, saturated data constructor applications +*must* be unambiguously given `LFCon`, and if the LFInfo says LFCon, then it +really is a static data constructor, and similar for LFReEntrant. + +In `mkLFImported`, we construct a LambdaFormInfo for imported Ids as follows: + +(1) If the `lfInfo` field contains an LFInfo, we use that LFInfo which is +correct by construction (the invariant being that if it exists, it is correct): + (1.1) Either it was serialised to the interface we're importing the Id from, + (1.2) Or it's a DataCon worker or wrapper and its LFInfo was constructed + according to Note [LFInfo of DataCon workers and wrappers] +(2) When the `lfInfo` field is `Nothing` + (2.1) If the `idFunRepArity` of the Id is known and is greater than 0, then + the Id is unambiguously a function and is given `LFReEntrant`, and pointers + to this Id will be tagged (by `litIdInfo`) with the corresponding arity. + (2.2) Otherwise, we can make a conservative estimate from the type. -} ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -120,7 +120,8 @@ infixl 1 `setRuleInfo`, `setCafInfo`, `setDmdSigInfo`, `setCprSigInfo`, - `setDemandInfo` + `setDemandInfo`, + `setLFInfo` {- ************************************************************************ * * ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -87,6 +87,10 @@ import GHC.Data.FastString import GHC.Data.List.SetOps import Data.List ( zipWith4 ) +-- A bit of a shame we must import these here +import GHC.StgToCmm.Types (LambdaFormInfo(..)) +import GHC.Runtime.Heap.Layout (ArgDescr(ArgUnknown)) + {- ************************************************************************ * * @@ -595,11 +599,15 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + -- See Note [LFInfo of DataCon workers and wrappers] + wkr_lf_info = if wkr_arity == 0 then LFCon data_con else LFReEntrant TopLevel wkr_arity True ArgUnknown + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con @@ -608,6 +616,7 @@ mkDataConWorkId wkr_name data_con `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf + `setLFInfo` (LFReEntrant TopLevel 1 True ArgUnknown) id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys) @@ -618,6 +627,85 @@ mkDataConWorkId wkr_name data_con wrapNewTypeBody tycon res_ty_args (Var id_arg1) {- +Note [LFInfo of DataCon workers and wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As noted in Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure, it's +crucial saturated data con applications are given an LFInfo of `LFCon`. + +Since for data constructors we never serialise the worker and the wrapper (only +the data type declaration), we never serialise their lambda form info either. + +Therefore, when making data constructors workers and wrappers, we construct a +correct LFInfo for them right away. This ensures the critical logic of creating +the correct LFInfo for a DataCon is done once on creation and we assertain that: + + The `lfInfo` field of a DataCon worker or wrapper is always populated with the correct LFInfo. + +which is expected by `mkLFImported`. +NB: The greater invariant being that if an `lfInfo` field is populated, the + LFInfo in it contained is correct + +How do we construct a /correct/ LFInfo for workers and wrappers? + +(1) Data constructors with arity > 0 are unambiguously functions and should be +given `LFReEntrant`, regardless of the runtime relevance of the arguments: + - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + +(2) Data constructors with arity == 0 should be given `LFCon` because +they are fully saturated data constructor applications (and pointers to them +should be tagged with the constructor index). + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +For example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +See also the Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +in GHC.StgToCmm.Types. + ------------------------------------------------- -- Data constructor representation -- @@ -709,11 +797,15 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + `setLFInfo` wrap_lf_info -- The signature is purely for passes like the Simplifier, not for -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv + -- See Note [LFInfo of DataCon workers and wrappers] + wrap_lf_info = if wrap_arity == 0 then LFCon data_con else LFReEntrant TopLevel wrap_arity True ArgUnknown + wrap_arg_dmds = replicate (length theta) topDmd ++ map mk_dmd arg_ibangs -- Don't forget the dictionary arguments when building View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e173d6471f12ebe848259bbdbe33ef74a27d5d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e173d6471f12ebe848259bbdbe33ef74a27d5d6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 11:37:01 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 07:37:01 -0400 Subject: [Git][ghc/ghc][wip/T23146] Make LFInfos for DataCons on construction Message-ID: <644bafddae45_178e7410c67cf5c21019be@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 1c02e1d4 by Rodrigo Mesquita at 2023-04-28T12:36:37+01:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 3 changed files: - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -96,6 +96,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc +import GHC.Data.Maybe (isNothing) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -255,130 +256,65 @@ mkApLFInfo id upd_flag arity (mightBeFunTy (idType id)) ------------- +-- | Make a 'LambdaFormInfo' for an imported Id. +-- See Note [The LFInfo of Imported Ids] mkLFImported :: Id -> LambdaFormInfo mkLFImported id = -- See Note [Conveying CAF-info and LFInfo between modules] in -- GHC.StgToCmm.Types case idLFInfo_maybe id of Just lf_info -> - -- Use the LambdaFormInfo from the interface + -- Use the existing LambdaFormInfo lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. - -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + -- Doesn't have a LambdaFormInfo, but we know it must be 'LFReEntrant' from its arity | arity > 0 -> LFReEntrant TopLevel arity True ArgUnknown - | Just con <- isDataConId_maybe id - -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types - -- and Note [The LFInfo of Imported Ids] below - -> assert (hasNoNonZeroWidthArgs con) $ - LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - + -- We can't be sure of the LambdaFormInfo of this imported Id, + -- so make a conservative one from the type. | otherwise - -> mkLFArgument id -- Not sure of exact arity + -> assert (isNothing (isDataConId_maybe id)) $ -- See Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make + mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As explained in Note [Conveying CAF-info and LFInfo between modules] and -Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the -LambdaFormInfo records the details of a closure representation and is often, -when optimisations are enabled, serialized to the interface of a module. - -In particular, the `lfInfo` field of the `IdInfo` field of an `Id` -* For Ids defined in this module: is `Nothing` -* For imported Ids: +As explained in Note [Conveying CAF-info and LFInfo between modules] +the LambdaFormInfo records the details of a closure representation and is +often, when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id`: +* For DataCon workers and wrappers is populated as described in +Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make +* For other Ids defined in this module: is `Nothing` +* For other imported Ids: * is (Just lf_info) if the LFInfo was serialised into the interface file (typically, when the exporting module was compiled with -O) * is Nothing if it wasn't serialised -However, when an interface doesn't have a LambdaFormInfo for some imported Id -(so that its `lfInfo` field is `Nothing`), we can conservatively create one -using `mkLFImported`. - The LambdaFormInfo we give an Id is used in determining how to tag its pointer -(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as -faithfully as possible or otherwise risk having pointers incorrectly tagged, -which can lead to performance issues and even segmentation faults (see #23231 -and #23146). In particular, saturated data constructor applications *must* be -unambiguously given `LFCon`, and the invariant - - If the LFInfo (serialised or built with mkLFImported) says LFCon, then it - really is a static data constructor, and similar for LFReEntrant - -must be upheld. - -In `mkLFImported`, we make a conservative approximation to the real -LambdaFormInfo as follows: - -(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are -tagged (by `litIdInfo`) with the corresponding arity. - - This is also true of data con wrappers and workers with arity > 0, - regardless of the runtime relevance of the arguments - - For example, `Just :: a -> Maybe a` is given `LFReEntrant` - and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too - -(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because -they are fully saturated data constructor applications and pointers to them -should be tagged with the constructor index. - -(2.1) A datacon *wrapper* with zero arity must be a fully saturated application -of the worker to zero-width arguments only (which are dropped after unarisation) - -(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes -no arguments whatsoever (not even zero-width args) - -To ensure we properly give `LFReEntrant` to data constructors with some arity, -and `LFCon` only to data constructors with zero arity, we must first check for -`arity > 0` and only afterwards `isDataConId` -- the order of the guards in -`mkLFImported` is quite important. - -As an example, consider the following data constructors: - - data T1 a where - TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a - - data T2 a where - TCon2 :: {-# UNPACK #-} !() -> T2 a - - data T3 a where - TCon3 :: T3 '[] - -`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while -the worker has an unlifted equality argument, which is zero-width. - -`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, -while the worker has no arguments. - -`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; -their Core representation: - - $WTCon3 :: T3 '[] - $WTCon3 = TCon3 @[] - - TCon3 :: forall (a :: * -> *). (a ~# []) => T a - TCon3 = /\a. \(co :: a~#[]). TCon3 co - -For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they -both have arity == 1. - -For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 -while the worker is `LFCon` since its arity == 0 - -For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the -worker `LFReEntrant` since its arity == 1 - -One might think we could give *workers* with only zero-width-args the `LFCon` -LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. -However, these workers, albeit rarely used, are unambiguously functions --- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. -See also the discussion in #23158. +(see `litIdInfo`). Therefore, it's crucial we attribute a correct +LambdaFormInfo to imported Ids, or otherwise risk having pointers incorrectly +tagged which can lead to performance issues and even segmentation faults (see +#23231 and #23146). In particular, saturated data constructor applications +*must* be unambiguously given `LFCon`, and if the LFInfo says LFCon, then it +really is a static data constructor, and similar for LFReEntrant. + +In `mkLFImported`, we construct a LambdaFormInfo for imported Ids as follows: + +(1) If the `lfInfo` field contains an LFInfo, we use that LFInfo which is +correct by construction (the invariant being that if it exists, it is correct): + (1.1) Either it was serialised to the interface we're importing the Id from, + (1.2) Or it's a DataCon worker or wrapper and its LFInfo was constructed + according to Note [LFInfo of DataCon workers and wrappers] +(2) When the `lfInfo` field is `Nothing` + (2.1) If the `idFunRepArity` of the Id is known and is greater than 0, then + the Id is unambiguously a function and is given `LFReEntrant`, and pointers + to this Id will be tagged (by `litIdInfo`) with the corresponding arity. + (2.2) Otherwise, we can make a conservative estimate from the type. -} ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -120,7 +120,8 @@ infixl 1 `setRuleInfo`, `setCafInfo`, `setDmdSigInfo`, `setCprSigInfo`, - `setDemandInfo` + `setDemandInfo`, + `setLFInfo` {- ************************************************************************ * * ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -87,6 +87,10 @@ import GHC.Data.FastString import GHC.Data.List.SetOps import Data.List ( zipWith4 ) +-- A bit of a shame we must import these here +import GHC.StgToCmm.Types (LambdaFormInfo(..)) +import GHC.Runtime.Heap.Layout (ArgDescr(ArgUnknown)) + {- ************************************************************************ * * @@ -595,11 +599,17 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + -- See Note [LFInfo of DataCon workers and wrappers] + wkr_lf_info + | wkr_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wkr_arity True ArgUnknown + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con @@ -608,6 +618,7 @@ mkDataConWorkId wkr_name data_con `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf + `setLFInfo` (LFReEntrant TopLevel 1 True ArgUnknown) id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys) @@ -618,6 +629,85 @@ mkDataConWorkId wkr_name data_con wrapNewTypeBody tycon res_ty_args (Var id_arg1) {- +Note [LFInfo of DataCon workers and wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As noted in Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure, it's +crucial saturated data con applications are given an LFInfo of `LFCon`. + +Since for data constructors we never serialise the worker and the wrapper (only +the data type declaration), we never serialise their lambda form info either. + +Therefore, when making data constructors workers and wrappers, we construct a +correct LFInfo for them right away. This ensures the critical logic of creating +the correct LFInfo for a DataCon is done once on creation and we assertain that: + + The `lfInfo` field of a DataCon worker or wrapper is always populated with the correct LFInfo. + +which is expected by `mkLFImported`. +NB: The greater invariant being that if an `lfInfo` field is populated, the + LFInfo in it contained is correct + +How do we construct a /correct/ LFInfo for workers and wrappers? + +(1) Data constructors with arity > 0 are unambiguously functions and should be +given `LFReEntrant`, regardless of the runtime relevance of the arguments: + - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + +(2) Data constructors with arity == 0 should be given `LFCon` because +they are fully saturated data constructor applications (and pointers to them +should be tagged with the constructor index). + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +For example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +See also the Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +in GHC.StgToCmm.Types. + ------------------------------------------------- -- Data constructor representation -- @@ -709,11 +799,17 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + `setLFInfo` wrap_lf_info -- The signature is purely for passes like the Simplifier, not for -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv + -- See Note [LFInfo of DataCon workers and wrappers] + wrap_lf_info + | wrap_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wrap_arity True ArgUnknown + wrap_arg_dmds = replicate (length theta) topDmd ++ map mk_dmd arg_ibangs -- Don't forget the dictionary arguments when building View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c02e1d417642ee2ee26db5ed638b1ecbf3c1192 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c02e1d417642ee2ee26db5ed638b1ecbf3c1192 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 11:38:36 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 07:38:36 -0400 Subject: [Git][ghc/ghc][wip/T23146] Make LFInfos for DataCons on construction Message-ID: <644bb03c4dfb_178e7410c74df3021030a7@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: d0fd4454 by Rodrigo Mesquita at 2023-04-28T12:38:25+01:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 3 changed files: - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -96,6 +96,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc +import GHC.Data.Maybe (isNothing) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -255,130 +256,65 @@ mkApLFInfo id upd_flag arity (mightBeFunTy (idType id)) ------------- +-- | Make a 'LambdaFormInfo' for an imported Id. +-- See Note [The LFInfo of Imported Ids] mkLFImported :: Id -> LambdaFormInfo mkLFImported id = -- See Note [Conveying CAF-info and LFInfo between modules] in -- GHC.StgToCmm.Types case idLFInfo_maybe id of Just lf_info -> - -- Use the LambdaFormInfo from the interface + -- Use the existing LambdaFormInfo lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. - -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + -- Doesn't have a LambdaFormInfo, but we know it must be 'LFReEntrant' from its arity | arity > 0 -> LFReEntrant TopLevel arity True ArgUnknown - | Just con <- isDataConId_maybe id - -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types - -- and Note [The LFInfo of Imported Ids] below - -> assert (hasNoNonZeroWidthArgs con) $ - LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - + -- We can't be sure of the LambdaFormInfo of this imported Id, + -- so make a conservative one from the type. | otherwise - -> mkLFArgument id -- Not sure of exact arity + -> assert (isNothing (isDataConId_maybe id)) $ -- See Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make + mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As explained in Note [Conveying CAF-info and LFInfo between modules] and -Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the -LambdaFormInfo records the details of a closure representation and is often, -when optimisations are enabled, serialized to the interface of a module. - -In particular, the `lfInfo` field of the `IdInfo` field of an `Id` -* For Ids defined in this module: is `Nothing` -* For imported Ids: +As explained in Note [Conveying CAF-info and LFInfo between modules] +the LambdaFormInfo records the details of a closure representation and is +often, when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id`: +* For DataCon workers and wrappers is populated as described in +Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make +* For other Ids defined in this module: is `Nothing` +* For other imported Ids: * is (Just lf_info) if the LFInfo was serialised into the interface file (typically, when the exporting module was compiled with -O) * is Nothing if it wasn't serialised -However, when an interface doesn't have a LambdaFormInfo for some imported Id -(so that its `lfInfo` field is `Nothing`), we can conservatively create one -using `mkLFImported`. - The LambdaFormInfo we give an Id is used in determining how to tag its pointer -(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as -faithfully as possible or otherwise risk having pointers incorrectly tagged, -which can lead to performance issues and even segmentation faults (see #23231 -and #23146). In particular, saturated data constructor applications *must* be -unambiguously given `LFCon`, and the invariant - - If the LFInfo (serialised or built with mkLFImported) says LFCon, then it - really is a static data constructor, and similar for LFReEntrant - -must be upheld. - -In `mkLFImported`, we make a conservative approximation to the real -LambdaFormInfo as follows: - -(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are -tagged (by `litIdInfo`) with the corresponding arity. - - This is also true of data con wrappers and workers with arity > 0, - regardless of the runtime relevance of the arguments - - For example, `Just :: a -> Maybe a` is given `LFReEntrant` - and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too - -(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because -they are fully saturated data constructor applications and pointers to them -should be tagged with the constructor index. - -(2.1) A datacon *wrapper* with zero arity must be a fully saturated application -of the worker to zero-width arguments only (which are dropped after unarisation) - -(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes -no arguments whatsoever (not even zero-width args) - -To ensure we properly give `LFReEntrant` to data constructors with some arity, -and `LFCon` only to data constructors with zero arity, we must first check for -`arity > 0` and only afterwards `isDataConId` -- the order of the guards in -`mkLFImported` is quite important. - -As an example, consider the following data constructors: - - data T1 a where - TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a - - data T2 a where - TCon2 :: {-# UNPACK #-} !() -> T2 a - - data T3 a where - TCon3 :: T3 '[] - -`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while -the worker has an unlifted equality argument, which is zero-width. - -`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, -while the worker has no arguments. - -`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; -their Core representation: - - $WTCon3 :: T3 '[] - $WTCon3 = TCon3 @[] - - TCon3 :: forall (a :: * -> *). (a ~# []) => T a - TCon3 = /\a. \(co :: a~#[]). TCon3 co - -For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they -both have arity == 1. - -For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 -while the worker is `LFCon` since its arity == 0 - -For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the -worker `LFReEntrant` since its arity == 1 - -One might think we could give *workers* with only zero-width-args the `LFCon` -LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. -However, these workers, albeit rarely used, are unambiguously functions --- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. -See also the discussion in #23158. +(see `litIdInfo`). Therefore, it's crucial we attribute a correct +LambdaFormInfo to imported Ids, or otherwise risk having pointers incorrectly +tagged which can lead to performance issues and even segmentation faults (see +#23231 and #23146). In particular, saturated data constructor applications +*must* be unambiguously given `LFCon`, and if the LFInfo says LFCon, then it +really is a static data constructor, and similar for LFReEntrant. + +In `mkLFImported`, we construct a LambdaFormInfo for imported Ids as follows: + +(1) If the `lfInfo` field contains an LFInfo, we use that LFInfo which is +correct by construction (the invariant being that if it exists, it is correct): + (1.1) Either it was serialised to the interface we're importing the Id from, + (1.2) Or it's a DataCon worker or wrapper and its LFInfo was constructed + according to Note [LFInfo of DataCon workers and wrappers] +(2) When the `lfInfo` field is `Nothing` + (2.1) If the `idFunRepArity` of the Id is known and is greater than 0, then + the Id is unambiguously a function and is given `LFReEntrant`, and pointers + to this Id will be tagged (by `litIdInfo`) with the corresponding arity. + (2.2) Otherwise, we can make a conservative estimate from the type. -} ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -120,7 +120,8 @@ infixl 1 `setRuleInfo`, `setCafInfo`, `setDmdSigInfo`, `setCprSigInfo`, - `setDemandInfo` + `setDemandInfo`, + `setLFInfo` {- ************************************************************************ * * ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -87,6 +87,10 @@ import GHC.Data.FastString import GHC.Data.List.SetOps import Data.List ( zipWith4 ) +-- A bit of a shame we must import these here +import GHC.StgToCmm.Types (LambdaFormInfo(..)) +import GHC.Runtime.Heap.Layout (ArgDescr(ArgUnknown)) + {- ************************************************************************ * * @@ -595,11 +599,17 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + -- See Note [LFInfo of DataCon workers and wrappers] + wkr_lf_info + | wkr_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wkr_arity True ArgUnknown + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con @@ -608,6 +618,7 @@ mkDataConWorkId wkr_name data_con `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf + `setLFInfo` (LFReEntrant TopLevel 1 True ArgUnknown) id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys) @@ -618,6 +629,85 @@ mkDataConWorkId wkr_name data_con wrapNewTypeBody tycon res_ty_args (Var id_arg1) {- +Note [LFInfo of DataCon workers and wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As noted in Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure, it's +crucial saturated data con applications are given an LFInfo of `LFCon`. + +Since for data constructors we never serialise the worker and the wrapper (only +the data type declaration), we never serialise their lambda form info either. + +Therefore, when making data constructors workers and wrappers, we construct a +correct LFInfo for them right away. This ensures the critical logic of creating +the correct LFInfo for a DataCon is done once on creation and we assertain that: + + The `lfInfo` field of a DataCon worker or wrapper is always populated with the correct LFInfo. + +which is expected by `mkLFImported`. +NB: The greater invariant being that if an `lfInfo` field is populated, the + LFInfo in it contained is correct + +How do we construct a /correct/ LFInfo for workers and wrappers? + +(1) Data constructors with arity > 0 are unambiguously functions and should be +given `LFReEntrant`, regardless of the runtime relevance of the arguments: + - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + +(2) Data constructors with arity == 0 should be given `LFCon` because +they are fully saturated data constructor applications (and pointers to them +should be tagged with the constructor index). + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +For example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +See also the Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +in GHC.StgToCmm.Types. + ------------------------------------------------- -- Data constructor representation -- @@ -709,11 +799,17 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + `setLFInfo` wrap_lf_info -- The signature is purely for passes like the Simplifier, not for -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv + -- See Note [LFInfo of DataCon workers and wrappers] + wrap_lf_info + | wrap_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wrap_arity True ArgUnknown + wrap_arg_dmds = replicate (length theta) topDmd ++ map mk_dmd arg_ibangs -- Don't forget the dictionary arguments when building View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d0fd4454d93aff0d193c37593cb37d4872f4b81c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d0fd4454d93aff0d193c37593cb37d4872f4b81c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 11:58:54 2023 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Fri, 28 Apr 2023 07:58:54 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T23309 Message-ID: <644bb4fe350c5_178e7410cbe69702104117@gitlab.mail> Ryan Scott pushed new branch wip/T23309 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T23309 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 12:06:41 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 28 Apr 2023 08:06:41 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Distinguish hetero-kind coercion holes from others Message-ID: <644bb6d1d972d_178e7410d0babcc2108652@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: fd03125c by Simon Peyton Jones at 2023-04-28T13:06:59+01:00 Distinguish hetero-kind coercion holes from others Fixes LopezJuan test. Hooray - - - - - 8 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Tc/Plugin.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/Unify.hs Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -2739,15 +2739,15 @@ has_co_hole_co :: Coercion -> Monoid.Any folder = TyCoFolder { tcf_view = noView , tcf_tyvar = const2 (Monoid.Any False) , tcf_covar = const2 (Monoid.Any False) - , tcf_hole = const2 (Monoid.Any True) + , tcf_hole = \_ hole -> Monoid.Any (isHeteroKindCoHole hole) , tcf_tycobinder = const2 } --- | Is there a coercion hole in this type? +-- | Is there a hetero-kind coercion hole in this type? hasCoercionHoleTy :: Type -> Bool hasCoercionHoleTy = Monoid.getAny . has_co_hole_ty --- | Is there a coercion hole in this coercion? +-- | Is there a hetero-kind coercion hole in this coercion? hasCoercionHoleCo :: Coercion -> Bool hasCoercionHoleCo = Monoid.getAny . has_co_hole_co ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -38,7 +38,7 @@ module GHC.Core.TyCo.Rep ( -- * Coercions Coercion(..), CoSel(..), FunSel(..), UnivCoProvenance(..), - CoercionHole(..), coHoleCoVar, setCoHoleCoVar, + CoercionHole(..), coHoleCoVar, setCoHoleCoVar, isHeteroKindCoHole, CoercionN, CoercionR, CoercionP, KindCoercion, MCoercion(..), MCoercionR, MCoercionN, @@ -1454,12 +1454,19 @@ data CoercionHole = CoercionHole { ch_co_var :: CoVar -- See Note [CoercionHoles and coercion free variables] - , ch_ref :: IORef (Maybe Coercion) + , ch_ref :: IORef (Maybe Coercion) + + , ch_hetero_kind :: Bool + -- True <=> arises from a kind-level equality + -- ToDo: write a Note } coHoleCoVar :: CoercionHole -> CoVar coHoleCoVar = ch_co_var +isHeteroKindCoHole :: CoercionHole -> Bool +isHeteroKindCoHole = ch_hetero_kind + setCoHoleCoVar :: CoercionHole -> CoVar -> CoercionHole setCoHoleCoVar h cv = h { ch_co_var = cv } @@ -1470,7 +1477,8 @@ instance Data.Data CoercionHole where dataTypeOf _ = mkNoRepType "CoercionHole" instance Outputable CoercionHole where - ppr (CoercionHole { ch_co_var = cv }) = braces (ppr cv) + ppr (CoercionHole { ch_co_var = cv, ch_hetero_kind = hk }) + = braces (ppr cv <> ppWhen hk (text "[hk]")) instance Uniquable CoercionHole where getUnique (CoercionHole { ch_co_var = cv }) = getUnique cv ===================================== compiler/GHC/Tc/Plugin.hs ===================================== @@ -184,7 +184,7 @@ newEvVar = unsafeTcPluginTcM . TcM.newEvVar -- | Create a fresh coercion hole. -- This should only be invoked within 'tcPluginSolve'. newCoercionHole :: PredType -> TcPluginM CoercionHole -newCoercionHole = unsafeTcPluginTcM . TcM.newCoercionHole +newCoercionHole = unsafeTcPluginTcM . TcM.newVanillaCoercionHole -- | Bind an evidence variable. -- ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -1753,7 +1753,7 @@ canEqCanLHSFinish_try_unification ev eq_rel swapped lhs rhs | otherwise -> tryIrredInstead reason ev eq_rel swapped lhs rhs ; - PuOK rhs_redn _ -> + PuOK _ rhs_redn -> -- Success: we can solve by unification do { -- In the common case where rhs_redn is Refl, we don't need to rewrite @@ -1839,7 +1839,7 @@ canEqCanLHSFinish_no_unification ev eq_rel swapped lhs rhs -> tryIrredInstead reason ev eq_rel swapped lhs rhs - PuOK rhs_redn _ + PuOK _ rhs_redn -> do { new_ev <- rewriteEqEvidence emptyRewriterSet ev swapped (mkReflRedn (eqRelRole eq_rel) lhs_ty) rhs_redn ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -1799,7 +1799,7 @@ emitNewWantedEq loc rewriters role ty1 ty2 newWantedEq :: CtLoc -> RewriterSet -> Role -> TcType -> TcType -> TcS (CtEvidence, Coercion) newWantedEq loc rewriters role ty1 ty2 - = do { hole <- wrapTcS $ TcM.newCoercionHole pty + = do { hole <- wrapTcS $ TcM.newCoercionHole loc pty ; traceTcS "Emitting new coercion hole" (ppr hole <+> dcolon <+> ppr pty) ; return ( CtWanted { ctev_pred = pty , ctev_dest = HoleDest hole @@ -2105,7 +2105,7 @@ checkTouchableTyVarEq -> TcType -- The RHS -> TcS (PuResult () Reduction) -- Used for Nominal, Wanted equalities, with a touchable meta-tyvar on LHS --- If checkTouchableTyVarEq tv ty = PuOK redn cts +-- If checkTouchableTyVarEq tv ty = PuOK cts redn -- then we can unify -- tv := ty |> redn -- with extra wanteds 'cts' @@ -2122,7 +2122,7 @@ checkTouchableTyVarEq ev lhs_tv rhs ; traceTcS "checkTouchableTyVarEq }" (ppr lhs_tv $$ ppr check_result) ; case check_result of PuFail reason -> return (PuFail reason) - PuOK redn cts -> do { emitWork cts + PuOK cts redn -> do { emitWork cts ; return (pure redn) } } where @@ -2171,13 +2171,13 @@ checkTouchableTyVarEq ev lhs_tv rhs _ -> TcM.newMetaTyVarTyAtLevel lhs_tv_lvl fam_app_kind ; let pty = mkPrimEqPredRole Nominal fam_app new_tv_ty - ; hole <- TcM.newCoercionHole pty + ; hole <- TcM.newVanillaCoercionHole pty ; let new_ev = CtWanted { ctev_pred = pty , ctev_dest = HoleDest hole , ctev_loc = cb_loc , ctev_rewriters = ctEvRewriters ev } - ; return (PuOK (mkReduction (HoleCo hole) new_tv_ty) - (singleCt (mkNonCanonical new_ev))) } } + ; return (PuOK (singleCt (mkNonCanonical new_ev)) + (mkReduction (HoleCo hole) new_tv_ty)) } } -- See Detail (7) of the Note cb_loc = updateCtLocOrigin (ctEvLoc ev) CycleBreakerOrigin @@ -2195,7 +2195,7 @@ checkTypeEq ev eq_rel lhs rhs ; traceTcS "checkTypeEq }" (ppr check_result) ; case check_result of PuFail reason -> return (PuFail reason) - PuOK redn prs -> do { new_givens <- mapBagM mk_new_given prs + PuOK prs redn -> do { new_givens <- mapBagM mk_new_given prs ; emitWork new_givens ; updInertTcS (addCycleBreakerBindings prs) ; return (pure redn) } } @@ -2204,7 +2204,7 @@ checkTypeEq ev eq_rel lhs rhs = do { check_result <- wrapTcS (checkTyEqRhs wanted_flags rhs) ; case check_result of PuFail reason -> return (PuFail reason) - PuOK redn cts -> do { emitWork cts + PuOK cts redn -> do { emitWork cts ; return (pure redn) } } where check_given_rhs :: TcType -> TcM (PuResult (TcTyVar,TcType) Reduction) @@ -2241,8 +2241,8 @@ checkTypeEq ev eq_rel lhs rhs break_given :: TcType -> TcM (PuResult (TcTyVar,TcType) Reduction) break_given fam_app = do { new_tv <- TcM.newCycleBreakerTyVar (typeKind fam_app) - ; return (PuOK (mkReflRedn Nominal (mkTyVarTy new_tv)) - (unitBag (new_tv, fam_app))) } + ; return (PuOK (unitBag (new_tv, fam_app)) + (mkReflRedn Nominal (mkTyVarTy new_tv))) } -- Why reflexive? See Detail (4) of the Note --------------------------- ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -2414,9 +2414,10 @@ data CtLoc mkKindLoc :: TcType -> TcType -- original *types* being compared -> CtLoc -> CtLoc -mkKindLoc s1 s2 loc = setCtLocOrigin (toKindLoc loc) - (KindEqOrigin s1 s2 (ctLocOrigin loc) - (ctLocTypeOrKind_maybe loc)) +mkKindLoc s1 s2 ctloc + | CtLoc { ctl_t_or_k = t_or_k, ctl_origin = origin } <- ctloc + = ctloc { ctl_origin = KindEqOrigin s1 s2 origin t_or_k + , ctl_t_or_k = Just KindLevel } adjustCtLocTyConBinder :: TyConBinder -> CtLoc -> CtLoc -- Adjust the CtLoc when decomposing a type constructor ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -44,7 +44,8 @@ module GHC.Tc.Utils.TcMType ( newTcEvBinds, newNoTcEvBinds, addTcEvBind, emitNewExprHole, - newCoercionHole, fillCoercionHole, isFilledCoercionHole, + newCoercionHole, newCoercionHoleO, newVanillaCoercionHole, + fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, checkCoercionHole, @@ -199,7 +200,7 @@ newEvVar ty = do { name <- newSysName (predTypeOccName ty) newWantedWithLoc :: CtLoc -> PredType -> TcM CtEvidence newWantedWithLoc loc pty = do dst <- case classifyPredType pty of - EqPred {} -> HoleDest <$> newCoercionHole pty + EqPred {} -> HoleDest <$> newCoercionHole loc pty _ -> EvVarDest <$> newEvVar pty return $ CtWanted { ctev_dest = dst , ctev_pred = pty @@ -224,9 +225,9 @@ newWanteds orig = mapM (newWanted orig Nothing) ---------------------------------------------- cloneWantedCtEv :: CtEvidence -> TcM CtEvidence -cloneWantedCtEv ctev@(CtWanted { ctev_pred = pty, ctev_dest = HoleDest _ }) +cloneWantedCtEv ctev@(CtWanted { ctev_pred = pty, ctev_dest = HoleDest _, ctev_loc = loc }) | isEqPrimPred pty - = do { co_hole <- newCoercionHole pty + = do { co_hole <- newCoercionHole loc pty ; return (ctev { ctev_dest = HoleDest co_hole }) } | otherwise = pprPanic "cloneWantedCtEv" (ppr pty) @@ -274,8 +275,8 @@ emitWantedEqs origin pairs -- | Emits a new equality constraint emitWantedEq :: CtOrigin -> TypeOrKind -> Role -> TcType -> TcType -> TcM Coercion emitWantedEq origin t_or_k role ty1 ty2 - = do { hole <- newCoercionHole pty - ; loc <- getCtLocM origin (Just t_or_k) + = do { hole <- newCoercionHoleO origin pty + ; loc <- getCtLocM origin (Just t_or_k) ; emitSimple $ mkNonCanonical $ CtWanted { ctev_pred = pty , ctev_dest = HoleDest hole @@ -354,12 +355,23 @@ newImplication ************************************************************************ -} -newCoercionHole :: TcPredType -> TcM CoercionHole -newCoercionHole pred_ty +newVanillaCoercionHole :: TcPredType -> TcM CoercionHole +newVanillaCoercionHole = new_coercion_hole False + +newCoercionHole :: CtLoc -> TcPredType -> TcM CoercionHole +newCoercionHole loc = newCoercionHoleO (ctLocOrigin loc) + +newCoercionHoleO :: CtOrigin -> TcPredType -> TcM CoercionHole +newCoercionHoleO (KindEqOrigin {}) = new_coercion_hole True +newCoercionHoleO _ = new_coercion_hole False + +new_coercion_hole :: Bool -> TcPredType -> TcM CoercionHole +new_coercion_hole hetero_kind pred_ty = do { co_var <- newEvVar pred_ty ; traceTc "New coercion hole:" (ppr co_var <+> dcolon <+> ppr pred_ty) ; ref <- newMutVar Nothing - ; return $ CoercionHole { ch_co_var = co_var, ch_ref = ref } } + ; return $ CoercionHole { ch_co_var = co_var, ch_ref = ref + , ch_hetero_kind = hetero_kind } } -- | Put a value in a coercion hole fillCoercionHole :: CoercionHole -> Coercion -> TcM () ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1802,11 +1802,7 @@ mkKindEnv :: UnifyEnv -> TcType -> TcType -> UnifyEnv -- Modify the UnifyEnv to be right for unifing -- the kinds of these two types mkKindEnv env@(UE { u_loc = ctloc }) ty1 ty2 - | CtLoc { ctl_t_or_k = t_or_k, ctl_origin = origin } <- ctloc - , let kind_origin = KindEqOrigin ty1 ty2 origin t_or_k - = env { u_role = Nominal - , u_loc = ctloc { ctl_origin = kind_origin - , ctl_t_or_k = Just KindLevel } } + = env { u_role = Nominal, u_loc = mkKindLoc ty1 ty2 ctloc } uType, uType_defer :: UnifyEnv @@ -1820,7 +1816,7 @@ uType_defer (UE { u_loc = loc, u_defer = ref , u_role = role, u_rewriters = rewriters }) ty1 ty2 -- ty1 is "actual", ty2 is "expected" = do { let pred_ty = mkPrimEqPredRole role ty1 ty2 - ; hole <- newCoercionHole pred_ty + ; hole <- newCoercionHole loc pred_ty ; let ct = mkNonCanonical $ CtWanted { ctev_pred = pred_ty , ctev_dest = HoleDest hole @@ -2631,7 +2627,7 @@ uTypeCheckTouchableTyVarEq lhs_tv rhs ; traceTc "uTypeCheckTouchableTyVarEq }" (ppr check_result) ; case check_result of PuFail reason -> return (PuFail reason) - PuOK redn _ -> assertPpr (isReflCo (reductionCoercion redn)) + PuOK _ redn -> assertPpr (isReflCo (reductionCoercion redn)) (ppr lhs_tv $$ ppr rhs $$ ppr redn) $ return (pure (reductionReducedType redn)) } where @@ -2779,22 +2775,22 @@ reductionCoercion is Refl. See `canEqCanLHSFinish_no_unification`. -} data PuResult a b = PuFail CheckTyEqResult - | PuOK b (Bag a) + | PuOK (Bag a) b instance Functor (PuResult a) where fmap _ (PuFail prob) = PuFail prob - fmap f (PuOK x cts) = PuOK (f x) cts + fmap f (PuOK cts x) = PuOK cts (f x) instance Applicative (PuResult a) where - pure x = PuOK x emptyBag + pure x = PuOK emptyBag x PuFail p1 <*> PuFail p2 = PuFail (p1 S.<> p2) PuFail p1 <*> PuOK {} = PuFail p1 PuOK {} <*> PuFail p2 = PuFail p2 - PuOK f c1 <*> PuOK x c2 = PuOK (f x) (c1 `unionBags` c2) + PuOK c1 f <*> PuOK c2 x = PuOK (c1 `unionBags` c2) (f x) instance (Outputable a, Outputable b) => Outputable (PuResult a b) where ppr (PuFail prob) = text "PuFail" <+> (ppr prob) - ppr (PuOK x cts) = text "PuOK" <> braces + ppr (PuOK cts x) = text "PuOK" <> braces (vcat [ text "redn:" <+> ppr x , text "cts:" <+> ppr cts ]) @@ -2804,7 +2800,7 @@ pprPur (PuFail prob) = text "PuFail:" <> ppr prob pprPur (PuOK {}) = text "PuOK" okCheckRefl :: TcType -> TcM (PuResult a Reduction) -okCheckRefl ty = return (PuOK (mkReflRedn Nominal ty) emptyBag) +okCheckRefl ty = return (PuOK emptyBag (mkReflRedn Nominal ty)) failCheckWith :: CheckTyEqResult -> TcM (PuResult a b) failCheckWith p = return (PuFail p) @@ -2940,7 +2936,7 @@ checkTyEqRhs flags ty checkCo :: TyEqFlags a -> Coercion -> TcM (PuResult a Coercion) -- See Note [checkCo] checkCo (TEF { tef_lhs = TyFamLHS {} }) co - = return (PuOK co emptyBag) + = return (pure co) checkCo (TEF { tef_lhs = TyVarLHS lhs_tv , tef_unifying = unifying @@ -2963,7 +2959,7 @@ checkCo (TEF { tef_lhs = TyVarLHS lhs_tv = failCheckWith (cteProblem occ_prob) | otherwise - = return (PuOK co emptyBag) + = return (pure co) {- Note [checkCo] ~~~~~~~~~~~~~~~~~ @@ -3147,7 +3143,7 @@ checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob TEFA_Break breaker -- Recurse; and break if there is a problem -> do { tys_res <- mapCheck (checkTyEqRhs arg_flags) tys ; case tys_res of - PuOK redns cts -> return (PuOK (mkTyConAppRedn Nominal tc redns) cts) + PuOK cts redns -> return (PuOK cts (mkTyConAppRedn Nominal tc redns)) PuFail {} -> breaker fam_app } where arg_flags = famAppArgFlags flags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd03125c10e2a7d938da69a7d509958db2dbbb2f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd03125c10e2a7d938da69a7d509958db2dbbb2f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 13:36:18 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 09:36:18 -0400 Subject: [Git][ghc/ghc][wip/T23146] Make LFInfos for DataCons on construction Message-ID: <644bcbd2eb8b6_178e7410e76bc0421237c0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/T23146 at Glasgow Haskell Compiler / GHC Commits: 2b0c9002 by Rodrigo Mesquita at 2023-04-28T14:36:06+01:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - 5 changed files: - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -271,8 +271,8 @@ isTagged v = do TagProper -> True TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. - False -- Imported - -> return $! + -- Imported + False -> return $! -- Determine whether it is tagged from the LFInfo of the imported id. -- See Note [The LFInfo of Imported Ids] case mkLFImported v of ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -96,6 +96,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc +import GHC.Data.Maybe (isNothing) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -255,130 +256,65 @@ mkApLFInfo id upd_flag arity (mightBeFunTy (idType id)) ------------- +-- | Make a 'LambdaFormInfo' for an imported Id. +-- See Note [The LFInfo of Imported Ids] mkLFImported :: Id -> LambdaFormInfo mkLFImported id = -- See Note [Conveying CAF-info and LFInfo between modules] in -- GHC.StgToCmm.Types case idLFInfo_maybe id of Just lf_info -> - -- Use the LambdaFormInfo from the interface + -- Use the existing LambdaFormInfo lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, so make a conservative one from the type. - -- See Note [The LFInfo of Imported Ids]; The order of the guards musn't be changed! + -- Doesn't have a LambdaFormInfo, but we know it must be 'LFReEntrant' from its arity | arity > 0 -> LFReEntrant TopLevel arity True ArgUnknown - | Just con <- isDataConId_maybe id - -- See Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] in GHC.StgToCmm.Types - -- and Note [The LFInfo of Imported Ids] below - -> assert (hasNoNonZeroWidthArgs con) $ - LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - + -- We can't be sure of the LambdaFormInfo of this imported Id, + -- so make a conservative one from the type. | otherwise - -> mkLFArgument id -- Not sure of exact arity + -> assert (isNothing (isDataConId_maybe id)) $ -- See Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make + mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id - hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys {- Note [The LFInfo of Imported Ids] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -As explained in Note [Conveying CAF-info and LFInfo between modules] and -Note [Imported unlifted nullary datacon wrappers must have correct LFInfo], the -LambdaFormInfo records the details of a closure representation and is often, -when optimisations are enabled, serialized to the interface of a module. - -In particular, the `lfInfo` field of the `IdInfo` field of an `Id` -* For Ids defined in this module: is `Nothing` -* For imported Ids: +As explained in Note [Conveying CAF-info and LFInfo between modules] +the LambdaFormInfo records the details of a closure representation and is +often, when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id`: +* For DataCon workers and wrappers is populated as described in +Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make +* For other Ids defined in this module: is `Nothing` +* For other imported Ids: * is (Just lf_info) if the LFInfo was serialised into the interface file (typically, when the exporting module was compiled with -O) * is Nothing if it wasn't serialised -However, when an interface doesn't have a LambdaFormInfo for some imported Id -(so that its `lfInfo` field is `Nothing`), we can conservatively create one -using `mkLFImported`. - The LambdaFormInfo we give an Id is used in determining how to tag its pointer -(see `litIdInfo`). Therefore, it's crucial we re-construct a LambdaFormInfo as -faithfully as possible or otherwise risk having pointers incorrectly tagged, -which can lead to performance issues and even segmentation faults (see #23231 -and #23146). In particular, saturated data constructor applications *must* be -unambiguously given `LFCon`, and the invariant - - If the LFInfo (serialised or built with mkLFImported) says LFCon, then it - really is a static data constructor, and similar for LFReEntrant - -must be upheld. - -In `mkLFImported`, we make a conservative approximation to the real -LambdaFormInfo as follows: - -(1) Ids with an `idFunRepArity > 0` are `LFReEntrant` and pointers to them are -tagged (by `litIdInfo`) with the corresponding arity. - - This is also true of data con wrappers and workers with arity > 0, - regardless of the runtime relevance of the arguments - - For example, `Just :: a -> Maybe a` is given `LFReEntrant` - and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too - -(2) Data constructors with `idFunRepArity == 0` should be given `LFCon` because -they are fully saturated data constructor applications and pointers to them -should be tagged with the constructor index. - -(2.1) A datacon *wrapper* with zero arity must be a fully saturated application -of the worker to zero-width arguments only (which are dropped after unarisation) - -(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes -no arguments whatsoever (not even zero-width args) - -To ensure we properly give `LFReEntrant` to data constructors with some arity, -and `LFCon` only to data constructors with zero arity, we must first check for -`arity > 0` and only afterwards `isDataConId` -- the order of the guards in -`mkLFImported` is quite important. - -As an example, consider the following data constructors: - - data T1 a where - TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a - - data T2 a where - TCon2 :: {-# UNPACK #-} !() -> T2 a - - data T3 a where - TCon3 :: T3 '[] - -`TCon1`'s wrapper has a lifted equality argument, which is non-zero-width, while -the worker has an unlifted equality argument, which is zero-width. - -`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, -while the worker has no arguments. - -`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; -their Core representation: - - $WTCon3 :: T3 '[] - $WTCon3 = TCon3 @[] - - TCon3 :: forall (a :: * -> *). (a ~# []) => T a - TCon3 = /\a. \(co :: a~#[]). TCon3 co - -For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they -both have arity == 1. - -For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 -while the worker is `LFCon` since its arity == 0 - -For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the -worker `LFReEntrant` since its arity == 1 - -One might think we could give *workers* with only zero-width-args the `LFCon` -LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. -However, these workers, albeit rarely used, are unambiguously functions --- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. -See also the discussion in #23158. +(see `litIdInfo` and `lfDynTag`). Therefore, it's crucial we attribute a correct +LambdaFormInfo to imported Ids, or otherwise risk having pointers incorrectly +tagged which can lead to performance issues and even segmentation faults (see +#23231 and #23146). In particular, saturated data constructor applications +*must* be unambiguously given `LFCon`, and if the LFInfo says LFCon, then it +really is a static data constructor, and similar for LFReEntrant. + +In `mkLFImported`, we construct a LambdaFormInfo for imported Ids as follows: + +(1) If the `lfInfo` field contains an LFInfo, we use that LFInfo which is +correct by construction (the invariant being that if it exists, it is correct): + (1.1) Either it was serialised to the interface we're importing the Id from, + (1.2) Or it's a DataCon worker or wrapper and its LFInfo was constructed + according to Note [LFInfo of DataCon workers and wrappers] +(2) When the `lfInfo` field is `Nothing` + (2.1) If the `idFunRepArity` of the Id is known and is greater than 0, then + the Id is unambiguously a function and is given `LFReEntrant`, and pointers + to this Id will be tagged (by `litIdInfo`) with the corresponding arity. + (2.2) Otherwise, we can make a conservative estimate from the type. -} ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -109,11 +109,9 @@ pointer to `fieldsSam`. This is problematic as `fieldsSam` may take advantage of the unlifted nature of its arguments by omitting handling of the zero tag when scrutinising them. -The fix is straightforward: extend the logic in `mkLFImported` to cover -(nullary) datacon wrappers as well as workers. This is safe because we -know that the wrapper of a nullary datacon will be in WHNF, even if it -includes equalities evidence (since such equalities are not runtime -relevant). This fixed #23146. +The fix is straightforward: ensure we always construct a /correct/ LFInfo for +datacon workers and wrappers, and populate the `lfInfo` with it. See +Note [LFInfo of DataCon workers and wrappers]. This fixed #23146. See also Note [The LFInfo of Imported Ids] -} ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -120,7 +120,8 @@ infixl 1 `setRuleInfo`, `setCafInfo`, `setDmdSigInfo`, `setCprSigInfo`, - `setDemandInfo` + `setDemandInfo`, + `setLFInfo` {- ************************************************************************ * * @@ -374,7 +375,12 @@ data IdInfo -- -- See documentation of the getters for what these packed fields mean. lfInfo :: !(Maybe LambdaFormInfo), - -- ^ See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure + -- ^ If lfInfo = Just info, then the `info` is guaranteed /correct/. + -- If lfInfo = Nothing, then we do not have a `LambdaFormInfo` for this Id, + -- so (for imported Ids) we make a conservative version. + -- See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure + -- For locally-defined Ids other than DataCons, the `lfInfo` field is always Nothing. + -- See also Note [LFInfo of DataCon workers and wrappers] -- See documentation of the getters for what these packed fields mean. tagSig :: !(Maybe TagSig) ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -87,6 +87,10 @@ import GHC.Data.FastString import GHC.Data.List.SetOps import Data.List ( zipWith4 ) +-- A bit of a shame we must import these here +import GHC.StgToCmm.Types (LambdaFormInfo(..)) +import GHC.Runtime.Heap.Layout (ArgDescr(ArgUnknown)) + {- ************************************************************************ * * @@ -595,11 +599,17 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + -- See Note [LFInfo of DataCon workers and wrappers] + wkr_lf_info + | wkr_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wkr_arity True ArgUnknown + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con @@ -608,6 +618,7 @@ mkDataConWorkId wkr_name data_con `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf + `setLFInfo` (LFReEntrant TopLevel 1 True ArgUnknown) id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys) @@ -618,6 +629,82 @@ mkDataConWorkId wkr_name data_con wrapNewTypeBody tycon res_ty_args (Var id_arg1) {- +Note [LFInfo of DataCon workers and wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As noted in Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure, it's +crucial that saturated data con applications are given an LFInfo of `LFCon`. + +Since for data constructors we never serialise the worker and the wrapper (only +the data type declaration), we never serialise their lambda form info either. + +Therefore, when making data constructors workers and wrappers, we construct a +correct `LFInfo` for them right away, and put it it in the `lfInfo` field of the +worker/wrapper Id, ensuring that: + + The `lfInfo` field of a DataCon worker or wrapper is always populated with the correct LFInfo. + +How do we construct a /correct/ LFInfo for workers and wrappers? +(Remember: `LFCon` means "a saturated constructor application") + +(1) Data constructor workers and wrappers with arity > 0 are unambiguously +functions and should be given `LFReEntrant`, regardless of the runtime +relevance of the arguments. + - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + +(2) A datacon /worker/ with zero arity is trivially fully saturated -- it takes +no arguments whatsoever (not even zero-width args), so it is given `LFCon`. + +(3) Perhaps surprisingly, a datacon /wrapper/ can be an `LFCon`. See Wrinkle (W1) below. +A datacon /wrapper/ with zero arity must be a fully saturated application of +the worker to zero-width arguments only (which are dropped after unarisation), +and therefore is also given `LFCon`. + +For example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +Wrinkle (W1). Perhaps surprisingly, it is possible for the /wrapper/ to be an +`LFCon` even though the /worker/ is not. Consider `T3` above. Here is the +Core representation of the worker and wrapper: + + $WTCon3 :: T3 '[] -- Wrapper + $WTCon3 = TCon3 @[] -- A saturated constructor application: LFCon + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a -- Worker + TCon3 = /\a. \(co :: a~#[]). TCon3 co -- A function: LFReEntrant + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +See also the Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +in GHC.StgToCmm.Types. + ------------------------------------------------- -- Data constructor representation -- @@ -709,11 +796,17 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + `setLFInfo` wrap_lf_info -- The signature is purely for passes like the Simplifier, not for -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv + -- See Note [LFInfo of DataCon workers and wrappers] + wrap_lf_info + | wrap_arity == 0 = LFCon data_con + | otherwise = LFReEntrant TopLevel wrap_arity True ArgUnknown + wrap_arg_dmds = replicate (length theta) topDmd ++ map mk_dmd arg_ibangs -- Don't forget the dictionary arguments when building View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b0c90022c214cb51b148e69c7d8e5f6371d048c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b0c90022c214cb51b148e69c7d8e5f6371d048c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 14:58:31 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 28 Apr 2023 10:58:31 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Wibbles Message-ID: <644bdf1765d00_178e7410fef4ac421310db@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 670a77b4 by Simon Peyton Jones at 2023-04-28T16:00:05+01:00 Wibbles - - - - - 6 changed files: - compiler/GHC/Tc/Errors.hs - testsuite/tests/partial-sigs/should_fail/T14584.stderr - testsuite/tests/partial-sigs/should_fail/T14584a.stderr - testsuite/tests/polykinds/T14846.stderr - testsuite/tests/rep-poly/RepPolyRecordUpdate.stderr - testsuite/tests/typecheck/should_fail/T16204c.stderr Changes: ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1672,8 +1672,8 @@ mkTyVarEqErr' ctxt item (tv1, co1) ty2 return (main_msg, []) -- Incompatible kinds - -- This is wrinkle (4) in Note [Equalities with incompatible kinds] in - -- GHC.Tc.Solver.Canonical + -- This is wrinkle (4) in Note [Equalities with incompatible kinds] + -- in GHC.Tc.Solver.Equality | hasCoercionHoleCo co1 || hasCoercionHoleTy ty2 = return (mkBlockedEqErr item, []) ===================================== testsuite/tests/partial-sigs/should_fail/T14584.stderr ===================================== @@ -1,7 +1,7 @@ T14584.hs:57:41: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)] • Could not deduce ‘SingI a’ arising from a use of ‘sing’ - from the context: (Action act, Monoid a, Good m1) + from the context: (Action act, Monoid a, Good m) bound by the instance declaration at T14584.hs:55:10-89 • In the second argument of ‘fromSing’, namely ‘(sing @m @a :: Sing _)’ @@ -10,23 +10,11 @@ T14584.hs:57:41: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)] In the expression: act @_ @_ @act (fromSing @m (sing @m @a :: Sing _)) -T14584.hs:57:41: warning: [GHC-06200] [-Wdeferred-type-errors (in -Wdefault)] - • Cannot use equality for substitution: a0 ~ a - Doing so would be ill-kinded. - • In the second argument of ‘fromSing’, namely - ‘(sing @m @a :: Sing _)’ - In the fourth argument of ‘act’, namely - ‘(fromSing @m (sing @m @a :: Sing _))’ - In the expression: - act @_ @_ @act (fromSing @m (sing @m @a :: Sing _)) - • Relevant bindings include - monHom :: a -> a (bound at T14584.hs:57:3) - T14584.hs:57:50: warning: [GHC-25897] [-Wdeferred-type-errors (in -Wdefault)] - • Could not deduce ‘m1 ~ *’ - from the context: (Action act, Monoid a, Good m1) + • Could not deduce ‘m ~ *’ + from the context: (Action act, Monoid a, Good m) bound by the instance declaration at T14584.hs:55:10-89 - ‘m1’ is a rigid type variable bound by + ‘m’ is a rigid type variable bound by the instance declaration at T14584.hs:55:10-89 • In the type ‘a’ @@ -36,9 +24,8 @@ T14584.hs:57:50: warning: [GHC-25897] [-Wdeferred-type-errors (in -Wdefault)] ‘(fromSing @m (sing @m @a :: Sing _))’ T14584.hs:57:60: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a0 :: m’ - Where: ‘a0’ is an ambiguous type variable - ‘m’ is a rigid type variable bound by + • Found type wildcard ‘_’ standing for ‘a :: m’ + Where: ‘a’, ‘m’ are rigid type variables bound by the instance declaration at T14584.hs:55:10-89 • In the first argument of ‘Sing’, namely ‘_’ ===================================== testsuite/tests/partial-sigs/should_fail/T14584a.stderr ===================================== @@ -1,7 +1,7 @@ T14584a.hs:12:5: warning: [GHC-83865] [-Wdeferred-type-errors (in -Wdefault)] • Couldn't match expected type ‘()’ with actual type ‘m -> m’ - • Probable cause: ‘id’ is applied to too few arguments + • Probable cause: ‘id @m :: _’ is applied to too few arguments In the expression: id @m :: _ In an equation for ‘f’: f = id @m :: _ @@ -16,7 +16,11 @@ T14584a.hs:12:9: warning: [GHC-25897] [-Wdeferred-type-errors (in -Wdefault)] In an equation for ‘f’: f = id @m :: _ T14584a.hs:12:14: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘()’ + • Found type wildcard ‘_’ standing for ‘m -> m’ + Where: ‘m’, ‘k’ are rigid type variables bound by + the type signature for: + f :: forall {k} (m :: k). () + at T14584a.hs:11:1-17 • In an expression type signature: _ In the expression: id @m :: _ In an equation for ‘f’: f = id @m :: _ ===================================== testsuite/tests/polykinds/T14846.stderr ===================================== @@ -5,8 +5,8 @@ T14846.hs:38:8: error: [GHC-25897] Actual: Hom riki a a ‘ríki’ is a rigid type variable bound by the type signature for: - i :: forall {k4} {k5} {cls2 :: k5 -> Constraint} (xx :: k4) - (a :: Struct cls2) (ríki :: Struct cls2 -> Struct cls2 -> *). + i :: forall {k4} {k5} {cls1 :: k5 -> Constraint} (xx :: k4) + (a :: Struct cls1) (ríki :: Struct cls1 -> Struct cls1 -> *). StructI xx a => ríki a a at T14846.hs:38:8-48 @@ -23,8 +23,8 @@ T14846.hs:38:8: error: [GHC-25897] In the instance declaration for ‘Category (Hom riki)’ T14846.hs:39:44: error: [GHC-25897] - • Couldn't match kind ‘k3’ with ‘Struct cls2’ - Expected kind ‘Struct cls2 -> Constraint’, + • Couldn't match kind ‘k3’ with ‘Struct cls1’ + Expected kind ‘Struct cls1 -> Constraint’, but ‘cls’ has kind ‘k3 -> Constraint’ ‘k3’ is a rigid type variable bound by the instance declaration ===================================== testsuite/tests/rep-poly/RepPolyRecordUpdate.stderr ===================================== @@ -17,7 +17,7 @@ RepPolyRecordUpdate.hs:13:9: error: [GHC-55287] • The record update at field ‘fld’ does not have a fixed runtime representation. Its type is: - a0 :: TYPE rep0 + a :: TYPE rep0 Cannot unify ‘rep’ with the type variable ‘rep0’ because it is not a concrete ‘RuntimeRep’. • In a record update at field ‘fld’, ===================================== testsuite/tests/typecheck/should_fail/T16204c.stderr ===================================== @@ -2,7 +2,7 @@ T16204c.hs:16:8: error: [GHC-83865] • Couldn't match type ‘Rep’ with ‘*’ Expected: Sing @(*) a - Actual: Sing @Rep a0 + Actual: Sing @Rep a • In the first argument of ‘id’, namely ‘sTo’ In the expression: id sTo In an equation for ‘x’: x = id sTo View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/670a77b4302cd6c63ef24ffae29f30e3e49b2425 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/670a77b4302cd6c63ef24ffae29f30e3e49b2425 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 16:02:48 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 12:02:48 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] 3 commits: codeGen: Fix LFInfo of imported datacon wrappers Message-ID: <644bee2875ed7_178e74111026504214186e@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: ba2177fa by Rodrigo Mesquita at 2023-04-26T14:24:05+01:00 codeGen: Fix LFInfo of imported datacon wrappers As noted in #23231 and in the previous commit, we were failing to give a an LFInfo of LFCon to a nullary datacon wrapper from another module, failing to properly tag pointers which ultimately led to the segmentation fault in #23146. On top of the previous commit which now considers wrappers where we previously only considered workers, we change the order of the guards so that we check for the arity of the binding before we check whether it is a constructor. This allows us to (1) Correctly assign `LFReEntrant` to imported wrappers whose worker was nullary, which we previously would fail to do (2) Remove the `isNullaryRepDataCon` predicate: (a) which was previously wrong, since it considered wrappers whose workers had zero-width arguments to be non-nullary and would fail to give `LFCon` to them (b) is now unnecessary, since arity == 0 guarantees - that the worker takes no arguments at all - and the wrapper takes no arguments and its RHS must be an application of the worker to zero-width-args only. - we lint these two items with an assertion that the datacon `hasNoNonZeroWidthArgs` We also update `isTagged` to use the new logic in determining the LFInfos of imported Ids. The creation of LFInfos for imported Ids and this detail are explained in Note [The LFInfo of Imported Ids]. Note that before the patch to those issues we would already consider these nullary wrappers to have `LFCon` lambda form info; but failed to re-construct that information in `mkLFImported` Closes #23231, #23146 (I've additionally batched some fixes to documentation I found while investigating this issue) - - - - - 1e173d64 by Rodrigo Mesquita at 2023-04-28T12:00:55+01:00 Make LFInfos for DataCons on construction As a result of the discussion in !10165, we decided to amend the previous commit which fixed the logic of `mkLFImported` with regard to datacon workers and wrappers. Instead of having the logic for the LFInfo of datacons be in `mkLFImported`, we now construct an LFInfo for all data constructors on GHC.Types.Id.Make and store it in the `lfInfo` field. See the new Note [LFInfo of DataCon workers and wrappers] and ammendments to Note [The LFInfo of Imported Ids] - - - - - e876c74a by Rodrigo Mesquita at 2023-04-28T17:02:08+01:00 Precompute static closures for DataCons with zero-width args Relax the predicate over nullary datacons that determines whether we can return a precomputed static closure for them, such that we give precomputed static closures to both datacon workers and wrappers as long as they only take zero-width arguments (and hence their closure is comprised of just the constructor info). Previously, we would only allow datacons that were nullary with regard to their Core representation, which prevented datacons workers with only zero-width arguments and wrappers with none from using a precomputed static closure. See Note [Precomputed static closures of nullary constructors] Closes #23158 - - - - - 18 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Stg/InferTags/Rewrite.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/DataCon.hs - compiler/GHC/StgToCmm/Env.hs - compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout - + testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs - testsuite/tests/codeGen/should_run/T23146/all.T Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1384,6 +1384,7 @@ For a data constructor (such as Just or Nothing), we have: ordinary Haskell function of arity 1 that allocates a (Just x) box: Just = \x -> Just x + Just_entry: The entry code for the worker function Just_closure: The closure for this worker Nothing_closure: a statically allocated closure for Nothing ===================================== compiler/GHC/Core/DataCon.hs ===================================== @@ -111,8 +111,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -213,7 +213,7 @@ Note [Data constructor workers and wrappers] * The wrapper (if it exists) takes dcOrigArgTys as its arguments. The worker takes dataConRepArgTys as its arguments - If the worker is absent, dataConRepArgTys is the same as dcOrigArgTys + If the wrapper is absent, dataConRepArgTys is the same as dcOrigArgTys * The 'NoDataConRep' case of DataConRep is important. Not only is it efficient, but it also ensures that the wrapper is replaced by the @@ -586,12 +586,22 @@ Function call 'dataConKindEqSpec' returns [k'~k] Note [DataCon arities] ~~~~~~~~~~~~~~~~~~~~~~ -dcSourceArity does not take constraints into account, -but dcRepArity does. For example: +A `DataCon`'s source arity and core representation arity may differ: +`dcSourceArity` does not take constraints into account, but `dcRepArity` does. + +The additional arguments taken into account by `dcRepArity` include quantified +dictionaries and coercion arguments, lifted and unlifted (despite the unlifted +coercion arguments having a zero-width runtime representation). +For example: MkT :: Ord a => a -> T a dcSourceArity = 1 dcRepArity = 2 + MkU :: (b ~ '[]) => U b + dcSourceArity = 0 + dcRepArity = 1 + + Note [DataCon user type variable binders] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A DataCon has two different sets of type variables: @@ -981,7 +991,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1405,10 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of value arguments (including zero-width coercions) +-- stored by the given `DataCon`'s worker in its Core representation. This may +-- differ from the number of arguments that appear in the source code; see also +-- Note [DataCon arities] dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1406,8 +1417,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity isNullarySrcDataCon :: DataCon -> Bool isNullarySrcDataCon dc = dataConSourceArity dc == 0 --- | Return whether there are any argument types for this 'DataCon's runtime representation type --- See Note [DataCon arities] +-- | Return whether this `DataCon`'s worker, in its Core representation, takes +-- any value arguments. +-- +-- In particular, remember that we include coercion arguments in the arity of +-- the Core representation of the `DataCon` -- both lifted and unlifted +-- coercions, despite the latter having zero-width runtime representation. +-- +-- See also Note [DataCon arities]. isNullaryRepDataCon :: DataCon -> Bool isNullaryRepDataCon dc = dataConRepArity dc == 0 ===================================== compiler/GHC/Core/Tidy.hs ===================================== @@ -82,7 +82,7 @@ tidyBind env (Rec prs) -- This means the code generator can get the full calling convention by only looking at the function -- itself without having to inspect the RHS. -- --- The actual logic is in tidyCbvInfo and takes: +-- The actual logic is in computeCbvInfo and takes: -- * The function id -- * The functions rhs -- And gives us back the function annotated with the marks. @@ -169,7 +169,7 @@ computeCbvInfo fun_id rhs -- seqList: avoid retaining the original rhs | otherwise - = -- pprTraceDebug "tidyCbvInfo: Worker seems to take unboxed tuple/sum types!" + = -- pprTraceDebug "computeCbvInfo: Worker seems to take unboxed tuple/sum types!" -- (ppr fun_id <+> ppr rhs) asNonWorkerLikeId fun_id ===================================== compiler/GHC/Stg/InferTags/Rewrite.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Core ( AltCon(..) ) import GHC.Core.Type import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (mkLFImported) import GHC.Stg.Utils import GHC.Stg.Syntax as StgSyn @@ -271,13 +272,10 @@ isTagged v = do TagTagged -> True TagTuple _ -> True -- Consider unboxed tuples tagged. False -- Imported - | Just con <- (isDataConWorkId_maybe v) - , isNullaryRepDataCon con - -> return True - | Just lf_info <- idLFInfo_maybe v -> return $! - -- Can we treat the thing as tagged based on it's LFInfo? - case lf_info of + -- Determine whether it is tagged from the LFInfo of the imported id. + -- See Note [The LFInfo of Imported Ids] + case mkLFImported v of -- Function, applied not entered. LFReEntrant {} -> True @@ -295,9 +293,6 @@ isTagged v = do -- Shouldn't be possible. I don't think we can export letNoEscapes -> True - | otherwise - -> return False - isArgTagged :: StgArg -> RM Bool isArgTagged (StgLitArg _) = return True ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -245,7 +245,7 @@ literals. -- which can't be let-bound | StgConApp DataCon ConstructorNumber - [StgArg] -- Saturated + [StgArg] -- Saturated. (After Unarisation, [NonVoid StgArg]) [Type] -- See Note [Types in StgConApp] in GHC.Stg.Unarise | StgOpApp StgOp -- Primitive op or foreign call ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -956,6 +956,8 @@ ubxSumRubbishArg (VecSlot n e) = StgLitArg (LitRubbish TypeLike vec_rep) -------------------------------------------------------------------------------- {- +Note [Unarisation of Void binders and arguments] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For arguments (StgArg) and binders (Id) we have two kind of unarisation: - When unarising function arg binders and arguments, we don't want to remove ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -239,9 +239,9 @@ cgEnumerationTyCon tycon | con <- tyConDataCons tycon] +-- | Generate the entry code and associated info table for a constructor. +-- Where are generating the static closure at all? cgDataCon :: ConInfoTableLocation -> DataCon -> FCode () --- Generate the entry code, info tables, and (for niladic constructor) --- the static closure, for a constructor. cgDataCon mn data_con = do { massert (not (isUnboxedTupleDataCon data_con || isUnboxedSumDataCon data_con)) ; profile <- getProfile ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -22,7 +22,7 @@ module GHC.StgToCmm.Closure ( argPrimRep, NonVoid(..), fromNonVoid, nonVoidIds, nonVoidStgArgs, - assertNonVoidIds, assertNonVoidStgArgs, + assertNonVoidIds, assertNonVoidStgArgs, hasNoNonZeroWidthArgs, -- * LambdaFormInfo LambdaFormInfo, -- Abstract @@ -96,6 +96,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Panic.Plain import GHC.Utils.Misc +import GHC.Data.Maybe (isNothing) import Data.Coerce (coerce) import qualified Data.ByteString.Char8 as BS8 @@ -170,6 +171,12 @@ assertNonVoidStgArgs :: [StgArg] -> [NonVoid StgArg] assertNonVoidStgArgs args = assert (not (any (isZeroBitTy . stgArgType) args)) $ coerce args +-- | Returns whether there are any arguments with a non-zero-width runtime +-- representation. +-- +-- Returns True if the datacon has no or /just/ zero-width arguments. +hasNoNonZeroWidthArgs :: DataCon -> Bool +hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys ----------------------------------------------------------------------------- -- Representations @@ -255,33 +262,68 @@ mkApLFInfo id upd_flag arity (mightBeFunTy (idType id)) ------------- +-- | Make a 'LambdaFormInfo' for an imported Id. +-- See Note [The LFInfo of Imported Ids] mkLFImported :: Id -> LambdaFormInfo mkLFImported id = -- See Note [Conveying CAF-info and LFInfo between modules] in -- GHC.StgToCmm.Types case idLFInfo_maybe id of Just lf_info -> - -- Use the LambdaFormInfo from the interface + -- Use the existing LambdaFormInfo lf_info Nothing - -- Interface doesn't have a LambdaFormInfo, make a conservative one from - -- the type. - | Just con <- isDataConId_maybe id - , isNullaryRepDataCon con - -- See Note [Imported nullary datacon wrappers must have correct LFInfo] - -- in GHC.StgToCmm.Types - -> LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - + -- Doesn't have a LambdaFormInfo, but we know it must be 'LFReEntrant' from its arity | arity > 0 -> LFReEntrant TopLevel arity True ArgUnknown + -- We can't be sure of the LambdaFormInfo of this imported Id, + -- so make a conservative one from the type. | otherwise - -> mkLFArgument id -- Not sure of exact arity + -> assert (isNothing (isDataConId_maybe id)) $ -- See Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make + mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id +{- +Note [The LFInfo of Imported Ids] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As explained in Note [Conveying CAF-info and LFInfo between modules] +the LambdaFormInfo records the details of a closure representation and is +often, when optimisations are enabled, serialized to the interface of a module. + +In particular, the `lfInfo` field of the `IdInfo` field of an `Id`: +* For DataCon workers and wrappers is populated as described in +Note [LFInfo of DataCon workers and wrappers] in GHC.Types.Id.Make +* For other Ids defined in this module: is `Nothing` +* For other imported Ids: + * is (Just lf_info) if the LFInfo was serialised into the interface file + (typically, when the exporting module was compiled with -O) + * is Nothing if it wasn't serialised + +The LambdaFormInfo we give an Id is used in determining how to tag its pointer +(see `litIdInfo`). Therefore, it's crucial we attribute a correct +LambdaFormInfo to imported Ids, or otherwise risk having pointers incorrectly +tagged which can lead to performance issues and even segmentation faults (see +#23231 and #23146). In particular, saturated data constructor applications +*must* be unambiguously given `LFCon`, and if the LFInfo says LFCon, then it +really is a static data constructor, and similar for LFReEntrant. + +In `mkLFImported`, we construct a LambdaFormInfo for imported Ids as follows: + +(1) If the `lfInfo` field contains an LFInfo, we use that LFInfo which is +correct by construction (the invariant being that if it exists, it is correct): + (1.1) Either it was serialised to the interface we're importing the Id from, + (1.2) Or it's a DataCon worker or wrapper and its LFInfo was constructed + according to Note [LFInfo of DataCon workers and wrappers] +(2) When the `lfInfo` field is `Nothing` + (2.1) If the `idFunRepArity` of the Id is known and is greater than 0, then + the Id is unambiguously a function and is given `LFReEntrant`, and pointers + to this Id will be tagged (by `litIdInfo`) with the corresponding arity. + (2.2) Otherwise, we can make a conservative estimate from the type. + +-} + ------------- mkLFStringLit :: LambdaFormInfo mkLFStringLit = LFUnlifted ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -41,6 +41,7 @@ import GHC.Data.FastString import GHC.Types.Id import GHC.Types.Id.Info( CafInfo( NoCafRefs ) ) import GHC.Types.Name (isInternalName) +import GHC.Types.Var (varName) import GHC.Types.RepType (countConRepArgs) import GHC.Types.Literal import GHC.Builtin.Utils @@ -246,7 +247,8 @@ But also at runtime where the GC does the same (but only for INT/CHAR closures). `precomputedStaticConInfo_maybe` checks if a given constructor application -can be replaced with a reference to a existing static closure. +can be replaced with a reference to a existing static closure, according +to the Note [Precomputed static closures of nullary constructors] If so the code will reference the existing closure when accessing the binding. @@ -317,6 +319,103 @@ This holds for both local and top level bindings. We don't support this optimization when compiling into Windows DLLs yet because they don't support cross package data references well. + +Note [Precomputed static closures of nullary constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We can easily create a precomputed static closure for all data constructors +that don't take runtime-relevant arguments since their closure is always just +the constructor info. + +Instead of allocating a closure with just the constructor info every time it is +used, we can instead use the precomputed static closure! + +For example, to return from a function the constructor `Nothing`, instead of +allocating on the heap a word for `Nothing_con_info` and returning the pointer +to it tagged `+1`, we can simply return `Nothing_closure+1` + +We must consider three distinct situations of saturated applications of +constructors that take no runtime-relevant arguments in which we can use a +precomputed static closure: + +(1) For a data con /worker/ `TCon1` application to no arguments whatsoever we +can trivially use the static closure of the worker, `TCon1_closure`. + Recall that for a worker such as `TCon1`, `TCon1_closure` is just the + `TCon1_con_info`: + section ""data" . M.TCon1_closure" { + M.TCon1_closure: + const M.TCon1_con_info; + } + Invariant: These workers don't have wrappers. + +(2) For a data con /wrapper/ `$WTCon2` that takes no arguments whatsoever, we +can also trivially return the static closure of the wrapper, `$WTCon2_closure`. +It might be surprising to see a nullary data con /wrapper/ -- they come into +existence when the worker only takes zero-width arguments. See the example below. + As in (1), `$WTCon2_closure` simply points to a `TCon2_con_info`. + section ""data" . M.$WTCon2_closure" { + M.$WTCon2_closure: + const M.TCon2_con_info; + } + +(3) For a data con /worker/ `TCon2` that takes zero-width arguments only (and +whose wrapper is `$WTCon2`): because the arguments aren't relevant at runtime, +closures for it still only have the constructor info -- we can use a +precomputed static closure instead of allocating them on the heap, nonetheless. + However, unlike the worker in (1), `TCon2`, in taking arguments (regardless +of runtime representation), is unambiguously a function! Therefore, its +`TCon2_closure` actually contains the info of the function (`TCon2_info`) that returns the +constructor when called -- and as so it must remain -- if `TCon2` is ever used as +a function instead of in a saturated data con application, it better be one. + To generate in place of a saturated data con application of `TCon2`, we would + need something close to: + section ""data" . M.TCon2_some_sort_of_closure" { + M.TCon2_some_sort_of_closure: + const M.TCon2_con_info; -- Must be TCon2_con_info rather than TCon2_info which we have in TCon2_closure + } + But this turns out to be exactly the definition of this worker's wrapper's + static closure (see `$WTCon2_closure`). So, for the kind of worker in (3), + the precomputed static closure is the same as the one for the wrapper. + Invariant: These workers always have a wrapper of type (2) + +The solution that handles all of these cases turns out to be surprisingly +simple: A data con applied to an empty list of non-void arguments has a +precomputed static closure which is the tagged closure label of the var name of +the `dataConWrapId`, both for workers and wrappers. + For (1), `dataConWrapId` will return the Id of the worker because the wrapper + doesn't exist (i.e. `Wrk_closure+tag`). + For (2), `dataConWrapId` will return the Id of the wrapper for the wrapper (i.e. `$Wrp_closure+tag`). + For (3), `dataConWrapId` will return the Id of the wrapper, which must exist (i.e. `$Wrp_closure+tag`). + +As an example, since (2) and (3) might be hard to visualise, consider the datatype: + + data TCon2 a where + TCon2 :: TCon2 () + +and its STG representation post-unarisation: + + G.$WTCon2 :: G.TCon2 () + = G.TCon2! []; + + G.TCon2 :: forall {a}. (a GHC.Prim.~# ()) => G.TCon2 a + = {} \r [void_0E] G.TCon2 []; + +and the C--: + + section ""data" . G.$WTCon2_closure" { + G.$WTCon2_closure: + const G.TCon2_con_info; -- Static constructor info + } + + section ""data" . G.TCon2_closure" { + G.TCon2_closure: + const G.TCon2_info; -- Static function info + } + +The precomputed static closure for `$WTCon2` is `$WTCon2_closure+1`, and the +precomputed static closure for `TCon2` is also `$WTCon2_closure+1`; that is, +all saturated data con applications of `TCon2` and `$WTCon2` are compiled to +`$WTCon2_closure+1` instead of an allocation on the heap and +tagging of its pointer. -} -- (precomputedStaticConInfo_maybe cfg id con args) @@ -326,10 +425,11 @@ because they don't support cross package data references well. -- See Note [Precomputed static closures] precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid StgArg] -> Maybe CgIdInfo precomputedStaticConInfo_maybe cfg binder con [] --- Nullary constructors - | isNullaryRepDataCon con - = Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) - (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) + -- Nullary constructors (list of nonvoid args is null) + -- See Note [Precomputed static closures of nullary constructors] + = assert (hasNoNonZeroWidthArgs con) $ + Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + (CmmLabel (mkClosureLabel (varName $ dataConWrapId con) NoCafRefs)) precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS | intClosure || charClosure ===================================== compiler/GHC/StgToCmm/Env.hs ===================================== @@ -151,7 +151,7 @@ getCgIdInfo id in return $ litIdInfo platform id (mkLFImported id) (CmmLabel ext_lbl) else - cgLookupPanic id -- Bug + cgLookupPanic id -- Bug, id is neither in local binds nor is external }}} -- | Retrieve cg info for a name if it already exists. ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -71,12 +71,13 @@ moving parts are: -fomit-interface-pragmas or -fno-code; and we won't read it in if you have -fignore-interface-pragmas. (We could revisit this decision.) -Note [Imported nullary datacon wrappers must have correct LFInfo] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As described in `Note [Conveying CAF-info and LFInfo between modules]`, -imported nullary datacons must have their LambdaFormInfo set to reflect the -fact that they are evaluated . This is necessary are otherwise references -to them may be passed untagged to code that expects tagged references. +imported unlifted nullary datacons must have their LambdaFormInfo set to +reflect the fact that they are evaluated . This is necessary as otherwise +references to them may be passed untagged to code that expects tagged +references. What may be less obvious is that this must be done for not only datacon workers but also *wrappers*. The reason is found in this program @@ -113,6 +114,8 @@ The fix is straightforward: extend the logic in `mkLFImported` to cover know that the wrapper of a nullary datacon will be in WHNF, even if it includes equalities evidence (since such equalities are not runtime relevant). This fixed #23146. + +See also Note [The LFInfo of Imported Ids] -} -- | Codegen-generated Id infos, to be passed to downstream via interfaces. @@ -161,7 +164,7 @@ data LambdaFormInfo !StandardFormInfo !Bool -- True <=> *might* be a function type - | LFCon -- A saturated constructor application + | LFCon -- A saturated data constructor application !DataCon -- The constructor | LFUnknown -- Used for function arguments and imported things. ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -697,6 +697,8 @@ idCallArity id = callArityInfo (idInfo id) setIdCallArity :: Id -> Arity -> Id setIdCallArity id arity = modifyIdInfo (`setCallArityInfo` arity) id +-- | This function counts all arguments post-unarisation, which includes +-- arguments with no runtime representation -- see Note [Unarisation and arity] idFunRepArity :: Id -> RepArity idFunRepArity x = countFunRepArgs (idArity x) (idType x) ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -120,7 +120,8 @@ infixl 1 `setRuleInfo`, `setCafInfo`, `setDmdSigInfo`, `setCprSigInfo`, - `setDemandInfo` + `setDemandInfo`, + `setLFInfo` {- ************************************************************************ * * @@ -374,6 +375,7 @@ data IdInfo -- -- See documentation of the getters for what these packed fields mean. lfInfo :: !(Maybe LambdaFormInfo), + -- ^ See Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure -- See documentation of the getters for what these packed fields mean. tagSig :: !(Maybe TagSig) @@ -439,7 +441,7 @@ oneShotInfo :: IdInfo -> OneShotInfo oneShotInfo = bitfieldGetOneShotInfo . bitfield -- | 'Id' arity, as computed by "GHC.Core.Opt.Arity". Specifies how many arguments --- this 'Id' has to be applied to before it doesn any meaningful work. +-- this 'Id' has to be applied to before it does any meaningful work. arityInfo :: IdInfo -> ArityInfo arityInfo = bitfieldGetArityInfo . bitfield ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -87,6 +87,10 @@ import GHC.Data.FastString import GHC.Data.List.SetOps import Data.List ( zipWith4 ) +-- A bit of a shame we must import these here +import GHC.StgToCmm.Types (LambdaFormInfo(..)) +import GHC.Runtime.Heap.Layout (ArgDescr(ArgUnknown)) + {- ************************************************************************ * * @@ -595,11 +599,15 @@ mkDataConWorkId wkr_name data_con `setInlinePragInfo` wkr_inline_prag `setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated, -- even if arity = 0 + `setLFInfo` wkr_lf_info -- No strictness: see Note [Data-con worker strictness] in GHC.Core.DataCon wkr_inline_prag = defaultInlinePragma { inl_rule = ConLike } wkr_arity = dataConRepArity data_con + -- See Note [LFInfo of DataCon workers and wrappers] + wkr_lf_info = if wkr_arity == 0 then LFCon data_con else LFReEntrant TopLevel wkr_arity True ArgUnknown + ----------- Workers for newtypes -------------- univ_tvs = dataConUnivTyVars data_con ex_tcvs = dataConExTyCoVars data_con @@ -608,6 +616,7 @@ mkDataConWorkId wkr_name data_con `setArityInfo` 1 -- Arity 1 `setInlinePragInfo` dataConWrapperInlinePragma `setUnfoldingInfo` newtype_unf + `setLFInfo` (LFReEntrant TopLevel 1 True ArgUnknown) id_arg1 = mkScaledTemplateLocal 1 (head arg_tys) res_ty_args = mkTyCoVarTys univ_tvs newtype_unf = assertPpr (null ex_tcvs && isSingleton arg_tys) @@ -618,6 +627,85 @@ mkDataConWorkId wkr_name data_con wrapNewTypeBody tycon res_ty_args (Var id_arg1) {- +Note [LFInfo of DataCon workers and wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +As noted in Note [The LFInfo of Imported Ids] in GHC.StgToCmm.Closure, it's +crucial saturated data con applications are given an LFInfo of `LFCon`. + +Since for data constructors we never serialise the worker and the wrapper (only +the data type declaration), we never serialise their lambda form info either. + +Therefore, when making data constructors workers and wrappers, we construct a +correct LFInfo for them right away. This ensures the critical logic of creating +the correct LFInfo for a DataCon is done once on creation and we assertain that: + + The `lfInfo` field of a DataCon worker or wrapper is always populated with the correct LFInfo. + +which is expected by `mkLFImported`. +NB: The greater invariant being that if an `lfInfo` field is populated, the + LFInfo in it contained is correct + +How do we construct a /correct/ LFInfo for workers and wrappers? + +(1) Data constructors with arity > 0 are unambiguously functions and should be +given `LFReEntrant`, regardless of the runtime relevance of the arguments: + - For example, `Just :: a -> Maybe a` is given `LFReEntrant`, + and `HNil :: (a ~# '[]) -> HList a` is given `LFReEntrant` too. + +(2) Data constructors with arity == 0 should be given `LFCon` because +they are fully saturated data constructor applications (and pointers to them +should be tagged with the constructor index). + +(2.1) A datacon *wrapper* with zero arity must be a fully saturated application +of the worker to zero-width arguments only (which are dropped after unarisation) + +(2.2) A datacon *worker* with zero arity is trivially fully saturated, it takes +no arguments whatsoever (not even zero-width args) + +For example, consider the following data constructors: + + data T1 a where + TCon1 :: {-# UNPACK #-} !(a :~: True) -> T1 a + + data T2 a where + TCon2 :: {-# UNPACK #-} !() -> T2 a + + data T3 a where + TCon3 :: T3 '[] + +`TCon1`'s wrapper has a lifted argument, which is non-zero-width, while +the worker has an unlifted equality argument, which is zero-width. + +`TCon2`'s wrapper has a lifted equality argument, which is non-zero-width, +while the worker has no arguments. + +`TCon3`'s wrapper has no arguments, and the worker has 1 zero-width argument; +their Core representation: + + $WTCon3 :: T3 '[] + $WTCon3 = TCon3 @[] + + TCon3 :: forall (a :: * -> *). (a ~# []) => T a + TCon3 = /\a. \(co :: a~#[]). TCon3 co + +For `TCon1`, both the wrapper and worker will be given `LFReEntrant` since they +both have arity == 1. + +For `TCon2`, the wrapper will be given `LFReEntrant` since it has arity == 1 +while the worker is `LFCon` since its arity == 0 + +For `TCon3`, the wrapper will be given `LFCon` since its arity == 0 and the +worker `LFReEntrant` since its arity == 1 + +One might think we could give *workers* with only zero-width-args the `LFCon` +LambdaFormInfo, e.g. give `LFCon` to the worker of `TCon1` and `TCon3`. +However, these workers, albeit rarely used, are unambiguously functions +-- which makes `LFReEntrant`, the LambdaFormInfo we give them, correct. +See also the discussion in #23158. + +See also the Note [Imported unlifted nullary datacon wrappers must have correct LFInfo] +in GHC.StgToCmm.Types. + ------------------------------------------------- -- Data constructor representation -- @@ -709,11 +797,15 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con -- We need to get the CAF info right here because GHC.Iface.Tidy -- does not tidy the IdInfo of implicit bindings (like the wrapper) -- so it not make sure that the CAF info is sane + `setLFInfo` wrap_lf_info -- The signature is purely for passes like the Simplifier, not for -- DmdAnal itself; see Note [DmdAnal for DataCon wrappers]. wrap_sig = mkClosedDmdSig wrap_arg_dmds topDiv + -- See Note [LFInfo of DataCon workers and wrappers] + wrap_lf_info = if wrap_arity == 0 then LFCon data_con else LFReEntrant TopLevel wrap_arity True ArgUnknown + wrap_arg_dmds = replicate (length theta) topDmd ++ map mk_dmd arg_ibangs -- Don't forget the dictionary arguments when building ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE GADTs, DataKinds #-} + +import T23146_lifted_unliftedA + +import Data.Type.Equality + +fieldsSam :: NP True -> NP True -> Bool +fieldsSam (x' ::* xs) (y' ::* ys) = fieldsSam xs ys +fieldsSam (UNil Refl) (UNil Refl) = True + +main :: IO () +main = print (fieldsSam (UNil Refl) (UNil Refl)) + + ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unlifted.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== testsuite/tests/codeGen/should_run/T23146/T23146_lifted_unliftedA.hs ===================================== @@ -0,0 +1,13 @@ +{-# OPTIONS_GHC -O1 #-} +{-# LANGUAGE DataKinds #-} + +module T23146_lifted_unliftedA where + +import Data.Kind +import Data.Type.Equality + +data NP a where + UNil :: {-# UNPACK #-} !(a :~: True) -> NP a + (::*) :: Bool -> NP True -> NP True + + ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', normal, compile_and_run, ['']) - +test('T23146_lifted_unlifted', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b75b3f37312493ad0acadffe88dc1b38ca8614c8...e876c74a81987a3586d47a18d0f7dae5b8fbe352 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b75b3f37312493ad0acadffe88dc1b38ca8614c8...e876c74a81987a3586d47a18d0f7dae5b8fbe352 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 16:06:14 2023 From: gitlab at gitlab.haskell.org (Sylvain Henry (@hsyl20)) Date: Fri, 28 Apr 2023 12:06:14 -0400 Subject: [Git][ghc/ghc][wip/js-boundsCheck] Split Addr# storage into arr and default array Message-ID: <644beef654223_178e7411128f9582143959@gitlab.mail> Sylvain Henry pushed to branch wip/js-boundsCheck at Glasgow Haskell Compiler / GHC Commits: c92a8f32 by Sylvain Henry at 2023-04-28T18:10:53+02:00 Split Addr# storage into arr and default array Addr# were stored in "arr" sub-array as tuples [array,offset] We change this to store only the array in "arr" and the offset in the default array. - - - - - 9 changed files: - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/StgToJS/Prim.hs - libraries/base/jsbits/base.js - rts/js/environment.js - rts/js/mem.js - rts/js/profiling.js - rts/js/staticpointer.js - rts/js/string.js - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/StgToJS/Linker/Utils.hs ===================================== @@ -138,6 +138,10 @@ genCommonCppDefs profiling = mconcat then "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM))\n" else "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset)))\n" + -- Put Addr# in ByteArray# or at Addr# (same thing) + , "#define PUT_ADDR(a,o,va,vo) if (!(a).arr) (a).arr = []; (a).arr[o] = va; (a).dv.setInt32(o,vo,true);\n" + , "#define GET_ADDR(a,o,ra,ro) var ra = (((a).arr && (a).arr[o]) ? (a).arr[o] : null_); var ro = (a).dv.getInt32(o,true);\n" + -- Data.Maybe.Maybe , "#define HS_NOTHING h$baseZCGHCziMaybeziNothing\n" , "#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e)\n" ===================================== compiler/GHC/StgToJS/Prim.hs ===================================== @@ -29,7 +29,6 @@ import GHC.Utils.Encoding (zEncodeString) import GHC.Data.FastString import GHC.Utils.Outputable (renderWithContext, defaultSDocContext, ppr) -import Data.Maybe genPrim :: Bool -- ^ Profiling (cost-centres) enabled @@ -527,203 +526,187 @@ genPrim prof bound ty op = case op of ------------------------------ Arrays ------------------------------------------- - NewArrayOp -> \[r] [l,e] -> PrimInline (newArray r l e) - ReadArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) - WriteArrayOp -> \[] [a,i,v] -> PrimInline $ boundsChecked bound a i (a .! i |= v) + NewArrayOp -> \[r] [l,e] -> PrimInline $ r |= app "h$newArray" [l,e] + ReadArrayOp -> \[r] [a,i] -> PrimInline $ bnd_arr bound a i (r |= a .! i) + WriteArrayOp -> \[] [a,i,v] -> PrimInline $ bnd_arr bound a i (a .! i |= v) SizeofArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" SizeofMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" - IndexArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) + IndexArrayOp -> \[r] [a,i] -> PrimInline $ bnd_arr bound a i (r |= a .! i) UnsafeFreezeArrayOp -> \[r] [a] -> PrimInline $ r |= a UnsafeThawArrayOp -> \[r] [a] -> PrimInline $ r |= a CopyArrayOp -> \[] [a,o1,ma,o2,n] -> - PrimInline $ loopBlockS (Int 0) (.<. n) \i -> - [ ma .! (Add i o2) |= a .! (Add i o1) - , preIncrS i - ] - CopyMutableArrayOp -> \[] [a1,o1,a2,o2,n] -> PrimInline $ appS "h$copyMutableArray" [a1,o1,a2,o2,n] - CloneArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] - CloneMutableArrayOp -> \[r] [a,start,n] -> genPrim prof bound ty CloneArrayOp [r] [a,start,n] - FreezeArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] - ThawArrayOp -> \[r] [a,start,n] -> PrimInline $ r |= app "h$sliceArray" [a,start,n] - CasArrayOp -> \[s,o] [a,i,old,new] -> PrimInline $ - jVar \x -> mconcat - [ x |= a .! i - , ifBlockS (x .===. old) - [ o |= new - , a .! i |= new - , s |= zero_ - ] - [ s |= one_ - , o |= x - ] - ] + PrimInline + $ bnd_arr_range bound a o1 n + $ bnd_arr_range bound ma o2 n + $ loopBlockS (Int 0) (.<. n) \i -> + [ ma .! (Add i o2) |= a .! (Add i o1) + , preIncrS i + ] + CopyMutableArrayOp -> \[] [a1,o1,a2,o2,n] -> + PrimInline + $ bnd_arr_range bound a1 o1 n + $ bnd_arr_range bound a2 o2 n + $ appS "h$copyMutableArray" [a1,o1,a2,o2,n] + + CloneArrayOp -> \[r] [a,start,n] -> + PrimInline + $ bnd_arr_range bound a start n + $ r |= app "h$sliceArray" [a,start,n] + + CloneMutableArrayOp -> \[r] [a,start,n] -> + PrimInline + $ bnd_arr_range bound a start n + $ r |= app "h$sliceArray" [a,start,n] + + FreezeArrayOp -> \[r] [a,start,n] -> + PrimInline + $ bnd_arr_range bound a start n + $ r |= app "h$sliceArray" [a,start,n] + + ThawArrayOp -> \[r] [a,start,n] -> + PrimInline + $ bnd_arr_range bound a start n + $ r |= app "h$sliceArray" [a,start,n] + + CasArrayOp -> \[s,o] [a,i,old,new] -> + PrimInline + $ bnd_arr bound a i + $ jVar \x -> mconcat + [ x |= a .! i + , ifBlockS (x .===. old) + [ o |= new + , a .! i |= new + , s |= zero_ + ] + [ s |= one_ + , o |= x + ] + ] ------------------------------ Small Arrays ------------------------------------- NewSmallArrayOp -> \[a] [n,e] -> PrimInline $ a |= app "h$newArray" [n,e] - ReadSmallArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) - WriteSmallArrayOp -> \[] [a,i,e] -> PrimInline $ boundsChecked bound a i (a .! i |= e) + ReadSmallArrayOp -> \[r] [a,i] -> PrimInline $ bnd_arr bound a i (r |= a .! i) + WriteSmallArrayOp -> \[] [a,i,e] -> PrimInline $ bnd_arr bound a i (a .! i |= e) SizeofSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" SizeofSmallMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" - IndexSmallArrayOp -> \[r] [a,i] -> PrimInline $ boundsChecked bound a i (r |= a .! i) + IndexSmallArrayOp -> \[r] [a,i] -> PrimInline $ bnd_arr bound a i (r |= a .! i) UnsafeFreezeSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a UnsafeThawSmallArrayOp -> \[r] [a] -> PrimInline $ r |= a - CopySmallArrayOp -> \[] [s,si,d,di,n] -> PrimInline $ - loopBlockS (Sub n one_) (.>=. zero_) \i -> - [ d .! (Add di i) |= s .! (Add si i) - , postDecrS i + CopySmallArrayOp -> \[] [s,si,d,di,n] -> + PrimInline + $ bnd_arr_range bound s si n + $ bnd_arr_range bound d di n + $ loopBlockS (Sub n one_) (.>=. zero_) \i -> + [ d .! (Add di i) |= s .! (Add si i) + , postDecrS i + ] + CopySmallMutableArrayOp -> \[] [s,si,d,di,n] -> + PrimInline + $ bnd_arr_range bound s si n + $ bnd_arr_range bound d di n + $ appS "h$copyMutableArray" [s,si,d,di,n] + + CloneSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray bound r a o n + CloneSmallMutableArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray bound r a o n + FreezeSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray bound r a o n + ThawSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray bound r a o n + + CasSmallArrayOp -> \[s,o] [a,i,old,new] -> + PrimInline + $ bnd_arr bound a i + $ jVar \x -> mconcat + [ x |= a .! i + , ifBlockS (x .===. old) + [ o |= new + , a .! i |= new + , s |= zero_ + ] + [ s |= one_ + , o |= x + ] ] - CopySmallMutableArrayOp -> \[] [s,si,d,di,n] -> PrimInline $ appS "h$copyMutableArray" [s,si,d,di,n] - CloneSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray r a (Just o) n - CloneSmallMutableArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray r a (Just o) n - FreezeSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray r a (Just o) n - ThawSmallArrayOp -> \[r] [a,o,n] -> PrimInline $ cloneArray r a (Just o) n - CasSmallArrayOp -> \[s,o] [a,i,old,new] -> PrimInline $ jVar \x -> mconcat - [ x |= a .! i - , ifBlockS (x .===. old) - [ o |= new - , a .! i |= new - , s |= zero_ - ] - [ s |= one_ - , o |= x - ] - ] ------------------------------- Byte Arrays ------------------------------------- - NewByteArrayOp_Char -> \[r] [l] -> PrimInline (newByteArray r l) - NewPinnedByteArrayOp_Char -> \[r] [l] -> PrimInline (newByteArray r l) - NewAlignedPinnedByteArrayOp_Char -> \[r] [l,_align] -> PrimInline (newByteArray r l) - MutableByteArrayIsPinnedOp -> \[r] [_] -> PrimInline $ r |= one_ - ByteArrayIsPinnedOp -> \[r] [_] -> PrimInline $ r |= one_ - ByteArrayContents_Char -> \[a,o] [b] -> PrimInline $ mconcat [a |= b, o |= zero_] - MutableByteArrayContents_Char -> \[a,o] [b] -> PrimInline $ mconcat [a |= b, o |= zero_] - ShrinkMutableByteArrayOp_Char -> \[] [a,n] -> PrimInline $ appS "h$shrinkMutableByteArray" [a,n] - ResizeMutableByteArrayOp_Char -> \[r] [a,n] -> PrimInline $ r |= app "h$resizeMutableByteArray" [a,n] - UnsafeFreezeByteArrayOp -> \[a] [b] -> PrimInline $ a |= b - SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" - IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i - IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i - IndexByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline . boundsCheckedLen bound a i $ jVar \t -> mconcat - [ t |= a .^ "arr" - , ifBlockS (t .&&. t .! (i .<<. two_)) - [ r1 |= t .! (i .<<. two_) .! zero_ - , r2 |= t .! (i .<<. two_) .! one_ - ] - [ r1 |= null_ - , r2 |= zero_ - ] - ] + NewByteArrayOp_Char -> \[r] [l] -> PrimInline (newByteArray r l) + NewPinnedByteArrayOp_Char -> \[r] [l] -> PrimInline (newByteArray r l) + NewAlignedPinnedByteArrayOp_Char -> \[r] [l,_align] -> PrimInline (newByteArray r l) + MutableByteArrayIsPinnedOp -> \[r] [_] -> PrimInline $ r |= one_ + ByteArrayIsPinnedOp -> \[r] [_] -> PrimInline $ r |= one_ + ByteArrayContents_Char -> \[a,o] [b] -> PrimInline $ mconcat [a |= b, o |= zero_] + MutableByteArrayContents_Char -> \[a,o] [b] -> PrimInline $ mconcat [a |= b, o |= zero_] + ShrinkMutableByteArrayOp_Char -> \[] [a,n] -> PrimInline $ appS "h$shrinkMutableByteArray" [a,n] + ResizeMutableByteArrayOp_Char -> \[r] [a,n] -> PrimInline $ r |= app "h$resizeMutableByteArray" [a,n] + UnsafeFreezeByteArrayOp -> \[a] [b] -> PrimInline $ a |= b + SizeofByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" + SizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" + GetSizeofMutableByteArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "len" + + IndexByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_u8 a i + IndexByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + IndexByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + IndexByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_u32 a i + IndexByteArrayOp_Addr -> \[r,o] [a,i] -> PrimInline $ bnd_ix32 bound a i $ read_addr a i r o + IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_f32 a i + IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ bnd_ix64 bound a i $ r |= read_f64 a i + IndexByteArrayOp_StablePtr -> \[r,o] [a,i] -> PrimInline $ bnd_ix32 bound a i $ read_stableptr a i r o + IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_i8 a i + IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ bnd_ix16 bound a i $ r |= read_i16 a i + IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ bnd_ix64 bound a i $ read_i64 a i h l + IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_u8 a i + IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ bnd_ix16 bound a i $ r |= read_u16 a i + IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_u32 a i + IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ bnd_ix64 bound a i $ read_u64 a i h l + + ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_u8 a i + ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_u32 a i + ReadByteArrayOp_Addr -> \[r,o] [a,i] -> PrimInline $ bnd_ix32 bound a i $ read_addr a i r o + ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_f32 a i + ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline $ bnd_ix64 bound a i $ r |= read_f64 a i + ReadByteArrayOp_StablePtr -> \[r,o] [a,i] -> PrimInline $ bnd_ix32 bound a i $ read_stableptr a i r o + ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_i8 a i + ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline $ bnd_ix16 bound a i $ r |= read_i16 a i + ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline $ bnd_ix64 bound a i $ read_i64 a i h l + ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline $ bnd_ix8 bound a i $ r |= read_u8 a i + ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline $ bnd_ix16 bound a i $ r |= read_u16 a i + ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_u32 a i + ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline $ bnd_ix64 bound a i $ read_u64 a i h l + + WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline $ bnd_ix8 bound a i $ write_u8 a i e + WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_i32 a i e + WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_i32 a i e + WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_u32 a i e + WriteByteArrayOp_Addr -> \[] [a,i,r,o] -> PrimInline $ bnd_ix32 bound a i $ write_addr a i r o + WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_f32 a i e + WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline $ bnd_ix64 bound a i $ write_f64 a i e + WriteByteArrayOp_StablePtr -> \[] [a,i,r,o] -> PrimInline $ bnd_ix32 bound a i $ write_stableptr a i r o + WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline $ bnd_ix8 bound a i $ write_i8 a i e + WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline $ bnd_ix16 bound a i $ write_i16 a i e + WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_i32 a i e + WriteByteArrayOp_Int64 -> \[] [a,i,h,l] -> PrimInline $ bnd_ix64 bound a i $ write_i64 a i h l + WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline $ bnd_ix8 bound a i $ write_u8 a i e + WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline $ bnd_ix16 bound a i $ write_u16 a i e + WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline $ bnd_ix32 bound a i $ write_u32 a i e + WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> PrimInline $ bnd_ix64 bound a i $ write_u64 a i h l - IndexByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_f32 a i - IndexByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_f64 a i - IndexByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ mconcat - [ r1 |= var "h$stablePtrBuf" - , r2 |= read_i32 a i - ] - IndexByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i - IndexByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_i16 a i - IndexByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - IndexByteArrayOp_Int64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ h |= read_i32 a (Add (i .<<. one_) one_) - , l |= read_u32 a (i .<<. one_) - ] - IndexByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i - IndexByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_u16 a i - IndexByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i - IndexByteArrayOp_Word64 -> \[h,l] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ h |= read_u32 a (Add (i .<<. one_) one_) - , l |= read_u32 a (i .<<. one_) - ] - ReadByteArrayOp_Char -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i - ReadByteArrayOp_WideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - ReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - ReadByteArrayOp_Word -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i - ReadByteArrayOp_Addr -> \[r1,r2] [a,i] -> - PrimInline $ jVar \x -> mconcat - [ x |= i .<<. two_ - , ifS (a .^ "arr" .&&. a .^ "arr" .! x) - (mconcat [ r1 |= a .^ "arr" .! x .! zero_ - , r2 |= a .^ "arr" .! x .! one_ - ]) - (mconcat [r1 |= null_, r2 |= one_]) - ] - ReadByteArrayOp_Float -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_f32 a i - ReadByteArrayOp_Double -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ r |= read_f64 a i - ReadByteArrayOp_StablePtr -> \[r1,r2] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ mconcat - [ r1 |= var "h$stablePtrBuf" - , r2 |= read_i32 a i - ] - ReadByteArrayOp_Int8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_i8 a i - ReadByteArrayOp_Int16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_i16 a i - ReadByteArrayOp_Int32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - ReadByteArrayOp_Int64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ h |= read_i32 a (Add (i .<<. one_) one_) - , l |= read_u32 a (i .<<. one_) - ] - ReadByteArrayOp_Word8 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_u8 a i - ReadByteArrayOp_Word16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ r |= read_u16 a i - ReadByteArrayOp_Word32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_u32 a i - ReadByteArrayOp_Word64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ h |= read_u32 a (Add (i .<<. one_) one_) - , l |= read_u32 a (i .<<. one_) - ] - WriteByteArrayOp_Char -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e - WriteByteArrayOp_WideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e - WriteByteArrayOp_Int -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e - WriteByteArrayOp_Word -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_u32 a i e - WriteByteArrayOp_Addr -> \[] [a,i,e1,e2] -> - PrimInline $ mconcat - [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) - ] - WriteByteArrayOp_Float -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_f32 a i e - WriteByteArrayOp_Double -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ write_f64 a i e - WriteByteArrayOp_StablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e2 - - WriteByteArrayOp_Int8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_i8 a i e - WriteByteArrayOp_Int16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_i16 a i e - WriteByteArrayOp_Int32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i e - WriteByteArrayOp_Int64 -> \[] [a,i,e1,e2] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ write_i32 a (Add (i .<<. one_) one_) e1 - , write_u32 a (i .<<. one_) e2 - ] - WriteByteArrayOp_Word8 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_u8 a i e - WriteByteArrayOp_Word16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ write_u16 a i e - WriteByteArrayOp_Word32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_u32 a i e - WriteByteArrayOp_Word64 -> \[] [a,i,h,l] -> - PrimInline . boundsCheckedLen bound a (byteIndex64 i) $ mconcat - [ write_u32 a (Add (i .<<. one_) one_) h - , write_u32 a (i .<<. one_) l - ] CompareByteArraysOp -> \[r] [a1,o1,a2,o2,n] -> PrimInline . boundsCheckedRangeLen bound a1 o1 n . boundsCheckedRangeLen bound a2 o2 n $ r |= app "h$compareByteArrays" [a1,o1,a2,o2,n] - CopyByteArrayOp -> \[] [a1,o1,a2,o2,n] -> - PrimInline . boundsCheckedRangeLen bound a1 o1 n - . boundsCheckedRangeLen bound a2 o2 n - . checkOverlapByteArray bound a1 o1 a2 o2 n - $ appS "h$copyMutableByteArray" [a1,o1,a2,o2,n] - CopyMutableByteArrayOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyMutableByteArrayNonOverlappingOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyMutableByteArrayToAddrOp -> \[] xs@[_a1,_o1,_a2,_o2,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyAddrToByteArrayOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyAddrToAddrOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs - CopyAddrToAddrNonOverlappingOp -> \[] xs@[_ba,_bo,_aa,_ao,_n] -> genPrim prof bound ty CopyByteArrayOp [] xs + CopyByteArrayOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyMutableByteArrayOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyMutableByteArrayNonOverlappingOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray False bound a1 o1 a2 o2 n + CopyByteArrayToAddrOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyMutableByteArrayToAddrOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyAddrToByteArrayOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyAddrToAddrOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray True bound a1 o1 a2 o2 n + CopyAddrToAddrNonOverlappingOp -> \[] [a1,o1,a2,o2,n] -> copyByteArray False bound a1 o1 a2 o2 n SetByteArrayOp -> \[] [a,o,n,v] -> PrimInline . boundsCheckedRangeLen bound a o n $ loopBlockS zero_ (.<. n) \i -> @@ -732,14 +715,14 @@ genPrim prof bound ty op = case op of ] SetAddrRangeOp -> \[] xs@[_a,_o,_n,_v] -> genPrim prof bound ty SetByteArrayOp [] xs - AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ r |= read_i32 a i - AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ write_i32 a i v - FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray Add r a i v - FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray Sub r a i v - FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BAnd r a i v - FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BOr r a i v - FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v - FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ fetchOpByteArray BXor r a i v + AtomicReadByteArrayOp_Int -> \[r] [a,i] -> PrimInline $ bnd_ix32 bound a i $ r |= read_i32 a i + AtomicWriteByteArrayOp_Int -> \[] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ write_i32 a i v + FetchAddByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray Add r a i v + FetchSubByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray Sub r a i v + FetchAndByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray BAnd r a i v + FetchOrByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray BOr r a i v + FetchNandByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray (\x y -> BNot (BAnd x y)) r a i v + FetchXorByteArrayOp_Int -> \[r] [a,i,v] -> PrimInline $ bnd_ix32 bound a i $ fetchOpByteArray BXor r a i v ------------------------------- Addr# ------------------------------------------ @@ -757,107 +740,58 @@ genPrim prof bound ty op = case op of ------------------------------- Addr Indexing: Unboxed Arrays ------------------- - IndexOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) - IndexOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) - IndexOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) - IndexOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) - IndexOffAddrOp_Addr -> \[ca,co] [a,o,i] -> - PrimInline . boundsChecked bound (a .^ "arr") (off32 o i) - $ ifBlockS (a .^ "arr " .&&. a .^ "arr" .! (i .<<. two_)) - [ ca |= a .^ "arr" .! (off32 o i) .! zero_ - , co |= a .^ "arr" .! (off32 o i) .! one_ - ] - [ ca |= null_ - , co |= zero_ - ] - IndexOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_f32 a (off32 o i) - IndexOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off64 o i) $ c |= read_boff_f64 a (off64 o i) - IndexOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ mconcat - [ c1 |= var "h$stablePtrBuf" - , c2 |= read_boff_i32 a (off32 o i) - ] - IndexOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_i8 a (off8 o i) - IndexOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ c |= read_boff_i16 a (off16 o i) - IndexOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) - IndexOffAddrOp_Int64 -> \[h,l] [a,o,i] -> - PrimInline $ mconcat - [ h |= read_boff_i32 a (Add (off64 o i) (Int 4)) - , l |= read_boff_u32 a (off64 o i) - ] - IndexOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) - IndexOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ c |= read_boff_u16 a (off16 o i) - IndexOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) - IndexOffAddrOp_Word64 -> \[h,l] [a,o,i] -> - PrimInline $ mconcat - [ h |= read_boff_u32 a (Add (off64 o i) (Int 4)) - , l |= read_boff_u32 a (off64 o i) - ] - ReadOffAddrOp_Char -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ c |= read_boff_u8 a (off8 o i) - ReadOffAddrOp_WideChar -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) - ReadOffAddrOp_Int -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_i32 a (off32 o i) - ReadOffAddrOp_Word -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_u32 a (off32 o i) - ReadOffAddrOp_Addr -> \[c1,c2] [a,o,i] -> - PrimInline $ jVar \x -> mconcat - [ x |= i .<<. two_ - , boundsChecked bound (a .^ "arr") (Add o x) $ - ifBlockS (a .^ "arr" .&&. a .^ "arr" .! (Add o x)) - [ c1 |= a .^ "arr" .! (Add o x) .! zero_ - , c2 |= a .^ "arr" .! (Add o x) .! one_ - ] - [ c1 |= null_ - , c2 |= zero_ - ] - ] - ReadOffAddrOp_Float -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ c |= read_boff_f32 a (off32 o i) - ReadOffAddrOp_Double -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off64 o i) $ c |= read_boff_f64 a (off64 o i) - ReadOffAddrOp_StablePtr -> \[c1,c2] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ mconcat - [ c1 |= var "h$stablePtrBuf" - , c2 |= read_boff_u32 a (off32 o i) - ] - ReadOffAddrOp_Int8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ AssignStat c $ read_boff_i8 a (off8 o i) - ReadOffAddrOp_Int16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ AssignStat c $ read_boff_i16 a (off16 o i) - ReadOffAddrOp_Int32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ AssignStat c $ read_boff_i32 a (off32 o i) - ReadOffAddrOp_Int64 -> \[h,l] [a,o,i] -> - PrimInline $ mconcat - [ h |= read_i32 a (Add (off64 o i) (Int 4)) - , l |= read_u32 a (off64 o i) - ] - ReadOffAddrOp_Word8 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off8 o i) $ AssignStat c $ read_boff_u8 a (off8 o i) - ReadOffAddrOp_Word16 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off16 o i) $ AssignStat c $ read_boff_u16 a (off16 o i) - ReadOffAddrOp_Word32 -> \[c] [a,o,i] -> PrimInline . boundsChecked bound a (off32 o i) $ AssignStat c $ read_boff_u32 a (off32 o i) - ReadOffAddrOp_Word64 -> \[c1,c2] [a,o,i] -> - PrimInline $ mconcat - [ c1 |= read_boff_u32 a (Add (off64 o i) (Int 4)) - , c2 |= read_boff_u32 a (off64 o i) - ] - WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_u8 a (off8 o i) v - WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v - WriteOffAddrOp_Addr -> \[] [a,o,i,va,vo] -> - PrimInline $ mconcat - [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , boundsChecked bound (a .^ "arr") (off32 o i) $ - AssignStat (a .^ "arr" .! (off32 o i)) $ ValExpr (JList [va, vo]) - ] - WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_f32 a (off32 o i) v - WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off64 o i) $ write_boff_f64 a (off64 o i) v - WriteOffAddrOp_StablePtr -> \[] [a,o,i,_v1,v2] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v2 - WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_i8 a (off8 o i) v - WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off16 o i) $ write_boff_i16 a (off16 o i) v - WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_i32 a (off32 o i) v - WriteOffAddrOp_Int64 -> \[] [a,o,i,v1,v2] -> PrimInline . boundsChecked bound a (off64 o i) $ mconcat - [ write_boff_i32 a (Add (off64 o i) (Int 4)) v1 - , write_boff_u32 a (off64 o i) v2 - ] - WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off8 o i) $ write_boff_u8 a (off8 o i) v - WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off16 o i) $ write_boff_u16 a (off16 o i) v - WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline . boundsChecked bound a (off32 o i) $ write_boff_u32 a (off32 o i) v - WriteOffAddrOp_Word64 -> \[] [a,o,i,v1,v2] -> PrimInline . boundsChecked bound a (off64 o i) $ mconcat - [ write_boff_u32 a (Add (off64 o i) (Int 4)) v1 - , write_boff_u32 a (off64 o i) v2 - ] --- Mutable variables + IndexOffAddrOp_Char -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_WideChar -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Word -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u32 a (off32 o i) + IndexOffAddrOp_Addr -> \[ra,ro] [a,o,i] -> PrimInline $ read_boff_addr a (off32 o i) ra ro + IndexOffAddrOp_Float -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_f32 a (off32 o i) + IndexOffAddrOp_Double -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_f64 a (off64 o i) + IndexOffAddrOp_StablePtr -> \[ra,ro] [a,o,i] -> PrimInline $ read_boff_stableptr a (off32 o i) ra ro + IndexOffAddrOp_Int8 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i8 a (off8 o i) + IndexOffAddrOp_Int16 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i16 a (off16 o i) + IndexOffAddrOp_Int32 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + IndexOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ read_boff_i64 a (off64 o i) h l + IndexOffAddrOp_Word8 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u8 a (off8 o i) + IndexOffAddrOp_Word16 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u16 a (off16 o i) + IndexOffAddrOp_Word32 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u32 a (off32 o i) + IndexOffAddrOp_Word64 -> \[h,l] [a,o,i] -> PrimInline $ read_boff_u64 a (off64 o i) h l + + ReadOffAddrOp_Char -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u8 a (off8 o i) + ReadOffAddrOp_WideChar -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Word -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u32 a (off32 o i) + ReadOffAddrOp_Addr -> \[ra,ro] [a,o,i] -> PrimInline $ read_boff_addr a (off32 o i) ra ro + ReadOffAddrOp_Float -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_f32 a (off32 o i) + ReadOffAddrOp_Double -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_f64 a (off64 o i) + ReadOffAddrOp_StablePtr -> \[ra,ro] [a,o,i] -> PrimInline $ read_boff_stableptr a (off32 o i) ra ro + ReadOffAddrOp_Int8 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i8 a (off8 o i) + ReadOffAddrOp_Int16 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i16 a (off16 o i) + ReadOffAddrOp_Int32 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_i32 a (off32 o i) + ReadOffAddrOp_Int64 -> \[h,l] [a,o,i] -> PrimInline $ read_boff_i64 a (off64 o i) h l + ReadOffAddrOp_Word8 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u8 a (off8 o i) + ReadOffAddrOp_Word16 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u16 a (off16 o i) + ReadOffAddrOp_Word32 -> \[r] [a,o,i] -> PrimInline $ r |= read_boff_u32 a (off32 o i) + ReadOffAddrOp_Word64 -> \[h,l] [a,o,i] -> PrimInline $ read_boff_u64 a (off64 o i) h l + + WriteOffAddrOp_Char -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_WideChar -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Int -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Word -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v + WriteOffAddrOp_Addr -> \[] [a,o,i,va,vo] -> PrimInline $ write_boff_addr a (off32 o i) va vo + WriteOffAddrOp_Float -> \[] [a,o,i,v] -> PrimInline $ write_boff_f32 a (off32 o i) v + WriteOffAddrOp_Double -> \[] [a,o,i,v] -> PrimInline $ write_boff_f64 a (off64 o i) v + WriteOffAddrOp_StablePtr -> \[] [a,o,i,va,vo] -> PrimInline $ write_boff_stableptr a (off32 o i) va vo + WriteOffAddrOp_Int8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i8 a (off8 o i) v + WriteOffAddrOp_Int16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i16 a (off16 o i) v + WriteOffAddrOp_Int32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_i32 a (off32 o i) v + WriteOffAddrOp_Int64 -> \[] [a,o,i,h,l] -> PrimInline $ write_boff_i64 a (off64 o i) h l + WriteOffAddrOp_Word8 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u8 a (off8 o i) v + WriteOffAddrOp_Word16 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u16 a (off16 o i) v + WriteOffAddrOp_Word32 -> \[] [a,o,i,v] -> PrimInline $ write_boff_u32 a (off32 o i) v + WriteOffAddrOp_Word64 -> \[] [a,o,i,h,l] -> PrimInline $ write_boff_u64 a (off64 o i) h l + +------------------------------- Mutable varialbes -------------------------------------- NewMutVarOp -> \[r] [x] -> PrimInline $ r |= New (app "h$MutVar" [x]) ReadMutVarOp -> \[r] [m] -> PrimInline $ r |= m .^ "val" WriteMutVarOp -> \[] [m,x] -> PrimInline $ m .^ "val" |= x @@ -918,17 +852,17 @@ genPrim prof bound ty op = case op of ------------------------------- Concurrency Primitives ------------------------- - ForkOp -> \[_tid] [x] -> PRPrimCall $ returnS (app "h$fork" [x, true_]) - ForkOnOp -> \[_tid] [_p,x] -> PRPrimCall $ returnS (app "h$fork" [x, true_]) -- ignore processor argument - KillThreadOp -> \[] [tid,ex] -> PRPrimCall $ returnS (app "h$killThread" [tid,ex]) - YieldOp -> \[] [] -> PRPrimCall $ returnS (app "h$yield" []) - MyThreadIdOp -> \[r] [] -> PrimInline $ r |= var "h$currentThread" - IsCurrentThreadBoundOp -> \[r] [] -> PrimInline $ r |= one_ - NoDuplicateOp -> \[] [] -> PrimInline mempty -- don't need to do anything as long as we have eager blackholing - ThreadStatusOp -> \[stat,cap,locked] [tid] -> PrimInline $ appT [stat, cap, locked] "h$threadStatus" [tid] - ListThreadsOp -> \[r] [] -> PrimInline $ r |= var "h$threads" - GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] - LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l + ForkOp -> \[_tid] [x] -> PRPrimCall $ returnS (app "h$fork" [x, true_]) + ForkOnOp -> \[_tid] [_p,x] -> PRPrimCall $ returnS (app "h$fork" [x, true_]) -- ignore processor argument + KillThreadOp -> \[] [tid,ex] -> PRPrimCall $ returnS (app "h$killThread" [tid,ex]) + YieldOp -> \[] [] -> PRPrimCall $ returnS (app "h$yield" []) + MyThreadIdOp -> \[r] [] -> PrimInline $ r |= var "h$currentThread" + IsCurrentThreadBoundOp -> \[r] [] -> PrimInline $ r |= one_ + NoDuplicateOp -> \[] [] -> PrimInline mempty -- don't need to do anything as long as we have eager blackholing + ThreadStatusOp -> \[stat,cap,locked] [tid] -> PrimInline $ appT [stat, cap, locked] "h$threadStatus" [tid] + ListThreadsOp -> \[r] [] -> PrimInline $ r |= var "h$threads" + GetThreadLabelOp -> \[r1, r2] [t] -> PrimInline $ appT [r1, r2] "h$getThreadLabel" [t] + LabelThreadOp -> \[] [t,l] -> PrimInline $ t .^ "label" |= l ------------------------------- Weak Pointers ----------------------------------- @@ -1032,184 +966,82 @@ genPrim prof bound ty op = case op of TraceEventBinaryOp -> \[] [ed,eo,len] -> PrimInline $ appS "h$traceEventBinary" [ed,eo,len] TraceMarkerOp -> \[] [ed,eo] -> PrimInline $ appS "h$traceMarker" [ed,eo] - IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i - IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> - PrimInline $ jVar \x -> mconcat - [ x |= i .<<. two_ - , boundsCheckedLen bound (a .^ "arr") x $ - ifS (a .^ "arr" .&&. a .^ "arr" .! x) - (mconcat [ r1 |= a .^ "arr" .! x .! zero_ - , r2 |= a .^ "arr" .! x .! one_ - ]) - (mconcat [r1 |= null_, r2 |= one_]) - ] - IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i - IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i - IndexByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> - PrimInline $ mconcat - [ r1 |= var "h$stablePtrBuf" - , r2 |= read_boff_i32 a i - ] - IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i - IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> - PrimInline $ mconcat - [ h |= read_boff_i32 a (Add i (Int 4)) - , l |= read_boff_u32 a i - ] - IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i - IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat - [ h |= read_boff_u32 a (Add i (Int 4)) - , l |= read_boff_u32 a i - ] - IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - - ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i $ r |= read_boff_u8 a i - ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsAddr -> \[r1,r2] [a,i] -> - PrimInline $ jVar \x -> mconcat - [ x |= i .<<. two_ - , boundsCheckedLen bound (a .^ "arr") x $ - ifS (a .^ "arr" .&&. a .^ "arr" .! x) - (mconcat [ r1 |= a .^ "arr" .! x .! zero_ - , r2 |= a .^ "arr" .! x .! one_ - ]) - (mconcat [r1 |= null_, r2 |= one_]) - ] - ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_f32 a i - ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ r |= read_boff_f64 a i - ReadByteArrayOp_Word8AsStablePtr -> \[r1,r2] [a,i] -> - PrimInline $ mconcat - [ r1 |= var "h$stablePtrBuf" - , r2 |= read_boff_i32 a i - ] - ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_i16 a i - ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> - PrimInline $ mconcat - [ h |= read_boff_i32 a (Add i (Int 4)) - , l |= read_boff_u32 a i - ] - ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_i32 a i - ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ r |= read_boff_u16 a i - ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> - PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ mconcat - [ h |= read_boff_u32 a (Add i (Int 4)) - , l |= read_boff_u32 a i - ] - ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ r |= read_boff_u32 a i - - WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i $ write_boff_i8 a i e - WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsAddr -> \[] [a,i,e1,e2] -> - PrimInline $ mconcat - [ ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty - , boundsCheckedLen bound (a .^ "arr") (i .<<. two_) $ - a .^ "arr" .! (i .<<. two_) |= ValExpr (JList [e1, e2]) - ] - - WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_f32 a i e - WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) $ write_boff_f64 a i e - WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_e1,e2] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e2 - WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_i16 a i e - WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> - -- JS Numbers are little-endian and 32-bit, so write the lower 4 bytes at i - -- then write the higher 4 bytes to i+4 - PrimInline . boundsCheckedLen bound a i - $ mconcat [ write_boff_i32 a (Add i (Int 4)) h - , write_boff_u32 a i l - ] - WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_i32 a i e - WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 1) $ write_boff_u16 a i e - WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e - WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> - PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 7) - $ mconcat [ write_boff_u32 a (Add i (Int 4)) h - , write_boff_u32 a i l - ] - WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline . boundsCheckedLen bound a i . boundsCheckedLen bound a (Add i 3) $ write_boff_u32 a i e - - CasByteArrayOp_Int -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ casOp read_i32 write_i32 r a i old new - CasByteArrayOp_Int8 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a i $ casOp read_i8 write_i8 r a i old new - CasByteArrayOp_Int16 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex16 i) $ casOp read_i16 write_i16 r a i old new - CasByteArrayOp_Int32 -> \[r] [a,i,old,new] -> PrimInline . boundsCheckedLen bound a (byteIndex32 i) $ casOp read_i32 write_i32 r a i old new - - CasByteArrayOp_Int64 -> \[r_h,r_l] [a,i,old_h,old_l,new_h,new_l] -> PrimInline . boundsCheckedLen bound a (Add (i .<<. one_) one_) $ - jVar \t_h t_l -> mconcat [ t_h |= read_i32 a (Add (i .<<. one_) one_) - , t_l |= read_u32 a (i .<<. one_) - , r_h |= t_h - , r_l |= t_l - , ifS (t_l .===. old_l) -- small optimization, check low bits first, fail fast - (ifBlockS (t_h .===. old_h) - -- Pre-Condition is good, do the write - [ write_i32 a (Add (i .<<. one_) one_) new_h - , write_u32 a (i .<<. one_) new_l - ] - -- no good, don't write - mempty) - mempty - ] - - CasAddrOp_Addr -> \[r_a,r_o] [a1,o1,a2,o2,a3,o3] -> PrimInline $ - mconcat [ ifS (app "h$comparePointer" [a1,o1,a2,o2]) - (appS "h$memcpy" [a3,o3,a1,o1,8]) - mempty - , r_a |= a1 - , r_o |= o1 - ] +------------------------------ ByteArray ------------------- + + IndexByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ bnd_ba8 bound a i $ r |= read_boff_u8 a i + IndexByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsAddr -> \[r,o] [a,i] -> PrimInline $ bnd_ba32 bound a i $ read_boff_addr a i r o + IndexByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_f32 a i + IndexByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ bnd_ba64 bound a i $ r |= read_boff_f64 a i + IndexByteArrayOp_Word8AsStablePtr -> \[r,o] [a,i] -> PrimInline $ bnd_ba32 bound a i $ read_boff_stableptr a i r o + IndexByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ bnd_ba16 bound a i $ r |= read_boff_i16 a i + IndexByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ bnd_ba64 bound a i $ read_boff_i64 a i h l + IndexByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + IndexByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ bnd_ba16 bound a i $ r |= read_boff_u16 a i + IndexByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_u32 a i + IndexByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ bnd_ba64 bound a i $ read_boff_u64 a i h l + IndexByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_u32 a i + + ReadByteArrayOp_Word8AsChar -> \[r] [a,i] -> PrimInline $ bnd_ba8 bound a i $ r |= read_boff_u8 a i + ReadByteArrayOp_Word8AsWideChar -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsAddr -> \[r,o] [a,i] -> PrimInline $ bnd_ba32 bound a i $ read_boff_addr a i r o + ReadByteArrayOp_Word8AsFloat -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_f32 a i + ReadByteArrayOp_Word8AsDouble -> \[r] [a,i] -> PrimInline $ bnd_ba64 bound a i $ r |= read_boff_f64 a i + ReadByteArrayOp_Word8AsStablePtr -> \[r,o] [a,i] -> PrimInline $ bnd_ba32 bound a i $ read_boff_stableptr a i r o + ReadByteArrayOp_Word8AsInt16 -> \[r] [a,i] -> PrimInline $ bnd_ba16 bound a i $ r |= read_boff_i16 a i + ReadByteArrayOp_Word8AsInt32 -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsInt64 -> \[h,l] [a,i] -> PrimInline $ bnd_ba64 bound a i $ read_boff_i64 a i h l + ReadByteArrayOp_Word8AsInt -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_i32 a i + ReadByteArrayOp_Word8AsWord16 -> \[r] [a,i] -> PrimInline $ bnd_ba16 bound a i $ r |= read_boff_u16 a i + ReadByteArrayOp_Word8AsWord32 -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_u32 a i + ReadByteArrayOp_Word8AsWord64 -> \[h,l] [a,i] -> PrimInline $ bnd_ba64 bound a i $ read_boff_u64 a i h l + ReadByteArrayOp_Word8AsWord -> \[r] [a,i] -> PrimInline $ bnd_ba32 bound a i $ r |= read_boff_u32 a i + + WriteByteArrayOp_Word8AsChar -> \[] [a,i,e] -> PrimInline $ bnd_ba8 bound a i $ write_boff_i8 a i e + WriteByteArrayOp_Word8AsWideChar -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsAddr -> \[] [a,i,r,o] -> PrimInline $ bnd_ba32 bound a i $ write_boff_addr a i r o + WriteByteArrayOp_Word8AsFloat -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_f32 a i e + WriteByteArrayOp_Word8AsDouble -> \[] [a,i,e] -> PrimInline $ bnd_ba64 bound a i $ write_boff_f64 a i e + WriteByteArrayOp_Word8AsStablePtr -> \[] [a,i,_,o] -> PrimInline $ bnd_ba32 bound a i $ write_boff_i32 a i o + WriteByteArrayOp_Word8AsInt16 -> \[] [a,i,e] -> PrimInline $ bnd_ba16 bound a i $ write_boff_i16 a i e + WriteByteArrayOp_Word8AsInt32 -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsInt64 -> \[] [a,i,h,l] -> PrimInline $ bnd_ba64 bound a i $ write_boff_i64 a i h l + WriteByteArrayOp_Word8AsInt -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_i32 a i e + WriteByteArrayOp_Word8AsWord16 -> \[] [a,i,e] -> PrimInline $ bnd_ba16 bound a i $ write_boff_u16 a i e + WriteByteArrayOp_Word8AsWord32 -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_u32 a i e + WriteByteArrayOp_Word8AsWord64 -> \[] [a,i,h,l] -> PrimInline $ bnd_ba64 bound a i $ write_boff_u64 a i h l + WriteByteArrayOp_Word8AsWord -> \[] [a,i,e] -> PrimInline $ bnd_ba32 bound a i $ write_boff_u32 a i e + + CasByteArrayOp_Int -> \[r] [a,i,o,n] -> PrimInline $ bnd_ix32 bound a i $ casOp read_i32 write_i32 r a i o n + CasByteArrayOp_Int8 -> \[r] [a,i,o,n] -> PrimInline $ bnd_ix8 bound a i $ casOp read_i8 write_i8 r a i o n + CasByteArrayOp_Int16 -> \[r] [a,i,o,n] -> PrimInline $ bnd_ix16 bound a i $ casOp read_i16 write_i16 r a i o n + CasByteArrayOp_Int32 -> \[r] [a,i,o,n] -> PrimInline $ bnd_ix32 bound a i $ casOp read_i32 write_i32 r a i o n + + CasByteArrayOp_Int64 -> \[rh,rl] [a,i,oh,ol,nh,nl] -> PrimInline $ bnd_ix64 bound a i $ casOp2 read_i64 write_i64 (rh,rl) a i (oh,ol) (nh,nl) + + CasAddrOp_Addr -> \[ra,ro] [a,o,oa,oo,na,no] -> PrimInline $ casOp2 read_boff_addr write_boff_addr (ra,ro) a o (oa,oo) (na,no) CasAddrOp_Word -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u32 write_u32 r a o old new CasAddrOp_Word8 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u8 write_u8 r a o old new CasAddrOp_Word16 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u16 write_u16 r a o old new CasAddrOp_Word32 -> \[r] [a,o,old,new] -> PrimInline $ casOp read_u32 write_u32 r a o old new - CasAddrOp_Word64 -> \[r_h,r_l] [a,o,old_h,old_l,new_h,new_l] -> PrimInline $ - mconcat [ r_h |= read_u32 a (Add o (Int 4)) - , r_l |= read_u32 a o - , ifS (r_l .===. old_l) - (ifBlockS (r_h .===. old_h) - [ write_u32 a (Add o (Int 4)) new_h - , write_u32 a o new_l - ] - mempty) - mempty - ] - - FetchAddAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr Add r a o v - FetchSubAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr Sub r a o v + CasAddrOp_Word64 -> \[rh,rl] [a,o,oh,ol,nh,nl] -> PrimInline $ casOp2 read_u64 write_u64 (rh,rl) a o (oh,ol) (nh,nl) + + FetchAddAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr Add r a o v + FetchSubAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr Sub r a o v FetchAndAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr BAnd r a o v FetchNandAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr ((BNot .) . BAnd) r a o v FetchOrAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr BOr r a o v FetchXorAddrOp_Word -> \[r] [a,o,v] -> PrimInline $ fetchOpAddr BXor r a o v - InterlockedExchange_Addr -> \[r_a,r_o] [a1,o1,_a2,o2] -> PrimInline $ - -- this primop can't be implemented - -- correctly because we don't store - -- the array reference part of an Addr#, - -- only the offset part. - -- - -- So let's assume that all the array - -- references are the same... - -- - -- Note: we could generate an assert - -- that checks that a1 === a2. However - -- we can't check that the Addr# read - -- at Addr# a2[o2] also comes from this - -- a1/a2 array. - mconcat [ r_a |= a1 -- might be wrong (see above) - , r_o |= read_boff_u32 a1 o1 - -- TODO (see above) - -- assert that a1 === a2 - , write_boff_u32 a1 o1 o2 - ] - InterlockedExchange_Word -> \[r] [a,o,w] -> PrimInline $ - mconcat [ r |= read_boff_u32 a o - , write_boff_u32 a o w - ] + InterlockedExchange_Addr -> \[ra,ro] [a1,o1,a2,o2] -> PrimInline $ mconcat + [ read_boff_addr a1 o1 ra ro + , write_boff_addr a1 o1 a2 o2 + ] + InterlockedExchange_Word -> \[r] [a,o,w] -> PrimInline $ mconcat + [ r |= read_boff_u32 a o + , write_boff_u32 a o w + ] ShrinkSmallMutableArrayOp_Char -> \[] [a,n] -> PrimInline $ appS "h$shrinkMutableCharArray" [a,n] GetSizeofSmallMutableArrayOp -> \[r] [a] -> PrimInline $ r |= a .^ "length" @@ -1368,6 +1200,79 @@ read_f32 a i = idx_f32 a i read_f64 :: JExpr -> JExpr -> JExpr read_f64 a i = idx_f64 a i +read_u64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_u64 a i rh rl = mconcat + [ rl |= read_u32 a (i .<<. 1) + , rh |= read_u32 a (Add 1 (i .<<. 1)) + ] + +read_i64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_i64 a i rh rl = mconcat + [ rl |= read_u32 a (i .<<. 1) + , rh |= read_i32 a (Add 1 (i .<<. 1)) + ] + +-------------------------------------- +-- Addr# +-------------------------------------- + +write_addr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_addr a i r o = mconcat + [ write_i32 a i o + -- create the hidden array for arrays if it doesn't exist + , ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty + , a .^ "arr" .! (i .<<. 2) |= r + ] + +read_addr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_addr a i r o = mconcat + [ o |= read_i32 a i + , r |= if_ ((a .^ "arr") .&&. (a .^ "arr" .! (i .<<. 2))) + (a .^ "arr" .! (i .<<. 2)) + null_ + ] + +read_boff_addr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_boff_addr a i r o = mconcat + [ o |= read_boff_i32 a i + , r |= if_ ((a .^ "arr") .&&. (a .^ "arr" .! i)) + (a .^ "arr" .! i) + null_ + ] + +write_boff_addr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_boff_addr a i r o = mconcat + [ write_boff_i32 a i o + -- create the hidden array for arrays if it doesn't exist + , ifS (Not (a .^ "arr")) (a .^ "arr" |= ValExpr (JList [])) mempty + , a .^ "arr" .! i |= r + ] + + +-------------------------------------- +-- StablePtr +-------------------------------------- + +read_stableptr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_stableptr a i r o = mconcat + [ r |= var "h$stablePtrBuf" -- stable pointers are always in this array + , o |= read_i32 a i + ] + +read_boff_stableptr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_boff_stableptr a i r o = mconcat + [ r |= var "h$stablePtrBuf" -- stable pointers are always in this array + , o |= read_boff_i32 a i + ] + +write_stableptr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_stableptr a i _r o = write_i32 a i o + -- don't store "r" as it must be h$stablePtrBuf + +write_boff_stableptr :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_boff_stableptr a i _r o = write_boff_i32 a i o + -- don't store "r" as it must be h$stablePtrBuf + write_u8 :: JExpr -> JExpr -> JExpr -> JStat write_u8 a i v = idx_u8 a i |= v @@ -1392,6 +1297,18 @@ write_f32 a i v = idx_f32 a i |= v write_f64 :: JExpr -> JExpr -> JExpr -> JStat write_f64 a i v = idx_f64 a i |= v +write_u64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_u64 a i h l = mconcat + [ write_u32 a (i .<<. 1) l + , write_u32 a (Add 1 (i .<<. 1)) h + ] + +write_i64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_i64 a i h l = mconcat + [ write_u32 a (i .<<. 1) l + , write_i32 a (Add 1 (i .<<. 1)) h + ] + -- Data View helper functions: byte indexed! -- -- The argument list consists of the array @a@, the index @i@, and the new value @@ -1407,6 +1324,16 @@ write_boff_u32 a i v = ApplStat (a .^ "dv" .^ "setUint32" ) [i, v, true_] write_boff_f32 a i v = ApplStat (a .^ "dv" .^ "setFloat32") [i, v, true_] write_boff_f64 a i v = ApplStat (a .^ "dv" .^ "setFloat64") [i, v, true_] +write_boff_i64, write_boff_u64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +write_boff_i64 a i h l = mconcat + [ write_boff_i32 a (Add i (Int 4)) h + , write_boff_u32 a i l + ] +write_boff_u64 a i h l = mconcat + [ write_boff_u32 a (Add i (Int 4)) h + , write_boff_u32 a i l + ] + read_boff_i8, read_boff_u8, read_boff_i16, read_boff_u16, read_boff_i32, read_boff_u32, read_boff_f32, read_boff_f64 :: JExpr -> JExpr -> JExpr read_boff_i8 a i = read_i8 a i read_boff_u8 a i = read_u8 a i @@ -1417,6 +1344,18 @@ read_boff_u32 a i = ApplExpr (a .^ "dv" .^ "getUint32" ) [i, true_] read_boff_f32 a i = ApplExpr (a .^ "dv" .^ "getFloat32") [i, true_] read_boff_f64 a i = ApplExpr (a .^ "dv" .^ "getFloat64") [i, true_] +read_boff_i64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_boff_i64 a i rh rl = mconcat + [ rh |= read_boff_i32 a (Add i (Int 4)) + , rl |= read_boff_u32 a i + ] + +read_boff_u64 :: JExpr -> JExpr -> JExpr -> JExpr -> JStat +read_boff_u64 a i rh rl = mconcat + [ rh |= read_boff_u32 a (Add i (Int 4)) + , rl |= read_boff_u32 a i + ] + fetchOpByteArray :: (JExpr -> JExpr -> JExpr) -> JExpr -> JExpr -> JExpr -> JExpr -> JStat fetchOpByteArray op tgt src i v = mconcat [ tgt |= read_i32 src i @@ -1432,8 +1371,8 @@ fetchOpAddr op tgt src i v = mconcat casOp :: (JExpr -> JExpr -> JExpr) -- read -> (JExpr -> JExpr -> JExpr -> JStat) -- write - -> JExpr -- target register to store result - -> JExpr -- source arrays + -> JExpr -- target register to store result + -> JExpr -- source array -> JExpr -- index -> JExpr -- old value to compare -> JExpr -- new value to write @@ -1445,56 +1384,127 @@ casOp read write tgt src i old new = mconcat mempty ] +casOp2 + :: (JExpr -> JExpr -> JExpr -> JExpr -> JStat) -- read + -> (JExpr -> JExpr -> JExpr -> JExpr -> JStat) -- write + -> (JExpr,JExpr) -- target registers to store result + -> JExpr -- source array + -> JExpr -- index + -> (JExpr,JExpr) -- old value to compare + -> (JExpr,JExpr) -- new value to write + -> JStat +casOp2 read write (tgt1,tgt2) src i (old1,old2) (new1,new2) = mconcat + [ read src i tgt1 tgt2 + , ifS ((tgt2 .===. old2) .&&. (tgt1 .===. old1)) + (write src i new1 new2) + mempty + ] + -------------------------------------------------------------------------------- -- Lifted Arrays -------------------------------------------------------------------------------- -- | lifted arrays -cloneArray :: JExpr -> JExpr -> Maybe JExpr -> JExpr -> JStat -cloneArray tgt src mb_offset len = mconcat - [ tgt |= ApplExpr (src .^ "slice") [start, end] - , tgt .^ closureMeta_ |= zero_ - , tgt .^ "__ghcjsArray" |= true_ - ] - where - start = fromMaybe zero_ mb_offset - end = maybe len (Add len) mb_offset - -newArray :: JExpr -> JExpr -> JExpr -> JStat -newArray tgt len elem = - tgt |= app "h$newArray" [len, elem] +cloneArray :: Bool -> JExpr -> JExpr -> JExpr -> JExpr -> JStat +cloneArray bound_check tgt src start len = + bnd_arr_range bound_check src start len + $ mconcat + [ tgt |= ApplExpr (src .^ "slice") [start, Add len start] + , tgt .^ closureMeta_ |= zero_ + , tgt .^ "__ghcjsArray" |= true_ + ] newByteArray :: JExpr -> JExpr -> JStat newByteArray tgt len = tgt |= app "h$newByteArray" [len] -boundsChecked' +-- | Check that index is positive and below a max value. Halt the process with +-- error code 134 otherwise. This is used to implement -fcheck-prim-bounds +check_bound :: JExpr -- ^ Max index expression -> Bool -- ^ Should we do bounds checking? -> JExpr -- ^ Index -> JStat -- ^ Result -> JStat -boundsChecked' _ False _ r = r -boundsChecked' max_index True i r = - ifS ((i .>=. zero_) .&&. (i .<. max_index)) r $ - returnS (app "h$exitProcess" [Int 134]) +check_bound _ False _ r = r +check_bound max_index True i r = mconcat + [ jwhenS ((i .<. zero_) .||. (i .>=. max_index)) $ + returnS (app "h$exitProcess" [Int 134]) + , r + ] -- | Bounds checking using ".length" property (Arrays) -boundsChecked +bnd_arr + :: Bool -- ^ Should we do bounds checking? + -> JExpr -- ^ Array + -> JExpr -- ^ Index + -> JStat -- ^ Result + -> JStat +bnd_arr do_check arr = check_bound (arr .^ "length") do_check + +-- | Range bounds checking using ".length" property (Arrays) +bnd_arr_range :: Bool -- ^ Should we do bounds checking? -> JExpr -- ^ Array -> JExpr -- ^ Index + -> JExpr -- ^ Range size -> JStat -- ^ Result -> JStat -boundsChecked do_check arr = boundsChecked' (arr .^ "length") do_check +bnd_arr_range do_check arr idx n r = + bnd_arr do_check arr idx + $ bnd_arr do_check arr (Add idx n) r -- | Bounds checking using ".len" property (ByteArrays) -boundsCheckedLen +bnd_ba :: Bool -- ^ Should we do bounds checking? -> JExpr -- ^ Array -> JExpr -- ^ Index -> JStat -- ^ Result -> JStat -boundsCheckedLen do_check arr = boundsChecked' (arr .^ "len") do_check +bnd_ba do_check arr = check_bound (arr .^ "len") do_check + +-- | ByteArray bounds checking (byte offset, 8-bit value) +bnd_ba8 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ba8 = bnd_ba + +-- | ByteArray bounds checking (byte offset, 16-bit value) +bnd_ba16 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ba16 do_check arr idx r = + -- check that idx non incremented is in range: + -- (idx + 1) may be in range while idx isn't + bnd_ba do_check arr idx + $ bnd_ba do_check arr (Add idx 1) r + +-- | ByteArray bounds checking (byte offset, 32-bit value) +bnd_ba32 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ba32 do_check arr idx r = + -- check that idx non incremented is in range: + -- (idx + 3) may be in range while idx isn't + bnd_ba do_check arr idx + $ bnd_ba do_check arr (Add idx 3) r + +-- | ByteArray bounds checking (byte offset, 64-bit value) +bnd_ba64 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ba64 do_check arr idx r = + -- check that idx non incremented is in range: + -- (idx + 7) may be in range while idx isn't + bnd_ba do_check arr idx + $ bnd_ba do_check arr (Add idx 7) r + +-- | ByteArray bounds checking (8-bit offset, 8-bit value) +bnd_ix8 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ix8 = bnd_ba8 + +-- | ByteArray bounds checking (16-bit offset, 16-bit value) +bnd_ix16 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ix16 do_check arr idx r = bnd_ba16 do_check arr (idx .<<. 1) r + +-- | ByteArray bounds checking (32-bit offset, 32-bit value) +bnd_ix32 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ix32 do_check arr idx r = bnd_ba32 do_check arr (idx .<<. 2) r + +-- | ByteArray bounds checking (64-bit offset, 64-bit value) +bnd_ix64 :: Bool -> JExpr -> JExpr -> JStat -> JStat +bnd_ix64 do_check arr idx r = bnd_ba64 do_check arr (idx .<<. 3) r -- | Bounds checking on a range and using ".len" property (ByteArrays) -- @@ -1511,7 +1521,7 @@ boundsCheckedRangeLen True xs i n r = ifS (n .<. zero_) (returnS $ app "h$exitProcess" [Int 134]) $ ifS (n .===. zero_) -- We can always fill zero elements, even if it seems out-of-bounds r - (boundsCheckedLen True xs (Add i (Sub n 1)) (boundsCheckedLen True xs i r)) + (bnd_ba True xs (Add i (Sub n 1)) (bnd_ba True xs i r)) checkOverlapByteArray :: Bool -- ^ Should we do bounds checking? @@ -1528,14 +1538,12 @@ checkOverlapByteArray True a1 o1 a2 o2 n r = r (returnS $ app "h$exitProcess" [Int 134]) -byteIndex16 :: JExpr -> JExpr -byteIndex16 i = Add 1 (Mul 2 i) - -byteIndex32 :: JExpr -> JExpr -byteIndex32 i = Add 3 (Mul 4 i) - -byteIndex64 :: JExpr -> JExpr -byteIndex64 i = Add 7 (Mul 8 i) +copyByteArray :: Bool -> Bool -> JExpr -> JExpr -> JExpr -> JExpr -> JExpr -> PrimRes +copyByteArray check_overlap bound a1 o1 a2 o2 n = PrimInline $ check $ appS "h$copyMutableByteArray" [a1,o1,a2,o2,n] + where + check = boundsCheckedRangeLen bound a1 o1 n + . boundsCheckedRangeLen bound a2 o2 n + . (if check_overlap then checkOverlapByteArray bound a1 o1 a2 o2 n else id) -- e|0 (32 bit signed integer truncation) required because of JS numbers. e|0 -- converts e to an Int32. Note that e|0 _is still a Double_ because JavaScript. ===================================== libraries/base/jsbits/base.js ===================================== @@ -878,8 +878,7 @@ function h$__hscore_readdir(d,o,dst_a,dst_o) { } const e = d.readSync(); - if (!dst_a.arr) dst_a.arr = []; - dst_a.arr[dst_o*2] = [e,0]; + PUT_ADDR(dst_a,dst_o*2,e,0); return 0; } ===================================== rts/js/environment.js ===================================== @@ -158,20 +158,19 @@ function h$getProgArgv(argc_v,argc_off,argv_v,argv_off) { } else { argc_v.dv.setInt32(argc_off, c, true); var argv = h$newByteArray(4*c); - argv.arr = []; for(var i=0;i=0;i--) { + a2.arr[o2+i] = a1.arr[o1+i] || null; + } + } else { + for (var i=0;i ptr (array) -function h$derefPtrA(ptr, ptr_off) { - return ptr.arr[ptr_off][0]; -} -// ptr* -> ptr (offset) -function h$derefPtrO(ptr, ptr_off) { - return ptr.arr[ptr_off][1]; -} - -// word** -> word ptr[x][y] -function h$readPtrPtrU32(ptr, ptr_off, x, y) { - x = x || 0; - y = y || 0; - var arr = ptr.arr[ptr_off + 4 * x]; - return arr[0].dv.getInt32(arr[1] + 4 * y, true); -} - -// char** -> char ptr[x][y] -function h$readPtrPtrU8(ptr, ptr_off, x, y) { - x = x || 0; - y = y || 0; - var arr = ptr.arr[ptr_off + 4 * x]; - return arr[0].dv.getUint8(arr[1] + y); -} - -// word** ptr[x][y] = v -function h$writePtrPtrU32(ptr, ptr_off, v, x, y) { - x = x || 0; - y = y || 0; - var arr = ptr.arr[ptr_off + 4 * x]; - arr[0].dv.putInt32(arr[1] + y, v); -} - -// unsigned char** ptr[x][y] = v -function h$writePtrPtrU8(ptr, ptr_off, v, x, y) { - x = x || 0; - y = y || 0; - var arr = ptr.arr[ptr_off+ 4 * x]; - arr[0].dv.putUint8(arr[1] + y, v); -} - // convert JavaScript String to a Haskell String #ifdef GHCJS_PROF function h$toHsString(str, cc) { ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -229,4 +229,4 @@ test('T20640b', normal, compile_and_run, ['']) test('T22296',[only_ways(llvm_ways) ,unless(arch('x86_64'), skip)],compile_and_run,['']) test('T22798', normal, compile_and_run, ['-fregs-graph']) -test('CheckBoundsOK', js_broken(21142), compile_and_run, ['-fcheck-prim-bounds']) +test('CheckBoundsOK', normal, compile_and_run, ['-fcheck-prim-bounds']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c92a8f3213dc1ef089c0772057ecbdf317e19b63 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c92a8f3213dc1ef089c0772057ecbdf317e19b63 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 16:17:49 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 12:17:49 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] Precompute static closures for DataCons with zero-width args Message-ID: <644bf1adae048_178e7411166b9b42151281@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: dbe3a857 by Rodrigo Mesquita at 2023-04-28T17:17:31+01:00 Precompute static closures for DataCons with zero-width args Relax the predicate over nullary datacons that determines whether we can return a precomputed static closure for them, such that we give precomputed static closures to both datacon workers and wrappers as long as they only take zero-width arguments (and hence their closure is comprised of just the constructor info). Previously, we would only allow datacons that were nullary with regard to their Core representation, which prevented datacons workers with only zero-width arguments and wrappers with none from using a precomputed static closure. See Note [Precomputed static closures of nullary constructors] Closes #23158 - - - - - 3 changed files: - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/DataCon.hs Changes: ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -239,9 +239,9 @@ cgEnumerationTyCon tycon | con <- tyConDataCons tycon] +-- | Generate the entry code and associated info table for a constructor. +-- Where are generating the static closure at all? cgDataCon :: ConInfoTableLocation -> DataCon -> FCode () --- Generate the entry code, info tables, and (for niladic constructor) --- the static closure, for a constructor. cgDataCon mn data_con = do { massert (not (isUnboxedTupleDataCon data_con || isUnboxedSumDataCon data_con)) ; profile <- getProfile ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -22,7 +22,7 @@ module GHC.StgToCmm.Closure ( argPrimRep, NonVoid(..), fromNonVoid, nonVoidIds, nonVoidStgArgs, - assertNonVoidIds, assertNonVoidStgArgs, + assertNonVoidIds, assertNonVoidStgArgs, hasNoNonZeroWidthArgs, -- * LambdaFormInfo LambdaFormInfo, -- Abstract @@ -170,6 +170,12 @@ assertNonVoidStgArgs :: [StgArg] -> [NonVoid StgArg] assertNonVoidStgArgs args = assert (not (any (isZeroBitTy . stgArgType) args)) $ coerce args +-- | Returns whether there are any arguments with a non-zero-width runtime +-- representation. +-- +-- Returns True if the datacon has no or /just/ zero-width arguments. +hasNoNonZeroWidthArgs :: DataCon -> Bool +hasNoNonZeroWidthArgs = all (isZeroBitTy . scaledThing) . dataConRepArgTys ----------------------------------------------------------------------------- -- Representations ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -41,6 +41,7 @@ import GHC.Data.FastString import GHC.Types.Id import GHC.Types.Id.Info( CafInfo( NoCafRefs ) ) import GHC.Types.Name (isInternalName) +import GHC.Types.Var (varName) import GHC.Types.RepType (countConRepArgs) import GHC.Types.Literal import GHC.Builtin.Utils @@ -246,7 +247,8 @@ But also at runtime where the GC does the same (but only for INT/CHAR closures). `precomputedStaticConInfo_maybe` checks if a given constructor application -can be replaced with a reference to a existing static closure. +can be replaced with a reference to a existing static closure, according +to the Note [Precomputed static closures of nullary constructors] If so the code will reference the existing closure when accessing the binding. @@ -317,6 +319,103 @@ This holds for both local and top level bindings. We don't support this optimization when compiling into Windows DLLs yet because they don't support cross package data references well. + +Note [Precomputed static closures of nullary constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We can easily create a precomputed static closure for all data constructors +that don't take runtime-relevant arguments since their closure is always just +the constructor info. + +Instead of allocating a closure with just the constructor info every time it is +used, we can instead use the precomputed static closure! + +For example, to return from a function the constructor `Nothing`, instead of +allocating on the heap a word for `Nothing_con_info` and returning the pointer +to it tagged `+1`, we can simply return `Nothing_closure+1` + +We must consider three distinct situations of saturated applications of +constructors that take no runtime-relevant arguments in which we can use a +precomputed static closure: + +(1) For a data con /worker/ `TCon1` application to no arguments whatsoever we +can trivially use the static closure of the worker, `TCon1_closure`. + Recall that for a worker such as `TCon1`, `TCon1_closure` is just the + `TCon1_con_info`: + section ""data" . M.TCon1_closure" { + M.TCon1_closure: + const M.TCon1_con_info; + } + Invariant: These workers don't have wrappers. + +(2) For a data con /wrapper/ `$WTCon2` that takes no arguments whatsoever, we +can also trivially return the static closure of the wrapper, `$WTCon2_closure`. +It might be surprising to see a nullary data con /wrapper/ -- they come into +existence when the worker only takes zero-width arguments. See the example below. + As in (1), `$WTCon2_closure` simply points to a `TCon2_con_info`. + section ""data" . M.$WTCon2_closure" { + M.$WTCon2_closure: + const M.TCon2_con_info; + } + +(3) For a data con /worker/ `TCon2` that takes zero-width arguments only (and +whose wrapper is `$WTCon2`): because the arguments aren't relevant at runtime, +closures for it still only have the constructor info -- we can use a +precomputed static closure instead of allocating them on the heap, nonetheless. + However, unlike the worker in (1), `TCon2`, in taking arguments (regardless +of runtime representation), is unambiguously a function! Therefore, its +`TCon2_closure` actually contains the info of the function (`TCon2_info`) that returns the +constructor when called -- and as so it must remain -- if `TCon2` is ever used as +a function instead of in a saturated data con application, it better be one. + To generate in place of a saturated data con application of `TCon2`, we would + need something close to: + section ""data" . M.TCon2_some_sort_of_closure" { + M.TCon2_some_sort_of_closure: + const M.TCon2_con_info; -- Must be TCon2_con_info rather than TCon2_info which we have in TCon2_closure + } + But this turns out to be exactly the definition of this worker's wrapper's + static closure (see `$WTCon2_closure`). So, for the kind of worker in (3), + the precomputed static closure is the same as the one for the wrapper. + Invariant: These workers always have a wrapper of type (2) + +The solution that handles all of these cases turns out to be surprisingly +simple: A data con applied to an empty list of non-void arguments has a +precomputed static closure which is the tagged closure label of the var name of +the `dataConWrapId`, both for workers and wrappers. + For (1), `dataConWrapId` will return the Id of the worker because the wrapper + doesn't exist (i.e. `Wrk_closure+tag`). + For (2), `dataConWrapId` will return the Id of the wrapper for the wrapper (i.e. `$Wrp_closure+tag`). + For (3), `dataConWrapId` will return the Id of the wrapper, which must exist (i.e. `$Wrp_closure+tag`). + +As an example, since (2) and (3) might be hard to visualise, consider the datatype: + + data TCon2 a where + TCon2 :: TCon2 () + +and its STG representation post-unarisation: + + G.$WTCon2 :: G.TCon2 () + = G.TCon2! []; + + G.TCon2 :: forall {a}. (a GHC.Prim.~# ()) => G.TCon2 a + = {} \r [void_0E] G.TCon2 []; + +and the C--: + + section ""data" . G.$WTCon2_closure" { + G.$WTCon2_closure: + const G.TCon2_con_info; -- Static constructor info + } + + section ""data" . G.TCon2_closure" { + G.TCon2_closure: + const G.TCon2_info; -- Static function info + } + +The precomputed static closure for `$WTCon2` is `$WTCon2_closure+1`, and the +precomputed static closure for `TCon2` is also `$WTCon2_closure+1`; that is, +all saturated data con applications of `TCon2` and `$WTCon2` are compiled to +`$WTCon2_closure+1` instead of an allocation on the heap and +tagging of its pointer. -} -- (precomputedStaticConInfo_maybe cfg id con args) @@ -326,10 +425,11 @@ because they don't support cross package data references well. -- See Note [Precomputed static closures] precomputedStaticConInfo_maybe :: StgToCmmConfig -> Id -> DataCon -> [NonVoid StgArg] -> Maybe CgIdInfo precomputedStaticConInfo_maybe cfg binder con [] --- Nullary constructors - | isNullaryRepDataCon con - = Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) - (CmmLabel (mkClosureLabel (dataConName con) NoCafRefs)) + -- Nullary constructors (list of nonvoid args is null) + -- See Note [Precomputed static closures of nullary constructors] + = assert (hasNoNonZeroWidthArgs con) $ + Just $ litIdInfo (stgToCmmPlatform cfg) binder (mkConLFInfo con) + (CmmLabel (mkClosureLabel (varName $ dataConWrapId con) NoCafRefs)) precomputedStaticConInfo_maybe cfg binder con [arg] -- Int/Char values with existing closures in the RTS | intClosure || charClosure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbe3a85766f15268e012af363528d9e61368644f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbe3a85766f15268e012af363528d9e61368644f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 16:19:16 2023 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 28 Apr 2023 12:19:16 -0400 Subject: [Git][ghc/ghc][wip/romes/isNullaryRepDataCon] 153 commits: Allow WARNING pragmas to be controlled with custom categories Message-ID: <644bf20497b70_178e74111722ec0215204b@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/isNullaryRepDataCon at Glasgow Haskell Compiler / GHC Commits: f932c589 by Adam Gundry at 2023-03-24T02:36:09-04:00 Allow WARNING pragmas to be controlled with custom categories Closes #17209. This implements GHC Proposal 541, allowing a WARNING pragma to be annotated with a category like so: {-# WARNING in "x-partial" head "This function is undefined on empty lists." #-} The user can then enable, disable and set the severity of such warnings using command-line flags `-Wx-partial`, `-Werror=x-partial` and so on. There is a new warning group `-Wextended-warnings` containing all these warnings. Warnings without a category are treated as if the category was `deprecations`, and are (still) controlled by the flags `-Wdeprecations` and `-Wwarnings-deprecations`. Updates Haddock submodule. - - - - - 0426515b by Adam Gundry at 2023-03-24T02:36:09-04:00 Move mention of warning groups change to 9.8.1 release notes - - - - - b8d783d2 by Ben Gamari at 2023-03-24T02:36:45-04:00 nativeGen/AArch64: Fix bitmask immediate predicate Previously the predicate for determining whether a logical instruction operand could be encoded as a bitmask immediate was far too conservative. This meant that, e.g., pointer untagged required five instructions whereas it should only require one. Fixes #23030. - - - - - 46120bb6 by Joachim Breitner at 2023-03-24T13:09:43-04:00 User's guide: Improve docs for -Wall previously it would list the warnings _not_ enabled by -Wall. That’s unnecessary round-about and was out of date. So let's just name the relevant warnings (based on `compiler/GHC/Driver/Flags.hs`). - - - - - 509d1f11 by Ben Gamari at 2023-03-24T13:10:20-04:00 codeGen/tsan: Disable instrumentation of unaligned stores There is some disagreement regarding the prototype of `__tsan_unaligned_write` (specifically whether it takes just the written address, or the address and the value as an argument). Moreover, I have observed crashes which appear to be due to it. Disable instrumentation of unaligned stores as a temporary mitigation. Fixes #23096. - - - - - 6a73655f by Li-yao Xia at 2023-03-25T00:02:44-04:00 base: Document GHC versions associated with past base versions in the changelog - - - - - 43bd7694 by Teo Camarasu at 2023-03-25T00:03:24-04:00 Add regression test for #17574 This test currently fails in the nonmoving way - - - - - f2d56bf7 by Teo Camarasu at 2023-03-25T00:03:24-04:00 fix: account for large and compact object stats with nonmoving gc Make sure that we keep track of the size of large and compact objects that have been moved onto the nonmoving heap. We keep track of their size and add it to the amount of live bytes in nonmoving segments to get the total size of the live nonmoving heap. Resolves #17574 - - - - - 7131b705 by David Feuer at 2023-03-25T00:04:04-04:00 Modify ThreadId documentation and comments For a long time, `GHC.Conc.Sync` has said ```haskell -- ToDo: data ThreadId = ThreadId (Weak ThreadId#) -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ``` We are now actually capable of using `Weak# ThreadId#`, but the world has moved on. To support the `Show` and `Ord` instances, we'd need to store the thread ID number in the `ThreadId`. And it seems very difficult to continue to support `threadStatus` in that regime, since it needs to be able to explain how threads died. In addition, garbage collection of weak references can be quite expensive, and it would be hard to evaluate the cost over he whole ecosystem. As discussed in [this CLC issue](https://github.com/haskell/core-libraries-committee/issues/125), it doesn't seem very likely that we'll actually switch to weak references here. - - - - - c421bbbb by Ben Gamari at 2023-03-25T00:04:41-04:00 rts: Fix barriers of IND and IND_STATIC Previously IND and IND_STATIC lacked the acquire barriers enjoyed by BLACKHOLE. As noted in the (now updated) Note [Heap memory barriers], this barrier is critical to ensure that the indirectee is visible to the entering core. Fixes #22872. - - - - - 62fa7faa by Bodigrim at 2023-03-25T00:05:22-04:00 Improve documentation of atomicModifyMutVar2# - - - - - b2d14d0b by Cheng Shao at 2023-03-25T03:46:43-04:00 rts: use performBlockingMajorGC in hs_perform_gc and fix ffi023 This patch does a few things: - Add the missing RtsSymbols.c entry of performBlockingMajorGC - Make hs_perform_gc call performBlockingMajorGC, which restores previous behavior - Use hs_perform_gc in ffi023 - Remove rts_clearMemory() call in ffi023, it now works again in some test ways previously marked as broken. Fixes #23089 - - - - - d9ae24ad by Cheng Shao at 2023-03-25T03:46:44-04:00 testsuite: add the rts_clearMemory test case This patch adds a standalone test case for rts_clearMemory that mimics how it's typically used by wasm backend users and ensures this RTS API isn't broken by future RTS refactorings. Fixes #23901. - - - - - 80729d96 by Bodigrim at 2023-03-25T03:47:22-04:00 Improve documentation for resizing of byte arrays - - - - - c6ec4cd1 by Ben Gamari at 2023-03-25T20:23:47-04:00 rts: Don't rely on EXTERN_INLINE for slop-zeroing logic Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE. - - - - - c32abd4b by Ben Gamari at 2023-03-25T20:23:48-04:00 rts: Fix capability-count check in zeroSlop Previously `zeroSlop` examined `RtsFlags` to determine whether the program was single-threaded. This is wrong; a program may be started with `+RTS -N1` yet the process may later increase the capability count with `setNumCapabilities`. This lead to quite subtle and rare crashes. Fixes #23088. - - - - - 656d4cb3 by Ryan Scott at 2023-03-25T20:24:23-04:00 Add Eq/Ord instances for SSymbol, SChar, and SNat This implements [CLC proposal #148](https://github.com/haskell/core-libraries-committee/issues/148). - - - - - 4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00 Update and expand atomic modification Haddocks * The documentation for `atomicModifyIORef` and `atomicModifyIORef'` were incomplete, and the documentation for `atomicModifyIORef` was out of date. Update and expand. * Remove a useless lazy pattern match in the definition of `atomicModifyIORef`. The pair it claims to match lazily was already forced by `atomicModifyIORef2`. - - - - - e1fb56b2 by David Feuer at 2023-03-26T15:33:41-04:00 Document the constructor name for lists Derived `Data` instances use raw infix constructor names when applicable. The `Data.Data [a]` instance, if derived, would have a constructor name of `":"`. However, it actually uses constructor name `"(:)"`. Document this peculiarity. See https://github.com/haskell/core-libraries-committee/issues/147 - - - - - c1f755c4 by Simon Peyton Jones at 2023-03-27T22:09:41+01:00 Make exprIsConApp_maybe a bit cleverer Addresses #23159. See Note Note [Exploit occ-info in exprIsConApp_maybe] in GHC.Core.SimpleOpt. Compile times go down very slightly, but always go down, never up. Good! Metrics: compile_time/bytes allocated ------------------------------------------------ CoOpt_Singletons(normal) -1.8% T15703(normal) -1.2% GOOD geo. mean -0.1% minimum -1.8% maximum +0.0% Metric Decrease: CoOpt_Singletons T15703 - - - - - 76bb4c58 by Ryan Scott at 2023-03-28T08:12:08-04:00 Add COMPLETE pragmas to TypeRep, SSymbol, SChar, and SNat This implements [CLC proposal #149](https://github.com/haskell/core-libraries-committee/issues/149). - - - - - 3f374399 by sheaf at 2023-03-29T13:57:33+02:00 Handle records in the renamer This patch moves the field-based logic for disambiguating record updates to the renamer. The type-directed logic, scheduled for removal, remains in the typechecker. To do this properly (and fix the myriad of bugs surrounding the treatment of duplicate record fields), we took the following main steps: 1. Create GREInfo, a renamer-level equivalent to TyThing which stores information pertinent to the renamer. This allows us to uniformly treat imported and local Names in the renamer, as described in Note [GREInfo]. 2. Remove GreName. Instead of a GlobalRdrElt storing GreNames, which distinguished between normal names and field names, we now store simple Names in GlobalRdrElt, along with the new GREInfo information which allows us to recover the FieldLabel for record fields. 3. Add namespacing for record fields, within the OccNames themselves. This allows us to remove the mangling of duplicate field selectors. This change ensures we don't print mangled names to the user in error messages, and allows us to handle duplicate record fields in Template Haskell. 4. Move record disambiguation to the renamer, and operate on the level of data constructors instead, to handle #21443. The error message text for ambiguous record updates has also been changed to reflect that type-directed disambiguation is on the way out. (3) means that OccEnv is now a bit more complex: we first key on the textual name, which gives an inner map keyed on NameSpace: OccEnv a ~ FastStringEnv (UniqFM NameSpace a) Note that this change, along with (2), both increase the memory residency of GlobalRdrEnv = OccEnv [GlobalRdrElt], which causes a few tests to regress somewhat in compile-time allocation. Even though (3) simplified a lot of code (in particular the treatment of field selectors within Template Haskell and in error messages), it came with one important wrinkle: in the situation of -- M.hs-boot module M where { data A; foo :: A -> Int } -- M.hs module M where { data A = MkA { foo :: Int } } we have that M.hs-boot exports a variable foo, which is supposed to match with the record field foo that M exports. To solve this issue, we add a new impedance-matching binding to M foo{var} = foo{fld} This mimics the logic that existed already for impedance-binding DFunIds, but getting it right was a bit tricky. See Note [Record field impedance matching] in GHC.Tc.Module. We also needed to be careful to avoid introducing space leaks in GHCi. So we dehydrate the GlobalRdrEnv before storing it anywhere, e.g. in ModIface. This means stubbing out all the GREInfo fields, with the function forceGlobalRdrEnv. When we read it back in, we rehydrate with rehydrateGlobalRdrEnv. This robustly avoids any space leaks caused by retaining old type environments. Fixes #13352 #14848 #17381 #17551 #19664 #21443 #21444 #21720 #21898 #21946 #21959 #22125 #22160 #23010 #23062 #23063 Updates haddock submodule ------------------------- Metric Increase: MultiComponentModules MultiLayerModules MultiLayerModulesDefsGhci MultiLayerModulesNoCode T13701 T14697 hard_hole_fits ------------------------- - - - - - 4f1940f0 by sheaf at 2023-03-29T13:57:33+02:00 Avoid repeatedly shadowing in shadowNames This commit refactors GHC.Type.Name.Reader.shadowNames to first accumulate all the shadowing arising from the introduction of a new set of GREs, and then applies all the shadowing to the old GlobalRdrEnv in one go. - - - - - d246049c by sheaf at 2023-03-29T13:57:34+02:00 igre_prompt_env: discard "only-qualified" names We were unnecessarily carrying around names only available qualified in igre_prompt_env, violating the icReaderEnv invariant. We now get rid of these, as they aren't needed for the shadowing computation that igre_prompt_env exists for. Fixes #23177 ------------------------- Metric Decrease: T14052 T14052Type ------------------------- - - - - - 41a572f6 by Matthew Pickering at 2023-03-29T16:17:21-04:00 hadrian: Fix path to HpcParser.y The source for this project has been moved into a src/ folder so we also need to update this path. Fixes #23187 - - - - - b159e0e9 by doyougnu at 2023-03-30T01:40:08-04:00 js: split JMacro into JS eDSL and JS syntax This commit: Splits JExpr and JStat into two nearly identical DSLs: - GHC.JS.Syntax is the JMacro based DSL without unsaturation, i.e., a value cannot be unsaturated, or, a value of this DSL is a witness that a value of GHC.JS.Unsat has been saturated - GHC.JS.Unsat is the JMacro DSL from GHCJS with Unsaturation. Then all binary and outputable instances are changed to use GHC.JS.Syntax. This moves us closer to closing out #22736 and #22352. See #22736 for roadmap. ------------------------- Metric Increase: CoOpt_Read LargeRecord ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T10858 T11195 T11374 T11822 T12227 T12707 T13035 T13253 T13253-spj T13379 T14683 T15164 T15703 T16577 T17096 T17516 T17836 T18140 T18282 T18304 T18478 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T4801 T5321FD T5321Fun T5631 T5642 T783 T9198 T9233 T9630 TcPlugin_RewritePerf WWRec ------------------------- - - - - - f4f1f14f by Sylvain Henry at 2023-03-30T01:40:49-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. Also used the opportunity to reenable 64-bit Word/Int tests - - - - - a5360490 by Ben Gamari at 2023-03-30T01:41:25-04:00 testsuite: Fix racing prints in T21465 As noted in #23155, we previously failed to add flushes necessary to ensure predictable output. Fixes #23155. - - - - - 98b5cf67 by Matthew Pickering at 2023-03-30T09:58:40+01:00 Revert "ghc-heap: remove wrong Addr# coercion (#23181)" This reverts commit f4f1f14f8009c3c120b8b963ec130cbbc774ec02. This fails to build with GHC-9.2 as a boot compiler. See #23195 for tracking this issue. - - - - - 61a2dfaa by Bodigrim at 2023-03-30T14:35:57-04:00 Add {-# WARNING #-} to Data.List.{head,tail} - - - - - 8f15c47c by Bodigrim at 2023-03-30T14:35:57-04:00 Fixes to accomodate Data.List.{head,tail} with {-# WARNING #-} - - - - - 7c7dbade by Bodigrim at 2023-03-30T14:35:57-04:00 Bump submodules - - - - - d2d8251b by Bodigrim at 2023-03-30T14:35:57-04:00 Fix tests - - - - - 3d38dcb6 by sheaf at 2023-03-30T14:35:57-04:00 Proxies for head and tail: review suggestions - - - - - 930edcfd by sheaf at 2023-03-30T14:36:33-04:00 docs: move RecordUpd changelog entry to 9.8 This was accidentally included in the 9.6 changelog instead of the 9.6 changelog. - - - - - 6f885e65 by sheaf at 2023-03-30T14:37:09-04:00 Add LANGUAGE GADTs to GHC.Rename.Env We need to enable this extension for the file to compile with ghc 9.2, as we are pattern matching on a GADT and this required the GADT extension to be enabled until 9.4. - - - - - 6d6a37a8 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: make lint-ci-config job fast again We don't pin our nixpkgs revision and tracks the default nixpkgs-unstable channel anyway. Instead of using haskell.packages.ghc924, we should be using haskell.packages.ghc92 to maximize the binary cache hit rate and make lint-ci-config job fast again. Also bumps the nix docker image to the latest revision. - - - - - ef1548c4 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: ensure that all non-i386 pipelines do parallel xz compression We can safely enable parallel xz compression for non-i386 pipelines. However, previously we didn't export XZ_OPT, so the xz process won't see it if XZ_OPT hasn't already been set in the current job. - - - - - 20432d16 by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: unset CROSS_EMULATOR for js job - - - - - 4a24dbbe by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: fix lint-testsuite job The list_broken make target will transitively depend on the calibrate.out target, which used STAGE1_GHC instead of TEST_HC. It really should be TEST_HC since that's what get passed in the gitlab CI config. - - - - - cea56ccc by Cheng Shao at 2023-03-30T18:42:56+00:00 ci: use alpine3_17-wasm image for wasm jobs Bump the ci-images dependency and use the new alpine3_17-wasm docker image for wasm jobs. - - - - - 79d0cb32 by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Add basic support for testing cross-compilers - - - - - e7392b4e by Ben Gamari at 2023-03-30T18:43:53+00:00 testsuite/driver: Normalize away differences in ghc executable name - - - - - ee160d06 by Ben Gamari at 2023-03-30T18:43:53+00:00 hadrian: Pass CROSS_EMULATOR to runtests.py - - - - - 30c84511 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: don't add optllvm way for wasm32 - - - - - f1beee36 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: normalize the .wasm extension - - - - - a984a103 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: strip the cross ghc prefix in output and error message - - - - - f7478d95 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: handle target executable extension - - - - - 8fe8b653 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: mypy typing error fixes This patch fixes some mypy typing errors which weren't caught in previous linting jobs. - - - - - 0149f32f by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: use context variable instead of thread-local variable This patch changes a thread-local variable to context variable instead, which works as intended when the testsuite transitions to use asyncio & coroutines instead of multi-threading to concurrently run test cases. Note that this also raises the minimum Python version to 3.7. - - - - - ea853ff0 by Cheng Shao at 2023-03-30T18:43:53+00:00 testsuite: asyncify the testsuite driver This patch refactors the testsuite driver, gets rid of multi-threading logic for running test cases concurrently, and uses asyncio & coroutines instead. This is not yak shaving for its own sake; the previous multi-threading logic is prone to livelock/deadlock conditions for some reason, even if the total number of threads is bounded to a thread pool's capacity. The asyncify change is an internal implementation detail of the testsuite driver and does not impact most GHC maintainers out there. The patch does not touch the .T files, test cases can be added/modified the exact same way as before. - - - - - 0077cb22 by Matthew Pickering at 2023-03-31T21:28:28-04:00 Add test for T23184 There was an outright bug, which Simon fixed in July 2021, as a little side-fix on a complicated patch: ``` commit 6656f0165a30fc2a22208532ba384fc8e2f11b46 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Fri Jul 23 23:57:01 2021 +0100 A bunch of changes related to eta reduction This is a large collection of changes all relating to eta reduction, originally triggered by #18993, but there followed a long saga. Specifics: ...lots of lines omitted... Other incidental changes * Fix a fairly long-standing outright bug in the ApplyToVal case of GHC.Core.Opt.Simplify.mkDupableContWithDmds. I was failing to take the tail of 'dmds' in the recursive call, which meant the demands were All Wrong. I have no idea why this has not caused problems before now. ``` Note this "Fix a fairly longstanding outright bug". This is the specific fix ``` @@ -3552,8 +3556,8 @@ mkDupableContWithDmds env dmds -- let a = ...arg... -- in [...hole...] a -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable - do { let (dmd:_) = dmds -- Never fails - ; (floats1, cont') <- mkDupableContWithDmds env dmds cont + do { let (dmd:cont_dmds) = dmds -- Never fails + ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont ; let env' = env `setInScopeFromF` floats1 ; (_, se', arg') <- simplArg env' dup se arg ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg' ``` Ticket #23184 is a report of the bug that this diff fixes. - - - - - 62d25071 by mangoiv at 2023-04-01T04:20:01-04:00 [feat] make ($) representation polymorphic - this change was approved by the CLC in [1] following a CLC proposal [2] - make ($) representation polymorphic (adjust the type signature) - change ($) implementation to allow additional polymorphism - adjust the haddock of ($) to reflect these changes - add additional documentation to document these changes - add changelog entry - adjust tests (move now succeeding tests and adjust stdout of some tests) [1] https://github.com/haskell/core-libraries-committee/issues/132#issuecomment-1487456854 [2] https://github.com/haskell/core-libraries-committee/issues/132 - - - - - 77c33fb9 by Artem Pelenitsyn at 2023-04-01T04:20:41-04:00 User Guide: update copyright year: 2020->2023 - - - - - 3b5be05a by doyougnu at 2023-04-01T09:42:31-04:00 driver: Unit State Data.Map -> GHC.Unique.UniqMap In pursuit of #22426. The driver and unit state are major contributors. This commit also bumps the haddock submodule to reflect the API changes in UniqMap. ------------------------- Metric Decrease: MultiComponentModules MultiComponentModulesRecomp T10421 T10547 T12150 T12234 T12425 T13035 T16875 T18140 T18304 T18698a T18698b T18923 T20049 T5837 T6048 T9198 ------------------------- - - - - - a84fba6e by Torsten Schmits at 2023-04-01T09:43:12-04:00 Add structured error messages for GHC.Tc.TyCl Tracking ticket: #20117 MR: !10183 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 6e2eb275 by doyougnu at 2023-04-01T18:27:56-04:00 JS: Linker: use saturated JExpr Follow on to MR!10142 in pursuit of #22736 - - - - - 3da69346 by sheaf at 2023-04-01T18:28:37-04:00 Improve haddocks of template-haskell Con datatype This adds a bit more information, in particular about the lists of constructors in the GadtC and RecGadtC cases. - - - - - 3b7bbb39 by sheaf at 2023-04-01T18:28:37-04:00 TH: revert changes to GadtC & RecGadtC Commit 3f374399 included a breaking-change to the template-haskell library when it made the GadtC and RecGadtC constructors take non-empty lists of names. As this has the potential to break many users' packages, we decided to revert these changes for now. - - - - - f60f6110 by Bodigrim at 2023-04-02T18:59:30-04:00 Rework documentation for data Char - - - - - 43ebd5dc by Bodigrim at 2023-04-02T19:00:09-04:00 cmm: implement parsing of MO_AtomicRMW from hand-written CMM files Fixes #23206 - - - - - ab9cd52d by Sylvain Henry at 2023-04-03T08:15:21-04:00 ghc-heap: remove wrong Addr# coercion (#23181) Conversion from Addr# to I# isn't correct with the JS backend. - - - - - 2b2afff3 by Matthew Pickering at 2023-04-03T08:15:58-04:00 hadrian: Update bootstrap plans for 9.2.6, 9.2.7, 9.4.4, 9.4.5, 9.6.1 Also fixes the ./generate_bootstrap_plans script which was recently broken We can hopefully drop the 9.2 plans soon but they still work so kept them around for now. - - - - - c2605e25 by Matthew Pickering at 2023-04-03T08:15:58-04:00 ci: Add job to test 9.6 bootstrapping - - - - - 53e4d513 by Krzysztof Gogolewski at 2023-04-03T08:16:35-04:00 hadrian: Improve option parsing Several options in Hadrian had their argument marked as optional (`OptArg`), but if the argument wasn't there they were just giving an error. It's more idiomatic to mark the argument as required instead; the code uses less Maybes, the parser can enforce that the argument is present, --help gives better output. - - - - - a8e36892 by Sylvain Henry at 2023-04-03T08:17:16-04:00 JS: fix issues with FD api support - Add missing implementations for fcntl_read/write/lock - Fix fdGetMode These were found while implementing TH in !9779. These functions must be used somehow by the external interpreter code. - - - - - 8b092910 by Haskell-mouse at 2023-04-03T19:31:26-04:00 Convert diagnostics in GHC.Rename.HsType to proper TcRnMessage I've turned all occurrences of TcRnUnknownMessage in GHC.Rename.HsType module into a proper TcRnMessage. Instead, these TcRnMessage messages were introduced: TcRnDataKindsError TcRnUnusedQuantifiedTypeVar TcRnIllegalKindSignature TcRnUnexpectedPatSigType TcRnSectionPrecedenceError TcRnPrecedenceParsingError TcRnIllegalKind TcRnNegativeNumTypeLiteral TcRnUnexpectedKindVar TcRnBindMultipleVariables TcRnBindVarAlreadyInScope - - - - - 220a7a48 by Krzysztof Gogolewski at 2023-04-03T19:32:02-04:00 Fixes around unsafeCoerce# 1. `unsafeCoerce#` was documented in `GHC.Prim`. But since the overhaul in 74ad75e87317, `unsafeCoerce#` is no longer defined there. I've combined the documentation in `GHC.Prim` with the `Unsafe.Coerce` module. 2. The documentation of `unsafeCoerce#` stated that you should not cast a function to an algebraic type, even if you later cast it back before applying it. But ghci was doing that type of cast, as can be seen with 'ghci -ddump-ds' and typing 'x = not'. I've changed it to use Any following the documentation. - - - - - 9095e297 by Matthew Craven at 2023-04-04T01:04:10-04:00 Add a few more memcpy-ish primops * copyMutableByteArrayNonOverlapping# * copyAddrToAddr# * copyAddrToAddrNonOverlapping# * setAddrRange# The implementations of copyBytes, moveBytes, and fillBytes in base:Foreign.Marshal.Utils now use these new primops, which can cause us to work a bit harder generating code for them, resulting in the metric increase in T21839c observed by CI on some architectures. But in exchange, we get better code! Metric Increase: T21839c - - - - - f7da530c by Matthew Craven at 2023-04-04T01:04:10-04:00 StgToCmm: Upgrade -fcheck-prim-bounds behavior Fixes #21054. Additionally, we can now check for range overlap when generating Cmm for primops that use memcpy internally. - - - - - cd00e321 by sheaf at 2023-04-04T01:04:50-04:00 Relax assertion in varToRecFieldOcc When using Template Haskell, it is possible to re-parent a field OccName belonging to one data constructor to another data constructor. The lsp-types package did this in order to "extend" a data constructor with additional fields. This ran into an assertion in 'varToRecFieldOcc'. This assertion can simply be relaxed, as the resulting splices are perfectly sound. Fixes #23220 - - - - - eed0d930 by Sylvain Henry at 2023-04-04T11:09:15-04:00 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201) - - - - - 071139c3 by Ryan Scott at 2023-04-04T11:09:51-04:00 Make INLINE pragmas for pattern synonyms work with TH Previously, the code for converting `INLINE <name>` pragmas from TH splices used `vNameN`, which assumed that `<name>` must live in the variable namespace. Pattern synonyms, on the other hand, live in the constructor namespace. I've fixed the issue by switching to `vcNameN` instead, which works for both the variable and constructor namespaces. Fixes #23203. - - - - - 7c16f3be by Krzysztof Gogolewski at 2023-04-04T17:13:00-04:00 Fix unification with oversaturated type families unify_ty was incorrectly saying that F x y ~ T x are surely apart, where F x y is an oversaturated type family and T x is a tyconapp. As a result, the simplifier dropped a live case alternative (#23134). - - - - - c165f079 by sheaf at 2023-04-04T17:13:40-04:00 Add testcase for #23192 This issue around solving of constraints arising from superclass expansion using other constraints also borned from superclass expansion was the topic of commit aed1974e. That commit made sure we don't emit a "redundant constraint" warning in a situation in which removing the constraint would cause errors. Fixes #23192 - - - - - d1bb16ed by Ben Gamari at 2023-04-06T03:40:45-04:00 nonmoving: Disable slop-zeroing As noted in #23170, the nonmoving GC can race with a mutator zeroing the slop of an updated thunk (in much the same way that two mutators would race). Consequently, we must disable slop-zeroing when the nonmoving GC is in use. Closes #23170 - - - - - 04b80850 by Brandon Chinn at 2023-04-06T03:41:21-04:00 Fix reverse flag for -Wunsupported-llvm-version - - - - - 0c990e13 by Pierre Le Marre at 2023-04-06T10:16:29+00:00 Add release note for GHC.Unicode refactor in base-4.18. Also merge CLC proposal 130 in base-4.19 with CLC proposal 59 in base-4.18 and add proper release date. - - - - - cbbfb283 by Alex Dixon at 2023-04-07T18:27:45-04:00 Improve documentation for ($) (#22963) - - - - - 5193c2b0 by Alex Dixon at 2023-04-07T18:27:45-04:00 Remove trailing whitespace from ($) commentary - - - - - b384523b by Sebastian Graf at 2023-04-07T18:27:45-04:00 Adjust wording wrt representation polymorphism of ($) - - - - - 6a788f0a by Torsten Schmits at 2023-04-07T22:29:28-04:00 Add structured error messages for GHC.Tc.TyCl.Utils Tracking ticket: #20117 MR: !10251 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 3ba77b36 by sheaf at 2023-04-07T22:30:07-04:00 Renamer: don't call addUsedGRE on an exact Name When looking up a record field in GHC.Rename.Env.lookupRecFieldOcc, we could end up calling addUsedGRE on an exact Name, which would then lead to a panic in the bestImport function: it would be incapable of processing a GRE which is not local but also not brought into scope by any imports (as it is referred to by its unique instead). Fixes #23240 - - - - - bc4795d2 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add support for -debug in the testsuite Confusingly, GhcDebugged referred to GhcDebugAssertions. - - - - - b7474b57 by Krzysztof Gogolewski at 2023-04-11T19:24:54-04:00 Add missing cases in -Di prettyprinter Fixes #23142 - - - - - 6c392616 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: make WasmCodeGenM an instance of MonadUnique - - - - - 05d26a65 by Cheng Shao at 2023-04-11T19:25:31-04:00 compiler: apply cmm node-splitting for wasm backend This patch applies cmm node-splitting for wasm32 NCG, which is required when handling irreducible CFGs. Fixes #23237. - - - - - f1892cc0 by Bodigrim at 2023-04-11T19:26:09-04:00 Set base 'maintainer' field to CLC - - - - - ecf22da3 by Simon Peyton Jones at 2023-04-11T19:26:45-04:00 Clarify a couple of Notes about 'nospec' - - - - - ebd8918b by Oleg Grenrus at 2023-04-12T12:32:57-04:00 Allow generation of TTH syntax with TH In other words allow generation of typed splices and brackets with Untyped Template Haskell. That is useful in cases where a library is build with TTH in mind, but we still want to generate some auxiliary declarations, where TTH cannot help us, but untyped TH can. Such example is e.g. `staged-sop` which works with TTH, but we would like to derive `Generic` declarations with TH. An alternative approach is to use `unsafeCodeCoerce`, but then the derived `Generic` instances would be type-checked only at use sites, i.e. much later. Also `-ddump-splices` output is quite ugly: user-written instances would use TTH brackets, not `unsafeCodeCoerce`. This commit doesn't allow generating of untyped template splices and brackets with untyped TH, as I don't know why one would want to do that (instead of merging the splices, e.g.) - - - - - 690d0225 by Rodrigo Mesquita at 2023-04-12T12:33:33-04:00 Add regression test for #23229 - - - - - 59321879 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quotRem rules (#22152) case quotRemInt# x y of (# q, _ #) -> body ====> case quotInt# x y of q -> body case quotRemInt# x y of (# _, r #) -> body ====> case remInt# x y of r -> body - - - - - 4dd02122 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Add quot folding rule (#22152) (x / l1) / l2 l1 and l2 /= 0 l1*l2 doesn't overflow ==> x / (l1 * l2) - - - - - 1148ac72 by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make Int64/Word64 division ok for speculation too. Only when the divisor is definitely non-zero. - - - - - 8af401cc by Sylvain Henry at 2023-04-13T08:50:33-04:00 Make WordQuotRem2Op ok-for-speculation too - - - - - 27d2978e by Josh Meredith at 2023-04-13T08:51:09-04:00 Base/JS: GHC.JS.Foreign.Callback module (issue 23126) * Add the Callback module for "exporting" Haskell functions to be available to plain JavaScript code * Fix some primitives defined in GHC.JS.Prim * Add a JavaScript section to the user guide with instructions on how to use the JavaScript FFI, building up to using Callbacks to interact with the browser * Add tests for the JavaScript FFI and Callbacks - - - - - a34aa8da by Adam Sandberg Ericsson at 2023-04-14T04:17:52-04:00 rts: improve memory ordering and add some comments in the StablePtr implementation - - - - - d7a768a4 by Matthew Pickering at 2023-04-14T04:18:28-04:00 docs: Generate docs/index.html with version number * Generate docs/index.html to include the version of the ghc library * This also fixes the packageVersions interpolations which were - Missing an interpolation for `LIBRARY_ghc_VERSION` - Double quoting the version so that "9.7" was being inserted. Fixes #23121 - - - - - d48fbfea by Simon Peyton Jones at 2023-04-14T04:19:05-04:00 Stop if type constructors have kind errors Otherwise we get knock-on errors, such as #23252. This makes GHC fail a bit sooner, and I have not attempted to add recovery code, to add a fake TyCon place of the erroneous one, in an attempt to get more type errors in one pass. We could do that (perhaps) if there was a call for it. - - - - - 2371d6b2 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Major refactor in the handling of equality constraints This MR substantially refactors the way in which the constraint solver deals with equality constraints. The big thing is: * Intead of a pipeline in which we /first/ canonicalise and /then/ interact (the latter including performing unification) the two steps are more closely integreated into one. That avoids the current rather indirect communication between the two steps. The proximate cause for this refactoring is fixing #22194, which involve solving [W] alpha[2] ~ Maybe (F beta[4]) by doing this: alpha[2] := Maybe delta[2] [W] delta[2] ~ F beta[4] That is, we don't promote beta[4]! This is very like introducing a cycle breaker, and was very awkward to do before, but now it is all nice. See GHC.Tc.Utils.Unify Note [Promotion and level-checking] and Note [Family applications in canonical constraints]. The big change is this: * Several canonicalisation checks (occurs-check, cycle-breaking, checking for concreteness) are combined into one new function: GHC.Tc.Utils.Unify.checkTyEqRhs This function is controlled by `TyEqFlags`, which says what to do for foralls, type families etc. * `canEqCanLHSFinish` now sees if unification is possible, and if so, actually does it: see `canEqCanLHSFinish_try_unification`. There are loads of smaller changes: * The on-the-fly unifier `GHC.Tc.Utils.Unify.unifyType` has a cheap-and-cheerful version of `checkTyEqRhs`, called `simpleUnifyCheck`. If `simpleUnifyCheck` succeeds, it can unify, otherwise it defers by emitting a constraint. This is simpler than before. * I simplified the swapping code in `GHC.Tc.Solver.Equality.canEqCanLHS`. Especially the nasty stuff involving `swap_for_occurs` and `canEqTyVarFunEq`. Much nicer now. See Note [Orienting TyVarLHS/TyFamLHS] Note [Orienting TyFamLHS/TyFamLHS] * Added `cteSkolemOccurs`, `cteConcrete`, and `cteCoercionHole` to the problems that can be discovered by `checkTyEqRhs`. * I fixed #23199 `pickQuantifiablePreds`, which actually allows GHC to to accept both cases in #22194 rather than rejecting both. Yet smaller: * Added a `synIsConcrete` flag to `SynonymTyCon` (alongside `synIsFamFree`) to reduce the need for synonym expansion when checking concreteness. Use it in `isConcreteType`. * Renamed `isConcrete` to `isConcreteType` * Defined `GHC.Core.TyCo.FVs.isInjectiveInType` as a more efficient way to find if a particular type variable is used injectively than finding all the injective variables. It is called in `GHC.Tc.Utils.Unify.definitely_poly`, which in turn is used quite a lot. * Moved `rewriterView` to `GHC.Core.Type`, so we can use it from the constraint solver. Fixes #22194, #23199 Compile times decrease by an average of 0.1%; but there is a 7.4% drop in compiler allocation on T15703. Metric Decrease: T15703 - - - - - 99b2734b by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Add some documentation about redundant constraints - - - - - 3f2d0eb8 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Improve partial signatures This MR fixes #23223. The changes are in two places: * GHC.Tc.Bind.checkMonomorphismRestriction See the new `Note [When the MR applies]` We now no longer stupidly attempt to apply the MR when the user specifies a context, e.g. f :: Eq a => _ -> _ * GHC.Tc.Solver.decideQuantification See rewritten `Note [Constraints in partial type signatures]` Fixing this bug apparently breaks three tests: * partial-sigs/should_compile/T11192 * partial-sigs/should_fail/Defaulting1MROff * partial-sigs/should_fail/T11122 However they are all symptoms of #23232, so I'm marking them as expect_broken(23232). I feel happy about this MR. Nice. - - - - - 23e2a8a0 by Simon Peyton Jones at 2023-04-14T20:01:02+02:00 Make approximateWC a bit cleverer This MR fixes #23224: making approximateWC more clever See the long `Note [ApproximateWC]` in GHC.Tc.Solver All this is delicate and ad-hoc -- but it /has/ to be: we are talking about inferring a type for a binding in the presence of GADTs, type families and whatnot: known difficult territory. We just try as hard as we can. - - - - - 2c040246 by Matthew Pickering at 2023-04-15T00:57:14-04:00 docs: Update template-haskell docs to use Code Q a rather than Q (TExp a) Since GHC Proposal #195, the type of [|| ... ||] has been Code Q a rather than Q (TExp a). The documentation in the `template-haskell` library wasn't updated to reflect this change. Fixes #23148 - - - - - 0da18eb7 by Krzysztof Gogolewski at 2023-04-15T14:35:53+02:00 Show an error when we cannot default a concrete tyvar Fixes #23153 - - - - - bad2f8b8 by sheaf at 2023-04-15T15:14:36+02:00 Handle ConcreteTvs in inferResultToType inferResultToType was discarding the ir_frr information, which meant some metavariables ended up being MetaTvs instead of ConcreteTvs. This function now creates new ConcreteTvs as necessary, instead of always creating MetaTvs. Fixes #23154 - - - - - 3b0ea480 by Simon Peyton Jones at 2023-04-16T18:12:20-04:00 Transfer DFunId_ness onto specialised bindings Whether a binding is a DFunId or not has consequences for the `-fdicts-strict` flag, essentially if we are doing demand analysis for a DFunId then `-fdicts-strict` does not apply because the constraint solver can create recursive groups of dictionaries. In #22549 this was fixed for the "normal" case, see Note [Do not strictify the argument dictionaries of a dfun]. However the loop still existed if the DFunId was being specialised. The problem was that the specialiser would specialise a DFunId and turn it into a VanillaId and so the demand analyser didn't know to apply special treatment to the binding anymore and the whole recursive group was optimised to bottom. The solution is to transfer over the DFunId-ness of the binding in the specialiser so that the demand analyser knows not to apply the `-fstrict-dicts`. Fixes #22549 - - - - - a1371ebb by Oleg Grenrus at 2023-04-16T18:12:59-04:00 Add import lists to few GHC.Driver.Session imports Related to https://gitlab.haskell.org/ghc/ghc/-/issues/23261. There are a lot of GHC.Driver.Session which only use DynFlags, but not the parsing code. - - - - - 51479ceb by Matthew Pickering at 2023-04-17T08:08:48-04:00 Account for special GHC.Prim import in warnUnusedPackages The GHC.Prim import is treated quite specially primarily because there isn't an interface file for GHC.Prim. Therefore we record separately in the ModSummary if it's imported or not so we don't go looking for it. This logic hasn't made it's way to `-Wunused-packages` so if you imported GHC.Prim then the warning would complain you didn't use `-package ghc-prim`. Fixes #23212 - - - - - 1532a8b2 by Simon Peyton Jones at 2023-04-17T08:09:24-04:00 Add regression test for #23199 - - - - - 0158c5f1 by Ryan Scott at 2023-04-17T18:43:27-04:00 validDerivPred: Reject exotic constraints in IrredPreds This brings the `IrredPred` case in sync with the treatment of `ClassPred`s as described in `Note [Valid 'deriving' predicate]` in `GHC.Tc.Validity`. Namely, we should reject `IrredPred`s that are inferred from `deriving` clauses whose arguments contain other type constructors, as described in `(VD2) Reject exotic constraints` of that Note. This has the nice property that `deriving` clauses whose inferred instance context mention `TypeError` will now emit the type error in the resulting error message, which better matches existing intuitions about how `TypeError` should work. While I was in town, I noticed that much of `Note [Valid 'deriving' predicate]` was duplicated in a separate `Note [Exotic derived instance contexts]` in `GHC.Tc.Deriv.Infer`. I decided to fold the latter Note into the former so that there is a single authority on describing the conditions under which an inferred `deriving` constraint can be considered valid. This changes the behavior of `deriving` in a way that existing code might break, so I have made a mention of this in the GHC User's Guide. It seems very, very unlikely that much code is relying on this strange behavior, however, and even if there is, there is a clear, backwards-compatible migration path using `StandaloneDeriving`. Fixes #22696. - - - - - 10364818 by Krzysztof Gogolewski at 2023-04-17T18:44:03-04:00 Misc cleanup - Use dedicated list functions - Make cloneBndrs and cloneRecIdBndrs monadic - Fix invalid haddock comments in libraries/base - - - - - 5e1d33d7 by Matthew Pickering at 2023-04-18T10:31:02-04:00 Convert interface file loading errors into proper diagnostics This patch converts all the errors to do with loading interface files into proper structured diagnostics. * DriverMessage: Sometimes in the driver we attempt to load an interface file so we embed the IfaceMessage into the DriverMessage. * TcRnMessage: Most the time we are loading interface files during typechecking, so we embed the IfaceMessage This patch also removes the TcRnInterfaceLookupError constructor which is superceded by the IfaceMessage, which is now structured compared to just storing an SDoc before. - - - - - df1a5811 by sheaf at 2023-04-18T10:31:43-04:00 Don't panic in ltPatersonSize The function GHC.Tc.Utils.TcType.ltPatersonSize would panic when it encountered a type family on the RHS, as usually these are not allowed (type families are not allowed on the RHS of class instances or of quantified constraints). However, it is possible to still encounter type families on the RHS after doing a bit of constraint solving, as seen in test case T23171. This could trigger the panic in the call to ltPatersonSize in GHC.Tc.Solver.Canonical.mk_strict_superclasses, which is involved in avoiding loopy superclass constraints. This patch simply changes ltPatersonSize to return "I don't know, because there's a type family involved" in these cases. Fixes #23171 - - - - - d442ac05 by Sylvain Henry at 2023-04-19T20:04:35-04:00 JS: fix thread-related primops - - - - - 7a96f90b by Bryan Richter at 2023-04-19T20:05:11-04:00 CI: Disable abi-test-nightly See #23269 - - - - - ab6c1d29 by Sylvain Henry at 2023-04-19T20:05:50-04:00 Testsuite: don't use obsolescent egrep (#22351) Recent egrep displays the following message, breaking golden tests: egrep: warning: egrep is obsolescent; using grep -E Switch to using "grep -E" instead - - - - - f15b0ce5 by Matthew Pickering at 2023-04-20T11:01:06-04:00 hadrian: Pass haddock file arguments in a response file In !10119 CI was failing on windows because the command line was too long. We can mitigate this by passing the file arguments to haddock in a response file. We can't easily pass all the arguments in a response file because the `+RTS` arguments can't be placed in the response file. Fixes #23273 - - - - - 7012ec2f by tocic at 2023-04-20T11:01:42-04:00 Fix doc typo in GHC.Read.readList - - - - - 5c873124 by sheaf at 2023-04-20T18:33:34-04:00 Implement -jsem: parallelism controlled by semaphores See https://github.com/ghc-proposals/ghc-proposals/pull/540/ for a complete description for the motivation for this feature. The `-jsem` option allows a build tool to pass a semaphore to GHC which GHC can use in order to control how much parallelism it requests. GHC itself acts as a client in the GHC jobserver protocol. ``` GHC Jobserver Protocol ~~~~~~~~~~~~~~~~~~~~~~ This proposal introduces the GHC Jobserver Protocol. This protocol allows a server to dynamically invoke many instances of a client process, while restricting all of those instances to use no more than <n> capabilities. This is achieved by coordination over a system semaphore (either a POSIX semaphore [6]_ in the case of Linux and Darwin, or a Win32 semaphore [7]_ in the case of Windows platforms). There are two kinds of participants in the GHC Jobserver protocol: - The *jobserver* creates a system semaphore with a certain number of available tokens. Each time the jobserver wants to spawn a new jobclient subprocess, it **must** first acquire a single token from the semaphore, before spawning the subprocess. This token **must** be released once the subprocess terminates. Once work is finished, the jobserver **must** destroy the semaphore it created. - A *jobclient* is a subprocess spawned by the jobserver or another jobclient. Each jobclient starts with one available token (its *implicit token*, which was acquired by the parent which spawned it), and can request more tokens through the Jobserver Protocol by waiting on the semaphore. Each time a jobclient wants to spawn a new jobclient subprocess, it **must** pass on a single token to the child jobclient. This token can either be the jobclient's implicit token, or another token which the jobclient acquired from the semaphore. Each jobclient **must** release exactly as many tokens as it has acquired from the semaphore (this does not include the implicit tokens). ``` Build tools such as cabal act as jobservers in the protocol and are responsibile for correctly creating, cleaning up and managing the semaphore. Adds a new submodule (semaphore-compat) for managing and interacting with semaphores in a cross-platform way. Fixes #19349 - - - - - 52d3e9b4 by Ben Gamari at 2023-04-20T18:34:11-04:00 rts: Initialize Array# header in listThreads# Previously the implementation of listThreads# failed to initialize the header of the created array, leading to various nastiness. Fixes #23071 - - - - - 1db30fe1 by Ben Gamari at 2023-04-20T18:34:11-04:00 testsuite: Add test for #23071 - - - - - dae514f9 by tocic at 2023-04-21T13:31:21-04:00 Fix doc typos in libraries/base/GHC - - - - - 113e21d7 by Sylvain Henry at 2023-04-21T13:32:01-04:00 Testsuite: replace some js_broken/js_skip predicates with req_c Using req_c is more precise. - - - - - 038bb031 by Krzysztof Gogolewski at 2023-04-21T18:03:04-04:00 Minor doc fixes - Add docs/index.html to .gitignore. It is created by ./hadrian/build docs, and it was the only file in Hadrian's templateRules not present in .gitignore. - Mention that MultiWayIf supports non-boolean guards - Remove documentation of optdll - removed in 2007, 763daed95 - Fix markdown syntax - - - - - e826cdb2 by amesgen at 2023-04-21T18:03:44-04:00 User's guide: DeepSubsumption is implied by Haskell{98,2010} - - - - - 499a1c20 by PHO at 2023-04-23T13:39:32-04:00 Implement executablePath for Solaris and make getBaseDir less platform-dependent Use base-4.17 executablePath when possible, and fall back on getExecutablePath when it's not available. The sole reason why getBaseDir had #ifdef's was apparently that getExecutablePath wasn't reliable, and we could reduce the number of CPP conditionals by making use of executablePath instead. Also export executablePath on js_HOST_ARCH. - - - - - 97a6f7bc by tocic at 2023-04-23T13:40:08-04:00 Fix doc typos in libraries/base - - - - - 787c6e8c by Ben Gamari at 2023-04-24T12:19:06-04:00 testsuite/T20137: Avoid impl.-defined behavior Previously we would cast pointers to uint64_t. However, implementations are allowed to either zero- or sign-extend such casts. Instead cast to uintptr_t to avoid this. Fixes #23247. - - - - - 87095f6a by Cheng Shao at 2023-04-24T12:19:44-04:00 rts: always build 64-bit atomic ops This patch does a few things: - Always build 64-bit atomic ops in rts/ghc-prim, even on 32-bit platforms - Remove legacy "64bit" cabal flag of rts package - Fix hs_xchg64 function prototype for 32-bit platforms - Fix AtomicFetch test for wasm32 - - - - - 2685a12d by Cheng Shao at 2023-04-24T12:20:21-04:00 compiler: don't install signal handlers when the host platform doesn't have signals Previously, large parts of GHC API will transitively invoke withSignalHandlers, which doesn't work on host platforms without signal functionality at all (e.g. wasm32-wasi). By making withSignalHandlers a no-op on those platforms, we can make more parts of GHC API work out of the box when signals aren't supported. - - - - - 1338b7a3 by Cheng Shao at 2023-04-24T16:21:30-04:00 hadrian: fix non-ghc program paths passed to testsuite driver when testing cross GHC - - - - - 1a10f556 by Bodigrim at 2023-04-24T16:22:09-04:00 Add since pragma to Data.Functor.unzip - - - - - 0da9e882 by Soham Chowdhury at 2023-04-25T00:15:22-04:00 More informative errors for bad imports (#21826) - - - - - ebd5b078 by Josh Meredith at 2023-04-25T00:15:58-04:00 JS/base: provide implementation for mkdir (issue 22374) - - - - - 8f656188 by Josh Meredith at 2023-04-25T18:12:38-04:00 JS: Fix h$base_access implementation (issue 22576) - - - - - 74c55712 by Andrei Borzenkov at 2023-04-25T18:13:19-04:00 Give more guarntees about ImplicitParams (#23289) - Added new section in the GHC user's guide that legends behavior of nested implicit parameter bindings in these two cases: let ?f = 1 in let ?f = 2 in ?f and data T where MkT :: (?f :: Int) => T f :: T -> T -> Int f MkT MkT = ?f - Added new test case to examine this behavior. - - - - - c30ac25f by Sebastian Graf at 2023-04-26T14:50:51-04:00 DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208) In #23208 we observed that the demand signature of a binder occuring in a RULE wasn't unleashed, leading to a transitively used binder being discarded as absent. The solution was to use the same code path that we already use for handling exported bindings. See the changes to `Note [Absence analysis for stable unfoldings and RULES]` for more details. I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a `VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our existing framework. As a result, I had to touch quite a few places in the code. This refactoring exposed a few small bugs around correct handling of bottoming demand environments. As a result, some strictness signatures now mention uniques that weren't there before which caused test output changes to T13143, T19969 and T22112. But these tests compared whole -ddump-simpl listings which is a very fragile thing to begin with. I changed what exactly they test for based on the symptoms in the corresponding issues. There is a single regression in T18894 because we are more conservative around stable unfoldings now. Unfortunately it is not easily fixed; let's wait until there is a concrete motivation before invest more time. Fixes #23208. - - - - - 77f506b8 by Josh Meredith at 2023-04-26T14:51:28-04:00 Refactor GenStgRhs to include the Type in both constructors (#23280, #22576, #22364) Carry the actual type of an expression through the PreStgRhs and into GenStgRhs for use in later stages. Currently this is used in the JavaScript backend to fix some tests from the above mentioned issues: EtaExpandLevPoly, RepPolyWrappedVar2, T13822, T14749. - - - - - 052e2bb6 by Alan Zimmerman at 2023-04-26T14:52:05-04:00 EPA: Use ExplicitBraces only in HsModule !9018 brought in exact print annotations in LayoutInfo for open and close braces at the top level. But it retained them in the HsModule annotations too. Remove the originals, so exact printing uses LayoutInfo - - - - - d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 7982d836 by Rodrigo Mesquita at 2023-04-28T17:18:55+01:00 Precompute static closures for DataCons with zero-width args Relax the predicate over nullary datacons that determines whether we can return a precomputed static closure for them, such that we give precomputed static closures to both datacon workers and wrappers as long as they only take zero-width arguments (and hence their closure is comprised of just the constructor info). Previously, we would only allow datacons that were nullary with regard to their Core representation, which prevented datacons workers with only zero-width arguments and wrappers with none from using a precomputed static closure. See Note [Precomputed static closures of nullary constructors] Closes #23158 - - - - - 30 changed files: - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/generate_job_metadata - .gitlab/generate_jobs - .gitlab/jobs.yaml - .gitmodules - cabal.project-reinstall - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/Wasm/Utils.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dbe3a85766f15268e012af363528d9e61368644f...7982d836b365ea35990b5064d0b71be410349edc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dbe3a85766f15268e012af363528d9e61368644f...7982d836b365ea35990b5064d0b71be410349edc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 16:53:56 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 28 Apr 2023 12:53:56 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 2 commits: First steps killing unifyWanted Message-ID: <644bfa247f959_178e741122628bc2165040@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 9150e329 by Simon Peyton Jones at 2023-04-28T16:47:36+01:00 First steps killing unifyWanted - - - - - ef4ea3e5 by Simon Peyton Jones at 2023-04-28T17:55:21+01:00 Wibbles - - - - - 30 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Plugin.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Rewrite.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - testsuite/tests/dependent/should_fail/T11471.hs - testsuite/tests/dependent/should_fail/T11471.stderr - testsuite/tests/impredicative/icfp20-fail.stderr - testsuite/tests/indexed-types/should_fail/T4179.stderr - testsuite/tests/indexed-types/should_fail/T4254b.hs - − testsuite/tests/indexed-types/should_fail/T4254b.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/670a77b4302cd6c63ef24ffae29f30e3e49b2425...ef4ea3e560c86a38c1236b0e4a6220ab0ddbac5e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/670a77b4302cd6c63ef24ffae29f30e3e49b2425...ef4ea3e560c86a38c1236b0e4a6220ab0ddbac5e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 17:06:12 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 28 Apr 2023 13:06:12 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Wibble Message-ID: <644bfd046fac3_178e7411256a69021687fe@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 525f107c by Simon Peyton Jones at 2023-04-28T18:07:46+01:00 Wibble - - - - - 2 changed files: - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs Changes: ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -1967,11 +1967,14 @@ Note [wrapUnifierTcS] When decomposing equalities we often create new wanted constraints for (s ~ t). But what if s=t? Then it'd be faster to return Refl right away. -Rather than making an equality test (which traverses the structure of -the type, perhaps fruitlessly), we call uType (via wrapUnifierTcS) to -traverse the common structure, and bales out when it finds a -difference by creating a new Wanted constraint. But where it succeeds -in finding common structure, it just builds a coercion to reflect it. +Rather than making an equality test (which traverses the structure of the type, +perhaps fruitlessly), we call uType (via wrapUnifierTcS) to traverse the common +structure, and bales out when it finds a difference by creating a new deferred +Wanted constraint. But where it succeeds in finding common structure, it just +builds a coercion to reflect it. + +This is all much faster than creating a new constraint, putting it in the +work list, picking it out, canonicalising it, etc etc. Note [unifyFunDeps] ~~~~~~~~~~~~~~~~~~~ @@ -2003,14 +2006,14 @@ unifyFunDeps ev role do_unifications wrapUnifierTcS :: CtEvidence -> Role -> (UnifyEnv -> TcM a) -- Some calls to uType -> TcS (a, Bag Ct, [TcTyVar]) --- Return coercions witnessing the equality of the two types, --- emitting new work equalities where necessary to achieve that +-- Invokes the do_unifications argument, with a suitable UnifyEnv. +-- Emit deferred equalities and kick-out from the inert set as a +-- result of any unifications. -- Very good short-cut when the two types are equal, or nearly so -- See Note [wrapUnifierTcS] --- The returned coercion's role matches the input parameter -- --- The [TcTyVar] is the list of unification variables --- that were unified the process. +-- The [TcTyVar] is the list of unification variables that were +-- unified the process; the (Bag Ct) are the deferred constraints. wrapUnifierTcS ev role do_unifications = do { (cos, unified, rewriters, cts) <- wrapTcS $ ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -247,7 +247,7 @@ and that can be used to rewrite other constrtaints. It satisfies these invariant * (TyEq:U) An EqCt is not immediately unifiable. If we can unify a:=ty, we will not form an EqCt (a ~ ty). * (TyEq:CH) rhs does not mention any coercion holes that resulted from fixing up - a hetero-kinded equality. See Note [Equalites with incompatible kinds] in + a hetero-kinded equality. See Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality These invariants ensure that the EqCts in inert_eqs constitute a terminating View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/525f107c99eff62938f216973f5253d87f3dc57b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/525f107c99eff62938f216973f5253d87f3dc57b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 18:04:18 2023 From: gitlab at gitlab.haskell.org (Sebastian Graf (@sgraf812)) Date: Fri, 28 Apr 2023 14:04:18 -0400 Subject: [Git][ghc/ghc][wip/T23083] 3 commits: ANFise string literal arguments (#23270) Message-ID: <644c0aa2142d1_178e7411370ac4c2173354@gitlab.mail> Sebastian Graf pushed to branch wip/T23083 at Glasgow Haskell Compiler / GHC Commits: 99871fae by Sebastian Graf at 2023-04-28T20:03:27+02:00 ANFise string literal arguments (#23270) This instates the invariant that a trivial CoreExpr translates to an atomic StgExpr. Nice. Fixes #23270. - - - - - 2b088873 by Sebastian Graf at 2023-04-28T20:03:27+02:00 CorePrep: Eliminate EmptyCase and unsafeEqualityProof in CoreToStg instead We eliminate EmptyCase by way of `coreToStg (Case e _ _ []) = coreToStg e` now. The main reason is that it plays far better in conjunction with eta expansion (as we aim to do for arguments in CorePrep, #23083), because we can discard any arguments, `(case e of {}) eta == case e of {}`, whereas in `(e |> co) eta` it's impossible to discard the argument. We do also give the same treatment to unsafeCoerce proofs and treat them as trivial iff their RHS is trivial. It is also both much simpler to describe than the previous mechanism of emitting an unsafe coercion and simpler to implement, removing quite a bit of commentary and `CorePrepProv`. - - - - - 3bbd970a by Sebastian Graf at 2023-04-28T20:03:27+02:00 CorePrep: Eta expand arguments (#23083) Previously, we'd only eta expand let bindings and lambdas, now we'll also eta expand arguments such as in T23083: ```hs g f h = f (h `seq` (h $)) ``` Unless `-fpedantic-bottoms` is set, we'll now transform to ```hs g f h = f (\eta -> h eta) ``` in CorePrep. See the new `Note [Eta expansion of arguments in CorePrep]` for the details. We only do this optimisation with -O2 because we saw 2-3% ghc/alloc regressions in T4801 and T5321FD. Fixes #23083. - - - - - 30 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/Tc/TyCl/Utils.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Utils/Trace.hs - docs/users_guide/using-optimisation.rst - libraries/base/Unsafe/Coerce.hs - + testsuite/tests/core-to-stg/T23270.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd7b0b2a9519eae24c2973d28dacc108e5a17968...3bbd970a15e892833b551ce95a74fa7e803b3a0c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cd7b0b2a9519eae24c2973d28dacc108e5a17968...3bbd970a15e892833b551ce95a74fa7e803b3a0c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Apr 28 21:22:42 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 28 Apr 2023 17:22:42 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Wibble Message-ID: <644c3922a59c3_178e7411684c1c0217768b@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 3d0ab24e by Simon Peyton Jones at 2023-04-28T22:24:19+01:00 Wibble - - - - - 1 changed file: - compiler/GHC/Tc/Solver/Equality.hs Changes: ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -1509,9 +1509,11 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 -- type_ev :: (xi2 |> kind_co) ~r# lhs1 = do { (kind_co, rewriters) <- mk_kind_eq -- :: ki1 ~N ki2 - ; if isEmptyRewriterSet rewriters + ; if isWanted ev && isEmptyRewriterSet rewriters -- Made kinds equal with no deferred rewrites so we must have done -- some unifications; start again to do the zonking + -- For Givens we never want to go round again, + -- and the rewriter set is empty, so we must check isWanted. then startAgainWith (mkNonCanonical ev) else do { let lhs_redn = mkReflRedn role ps_xi1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d0ab24ebe588d800b3559a7a56f993ea2830d3a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d0ab24ebe588d800b3559a7a56f993ea2830d3a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 29 14:38:06 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sat, 29 Apr 2023 10:38:06 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] More wibbles Message-ID: <644d2bceadf66_178e741272040b8222649e@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: f2ad5ba8 by Simon Peyton Jones at 2023-04-29T15:39:36+01:00 More wibbles - - - - - 14 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - compiler/GHC/Core/Reduction.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/rep-poly/T13929.stderr Changes: ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -39,8 +39,8 @@ module GHC.Core.Coercion ( mkSymCo, mkTransCo, mkSelCo, getNthFun, getNthFromType, mkLRCo, mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo, - mkFunCo1, mkFunCo2, mkFunCoNoFTF, mkFunResCo, - mkNakedFunCo1, mkNakedFunCo2, + mkFunCo, mkFunCo2, mkFunCoNoFTF, mkFunResCo, + mkNakedFunCo, mkForAllCo, mkForAllCos, mkHomoForAllCos, mkPhantomCo, mkHoleCo, mkUnivCo, mkSubCo, @@ -811,29 +811,20 @@ mkFunCoNoFTF r w arg_co res_co -- or @(a => x) ~ (b => y)@, depending on the kind of @a@/@b at . -- This (most common) version takes a single FunTyFlag, which is used -- for both fco_afl and ftf_afr of the FunCo -mkFunCo1 :: HasDebugCallStack => Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion -mkFunCo1 r af w arg_co res_co +mkFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion +mkFunCo r af w arg_co res_co = mkFunCo2 r af af w arg_co res_co -mkNakedFunCo1 :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion --- This version of mkFunCo1 does not check FunCo invariants (checkFunCo) --- It is called during typechecking on un-zonked types; --- in particular there may be un-zonked coercion variables. -mkNakedFunCo1 r af w arg_co res_co - = mkNakedFunCo2 r af af w arg_co res_co +mkNakedFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion +-- This version of mkFunCo does not check FunCo invariants (checkFunCo) +-- It's a historical vestige; See Note [No assertion check on mkFunCo] +mkNakedFunCo = mkFunCo -mkFunCo2 :: HasDebugCallStack => Role -> FunTyFlag -> FunTyFlag - -> CoercionN -> Coercion -> Coercion -> Coercion +mkFunCo2 :: Role -> FunTyFlag -> FunTyFlag + -> CoercionN -> Coercion -> Coercion -> Coercion -- This is the smart constructor for FunCo; it checks invariants mkFunCo2 r afl afr w arg_co res_co - = assertPprMaybe (checkFunCo r afl afr w arg_co res_co) $ - mkNakedFunCo2 r afl afr w arg_co res_co - -mkNakedFunCo2 :: Role -> FunTyFlag -> FunTyFlag - -> CoercionN -> Coercion -> Coercion -> Coercion --- This is the smart constructor for FunCo --- "Naked"; it does not check invariants -mkNakedFunCo2 r afl afr w arg_co res_co + -- See Note [No assertion check on mkFunCo] | Just (ty1, _) <- isReflCo_maybe arg_co , Just (ty2, _) <- isReflCo_maybe res_co , Just (w, _) <- isReflCo_maybe w @@ -844,6 +835,19 @@ mkNakedFunCo2 r afl afr w arg_co res_co , fco_mult = w, fco_arg = arg_co, fco_res = res_co } +{- Note [No assertion check on mkFunCo] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We used to have a checkFunCo assertion on mkFunCo, but during typechecking +we can (legitimately) have not-full-zonked types or coercion variables, so +the assertion spuriously fails (test T11480b is a case in point). Lint +checks all these things anyway. + +We used to get around the problem by calling mkNakedFunCo from within the +typechecker, which dodged the assertion check. But then mkAppCo calls +mkTyConAppCo, which calls tyConAppFunCo_maybe, which calls mkFunCo. +Duplicating this stack of calls with "naked" versions of each seems too much. + +-- Commented out: see Note [No assertion check on mkFunCo] checkFunCo :: Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Maybe SDoc @@ -875,6 +879,7 @@ checkFunCo _r afl afr _w arg_co res_co ok ty = isTYPEorCONSTRAINT (typeKind ty) pp_ty str ty = text str <> colon <+> hang (ppr ty) 2 (dcolon <+> ppr (typeKind ty)) +-} -- | Apply a 'Coercion' to another 'Coercion'. -- The second coercion must be Nominal, unless the first is Phantom. @@ -2068,7 +2073,7 @@ ty_co_subst !lc role ty liftCoSubstTyVar lc r tv go r (AppTy ty1 ty2) = mkAppCo (go r ty1) (go Nominal ty2) go r (TyConApp tc tys) = mkTyConAppCo r tc (zipWith go (tyConRoleListX r tc) tys) - go r (FunTy af w t1 t2) = mkFunCo1 r af (go Nominal w) (go r t1) (go r t2) + go r (FunTy af w t1 t2) = mkFunCo r af (go Nominal w) (go r t1) (go r t2) go r t@(ForAllTy (Bndr v _) ty) = let (lc', v', h) = liftCoSubstVarBndr lc v body_co = ty_co_subst lc' r ty in @@ -2658,7 +2663,7 @@ buildCoercion orig_ty1 orig_ty2 = go orig_ty1 orig_ty2 go (FunTy { ft_af = af1, ft_mult = w1, ft_arg = arg1, ft_res = res1 }) (FunTy { ft_af = af2, ft_mult = w2, ft_arg = arg2, ft_res = res2 }) = assert (af1 == af2) $ - mkFunCo1 Nominal af1 (go w1 w2) (go arg1 arg2) (go res1 res2) + mkFunCo Nominal af1 (go w1 w2) (go arg1 arg2) (go res1 res2) go (TyConApp tc1 args1) (TyConApp tc2 args2) = assert (tc1 == tc2) $ @@ -2745,7 +2750,7 @@ has_co_hole_co :: Coercion -> Monoid.Any -- | Is there a hetero-kind coercion hole in this type? -- (That is, a coercion hole with ch_hetero_kind=True.) --- See wrinkle (2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality +-- See wrinkle (W2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality hasCoercionHoleTy :: Type -> Bool hasCoercionHoleTy = Monoid.getAny . has_co_hole_ty ===================================== compiler/GHC/Core/Coercion.hs-boot ===================================== @@ -17,9 +17,9 @@ mkReflCo :: Role -> Type -> Coercion mkTyConAppCo :: HasDebugCallStack => Role -> TyCon -> [Coercion] -> Coercion mkAppCo :: Coercion -> Coercion -> Coercion mkForAllCo :: TyCoVar -> Coercion -> Coercion -> Coercion -mkFunCo1 :: HasDebugCallStack => Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion -mkNakedFunCo1 :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion -mkFunCo2 :: HasDebugCallStack => Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion +mkFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion +mkNakedFunCo :: Role -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion +mkFunCo2 :: Role -> FunTyFlag -> FunTyFlag -> CoercionN -> Coercion -> Coercion -> Coercion mkCoVarCo :: CoVar -> Coercion mkAxiomInstCo :: CoAxiom Branched -> BranchIndex -> [Coercion] -> Coercion mkPhantomCo :: Coercion -> Type -> Type -> Coercion ===================================== compiler/GHC/Core/Reduction.hs ===================================== @@ -361,8 +361,8 @@ mkFunRedn r af (Reduction arg_co arg_ty) (Reduction res_co res_ty) = mkReduction - (mkFunCo1 r af w_co arg_co res_co) - (mkFunTy af w_ty arg_ty res_ty) + (mkFunCo r af w_co arg_co res_co) + (mkFunTy af w_ty arg_ty res_ty) {-# INLINE mkFunRedn #-} -- | Create a 'Reduction' associated to a Π type, ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -1459,7 +1459,7 @@ data CoercionHole , ch_hetero_kind :: Bool -- True <=> arises from a kind-level equality -- See Note [Equalities with incompatible kinds] - -- in GHC.Tc.Solver.Equality, wrinkle (2) + -- in GHC.Tc.Solver.Equality, wrinkle (W2) } coHoleCoVar :: CoercionHole -> CoVar ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -273,7 +273,7 @@ import {-# SOURCE #-} GHC.Core.Coercion , mkTyConAppCo, mkAppCo , mkForAllCo, mkFunCo2, mkAxiomInstCo, mkUnivCo , mkSymCo, mkTransCo, mkSelCo, mkLRCo, mkInstCo - , mkKindCo, mkSubCo, mkFunCo1 + , mkKindCo, mkSubCo, mkFunCo , decomposePiCos, coercionKind , coercionRKind, coercionType , isReflexiveCo, seqCo @@ -1329,7 +1329,7 @@ tyConAppFunCo_maybe :: HasDebugCallStack => Role -> TyCon -> [Coercion] -- ^ Return Just if this TyConAppCo should be represented as a FunCo tyConAppFunCo_maybe r tc cos | Just (af, mult, arg, res) <- ty_con_app_fun_maybe (mkReflCo r manyDataConTy) tc cos - = Just (mkFunCo1 r af mult arg res) + = Just (mkFunCo r af mult arg res) | otherwise = Nothing ty_con_app_fun_maybe :: (HasDebugCallStack, Outputable a) => a -> TyCon -> [a] ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1672,7 +1672,7 @@ mkTyVarEqErr' ctxt item (tv1, co1) ty2 return (main_msg, []) -- Incompatible kinds - -- This is wrinkle (4) in Note [Equalities with incompatible kinds] + -- This is wrinkle (W2) in Note [Equalities with incompatible kinds] -- in GHC.Tc.Solver.Equality | hasCoercionHoleCo co1 || hasCoercionHoleTy ty2 = return (mkBlockedEqErr item, []) @@ -1856,7 +1856,7 @@ misMatchOrCND insoluble_occurs_check ctxt item ty1 ty2 -- See Note [Suppress redundant givens during error reporting] -- These are for the "blocked" equalities, as described in TcCanonical --- Note [Equalities with incompatible kinds], wrinkle (2). There should +-- Note [Equalities with incompatible kinds], wrinkle (W2). There should -- always be another unsolved wanted around, which will ordinarily suppress -- this message. But this can still be printed out with -fdefer-type-errors -- (sigh), so we must produce a message. ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -4520,7 +4520,7 @@ data TcSolverReportMsg | BlockedEquality ErrorItem -- These are for the "blocked" equalities, as described in -- Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical, - -- wrinkle (2). There should always be another unsolved wanted around, + -- wrinkle (W2). There should always be another unsolved wanted around, -- which will ordinarily suppress this message. But this can still be printed out -- with -fdefer-type-errors (sigh), so we must produce a message. ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -388,7 +388,7 @@ kcClassSigType :: [LocatedN Name] -> LHsSigType GhcRn -> TcM () -- meth :: forall a (x :: f a). Proxy x -> () -- When instantiating Proxy with kappa, we must unify kappa := f a. But we're -- still working out the kind of f, and thus f a will have a coercion in it. --- Coercions block unification (Note [Equalities with incompatible kinds] in +-- Coercions may block unification (Note [Equalities with incompatible kinds] in -- TcCanonical) and so we fail to unify. If we try to kind-generalize, we'll -- end up promoting kappa to the top level (because kind-generalization is -- normally done right before adding a binding to the context), and then we @@ -1932,7 +1932,7 @@ checkExpectedKind hs_ty ty act_kind exp_kind ; if act_kind' `tcEqType` exp_kind then return res_ty -- This is very common - else do { co_k <- uTypeAndEmit KindLevel origin act_kind' exp_kind + else do { co_k <- unifyTypeAndEmit KindLevel origin act_kind' exp_kind ; traceTc "checkExpectedKind" (vcat [ ppr act_kind , ppr exp_kind , ppr co_k ]) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -872,10 +872,6 @@ doLocalFunDepImprovement :: Ct -> TcS Bool doLocalFunDepImprovement (CDictCan { cc_ev = work_ev, cc_class = cls }) = do { inerts <- getInertCans ; foldlM add_fds False (findDictsByClass (inert_dicts inerts) cls) } - -- No need to check flavour; fundeps work between - -- any pair of constraints, regardless of flavour - -- Importantly we don't throw workitem back in the - -- worklist because this can cause loops (see #5236) where work_pred = ctEvPred work_ev work_loc = ctEvLoc work_ev @@ -895,8 +891,6 @@ doLocalFunDepImprovement (CDictCan { cc_ev = work_ev, cc_class = cls }) ; unifs <- emitFunDepWanteds work_ev $ improveFromAnother (derived_loc, inert_rewriters) inert_pred work_pred - -- We don't really rewrite tys2, see below - -- _rewritten_tys2, so that's ok ; return (so_far || unifs) } where ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -179,10 +179,10 @@ can_eq_nc' _rewritten rdr_env envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2 -- Then, get rid of casts can_eq_nc' rewritten _rdr_env _envs ev eq_rel (CastTy ty1 co1) _ ty2 ps_ty2 - | isNothing (canEqLHS_maybe ty2) -- See (3) in Note [Equalities with incompatible kinds] + | isNothing (canEqLHS_maybe ty2) -- See (W3) in Note [Equalities with incompatible kinds] = canEqCast rewritten ev eq_rel NotSwapped ty1 co1 ty2 ps_ty2 can_eq_nc' rewritten _rdr_env _envs ev eq_rel ty1 ps_ty1 (CastTy ty2 co2) _ - | isNothing (canEqLHS_maybe ty1) -- See (3) in Note [Equalities with incompatible kinds] + | isNothing (canEqLHS_maybe ty1) -- See (W3) in Note [Equalities with incompatible kinds] = canEqCast rewritten ev eq_rel IsSwapped ty2 co2 ty1 ps_ty1 ---------------------- @@ -1277,7 +1277,7 @@ canDecomposableFunTy ev eq_rel af f1@(m1,a1,r1) f2@(m2,a2,r2) ; mult <- uType mult_env m1 m2 ; arg <- uType (uenv `setUEnvRole` funRole role SelArg) a1 a2 ; res <- uType (uenv `setUEnvRole` funRole role SelRes) r1 r2 - ; return (mkNakedFunCo1 role af mult arg res) } + ; return (mkNakedFunCo role af mult arg res) } ; setWantedEq dest co } CtGiven { ctev_evar = evar } @@ -1508,12 +1508,10 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 -- kind_co :: ki2 ~# ki1 -- Same orientiation as ev -- type_ev :: (xi2 |> kind_co) ~r# lhs1 - = do { (kind_co, rewriters) <- mk_kind_eq -- :: ki1 ~N ki2 - ; if isWanted ev && isEmptyRewriterSet rewriters - -- Made kinds equal with no deferred rewrites so we must have done - -- some unifications; start again to do the zonking - -- For Givens we never want to go round again, - -- and the rewriter set is empty, so we must check isWanted. + = do { (kind_co, rewriters, unifs_happened) <- mk_kind_eq -- :: ki1 ~N ki2 + ; if unifs_happened + -- Unifications happened, so start again to do the zonking + -- Otherwise we might put something in the inert set that isn't inert then startAgainWith (mkNonCanonical ev) else do { let lhs_redn = mkReflRedn role ps_xi1 @@ -1531,7 +1529,7 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 ; canEqCanLHSHomo type_ev eq_rel NotSwapped lhs1 ps_xi1 new_xi2 new_xi2 }} where - mk_kind_eq :: TcS (CoercionN, RewriterSet) + mk_kind_eq :: TcS (CoercionN, RewriterSet, Bool) -- Returned kind_co has kind (k1 ~ k2) if NotSwapped, (k2 ~ k1) if Swapped -- Returned Bool = True if unifications happened, so we should retry mk_kind_eq = case ev of @@ -1541,13 +1539,13 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2 kind_loc = mkKindEqLoc xi1 xi2 (ctev_loc ev) ; kind_ev <- newGivenEvVar kind_loc (pred_ty, evCoercion kind_co) ; emitWorkNC [kind_ev] - ; return (ctEvCoercion kind_ev, emptyRewriterSet) } + ; return (ctEvCoercion kind_ev, emptyRewriterSet, False) } CtWanted {} - -> do { (kind_co, cts, _) <- wrapUnifierTcS ev Nominal $ \uenv -> - let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2) - in unSwap swapped (uType uenv') ki1 ki2 - ; return (kind_co, rewriterSetFromCts cts) } + -> do { (kind_co, cts, unifs) <- wrapUnifierTcS ev Nominal $ \uenv -> + let uenv' = updUEnvLoc uenv (mkKindEqLoc xi1 xi2) + in unSwap swapped (uType uenv') ki1 ki2 + ; return (kind_co, rewriterSetFromCts cts, not (null unifs)) } xi1 = canEqLHSType lhs1 role = eqRelRole eq_rel @@ -1942,12 +1940,12 @@ k2 and use this to cast. To wit, from Wrinkles: - (1) When X is W, the new type-level wanted is effectively rewritten by the +(W1) When X is W, the new type-level wanted is effectively rewritten by the kind-level one. We thus include the kind-level wanted in the RewriterSet for the type-level one. See Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint. This is done in canEqCanLHSHetero. - (2) Suppose we have [W] (a::Type) ~ (b::Type->Type). The above rewrite will produce +(W2) Suppose we have [W] (a::Type) ~ (b::Type->Type). The above rewrite will produce [W] w : a ~ (b |> kw) [W] kw : Type ~ (Type->Type) @@ -1965,13 +1963,13 @@ Wrinkles: Instead, it lands in the inert_irreds in the inert set, awaiting solution of that `kw`. - (2a) We must later indeed unify if/when the kind-level wanted, `kw` gets + (W2a) We must later indeed unify if/when the kind-level wanted, `kw` gets solved. This is done in kickOutAfterFillingCoercionHole, which kicks out all equalities whose RHS mentions the filled-in coercion hole. Note that it looks for type family equalities, too, because of the use of unifyTest in canEqTyVarFunEq. - (2b) What if the RHS mentions /other/ coercion holes. How can that happen? The + (W2b) What if the RHS mentions /other/ coercion holes. How can that happen? The main way is like this. Assume F :: forall k. k -> Type [W] kw : k ~ Type [W] w : a ~ F k t @@ -1979,7 +1977,8 @@ Wrinkles: [W] w' : a ~ F Type (t |> kw) The cast on the second argument of `F` is necessary to keep the appliation well-kinded. There is nothing special here; no reason not treat w' as canonical, and use it for - rewriting. Indeed tests JuanLopez only typechecks if we do. + rewriting. Indeed tests JuanLopez only typechecks if we do. So we'd like to treat + this kind of equality as canonical. Hence the ch_hetero_kind field in CoercionHole: it is True of constraints created by `canEqCanLHSHetero` to fix up hetero-kinded equalities; and False otherwise: @@ -1991,7 +1990,7 @@ Wrinkles: KindEqOrigin: see GHC.Tc.Utils.TcMType.newCoercionHole and friends. We set this origin, via `mkKindLoc`, in `mk_kind_eq` in `canEqCanLHSHetero`. - (3) Suppose we have [W] (a :: k1) ~ (rhs :: k2). We duly follow the +(W3) Suppose we have [W] (a :: k1) ~ (rhs :: k2). We duly follow the algorithm detailed here, producing [W] co :: k1 ~ k2, and adding [W] (a :: k1) ~ ((rhs |> sym co) :: k1) to the irreducibles. Some time later, we solve co, and fill in co's coercion hole. This kicks out @@ -2749,9 +2748,9 @@ like the right thing to do. When this was originally conceived, it was necessary to avoid a loop in T13135. That loop is now avoided by continuing with the kind equality (not the type -equality) in canEqCanLHSHetero (see Note [Equalities with incompatible kinds] -in GHC.Tc.Solver.Canonical). However, the idea of working left-to-right still -seems worthwhile, and so the calls to 'reverse' remain. +equality) in canEqCanLHSHetero (see Note [Equalities with incompatible kinds]). +However, the idea of working left-to-right still seems worthwhile, and so the calls +to 'reverse' remain. Note [Improvement orientation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -419,7 +419,7 @@ kickOutAfterUnification new_tv ; setInertCans ics2 ; return n_kicked } --- See Wrinkle (2) in Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical +-- See Wrinkle (W2a) in Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Canonical -- It's possible that this could just go ahead and unify, but could there be occurs-check -- problems? Seems simpler just to kick out. kickOutAfterFillingCoercionHole :: CoercionHole -> TcS () ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -230,7 +230,7 @@ mkWpEta xs wrap = foldr eta_one wrap xs mk_wp_fun_co :: Mult -> TcCoercionR -> TcCoercionR -> TcCoercionR mk_wp_fun_co mult arg_co res_co - = mkNakedFunCo1 Representational FTF_T_T (multToCo mult) arg_co res_co + = mkNakedFunCo Representational FTF_T_T (multToCo mult) arg_co res_co -- FTF_T_T: WpFun is always (->) mkWpCastR :: TcCoercionR -> HsWrapper ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Tc.Utils.Unify ( -- Various unifications unifyType, unifyKind, unifyInvisibleType, unifyExpectedType, - uTypeAndEmit, promoteTcType, + unifyTypeAndEmit, promoteTcType, swapOverTyVars, touchabilityAndShapeTest, UnifyEnv(..), updUEnvLoc, setUEnvRole, uType, @@ -1147,7 +1147,7 @@ tcEqMult origin w_actual w_expected = do { -- Note that here we do not call to `submult`, so we check -- for strict equality. - ; coercion <- uTypeAndEmit TypeLevel origin w_actual w_expected + ; coercion <- unifyTypeAndEmit TypeLevel origin w_actual w_expected ; return $ if isReflCo coercion then WpHole else WpMultCoercion coercion } @@ -1713,7 +1713,7 @@ unifyType :: Maybe TypedThing -- ^ If present, the thing that has type ty1 -- Actual and expected types -- Returns a coercion : ty1 ~ ty2 unifyType thing ty1 ty2 - = uTypeAndEmit TypeLevel origin ty1 ty2 + = unifyTypeAndEmit TypeLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty1 , uo_expected = ty2 @@ -1725,18 +1725,18 @@ unifyInvisibleType :: TcTauType -> TcTauType -- ty1 (actual), ty2 (expected) -- Actual and expected types -- Returns a coercion : ty1 ~ ty2 unifyInvisibleType ty1 ty2 - = uTypeAndEmit TypeLevel origin ty1 ty2 + = unifyTypeAndEmit TypeLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty1 , uo_expected = ty2 , uo_thing = Nothing - , uo_visible = False } + , uo_visible = False } -- This is the "invisible" bit unifyTypeET :: TcTauType -> TcTauType -> TcM CoercionN -- Like unifyType, but swap expected and actual in error messages -- This is used when typechecking patterns unifyTypeET ty1 ty2 - = uTypeAndEmit TypeLevel origin ty1 ty2 + = unifyTypeAndEmit TypeLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty2 -- NB swapped , uo_expected = ty1 -- NB swapped @@ -1746,16 +1746,16 @@ unifyTypeET ty1 ty2 unifyKind :: Maybe TypedThing -> TcKind -> TcKind -> TcM CoercionN unifyKind mb_thing ty1 ty2 - = uTypeAndEmit KindLevel origin ty1 ty2 + = unifyTypeAndEmit KindLevel origin ty1 ty2 where origin = TypeEqOrigin { uo_actual = ty1 , uo_expected = ty2 , uo_thing = mb_thing , uo_visible = True } -uTypeAndEmit :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM CoercionN +unifyTypeAndEmit :: TypeOrKind -> CtOrigin -> TcType -> TcType -> TcM CoercionN -- Make a ref-cell, unify, emit the collected constraints -uTypeAndEmit t_or_k orig ty1 ty2 +unifyTypeAndEmit t_or_k orig ty1 ty2 = do { ref <- newTcRef emptyBag ; loc <- getCtLocM orig (Just t_or_k) ; let env = UE { u_loc = loc, u_role = Nominal @@ -1931,7 +1931,7 @@ uType env@(UE { u_role = role }) orig_ty1 orig_ty2 = do { co_w <- uType (env { u_role = funRole role SelMult }) w1 w2 ; co_l <- uType (env { u_role = funRole role SelArg }) arg1 arg2 ; co_r <- uType (env { u_role = funRole role SelRes }) res1 res2 - ; return $ mkNakedFunCo1 role af1 co_w co_l co_r } + ; return $ mkNakedFunCo role af1 co_w co_l co_r } -- Always defer if a type synonym family (type function) -- is involved. (Data families behave rigidly.) @@ -2320,8 +2320,9 @@ There are five reasons not to unify: Suppose our equality is (alpha :: k) ~ (Int |> {co}) where co :: Type ~ k is an unsolved wanted. Note that this equality - is homogeneous; both sides have kind k. We refrain from unifying here -- - see Wrinkle (2) in Note [Equalities with incompatible kinds] in GHC.Solver.Equality. + is homogeneous; both sides have kind k. We refrain from unifying here, because + of the coercion hold in the RHS -- see Wrinkle (W2) in + Note [Equalities with incompatible kinds] in GHC.Solver.Equality. Needless to say, all there are wrinkles: @@ -2591,7 +2592,7 @@ matchExpectedFunKind hs_ty n k = go n k go n (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res }) | isVisibleFunArg af = do { co <- go (n-1) res - ; return (mkNakedFunCo1 Nominal af (mkNomReflCo w) (mkNomReflCo arg) co) } + ; return (mkNakedFunCo Nominal af (mkNomReflCo w) (mkNomReflCo arg) co) } go n other = defer n other @@ -2605,7 +2606,7 @@ matchExpectedFunKind hs_ty n k = go n k , uo_thing = Just hs_ty , uo_visible = True } - ; uTypeAndEmit KindLevel origin k new_fun } + ; unifyTypeAndEmit KindLevel origin k new_fun } {- ********************************************************************* * * ===================================== testsuite/tests/rep-poly/T13929.stderr ===================================== @@ -3,7 +3,7 @@ T13929.hs:29:24: error: [GHC-55287] • The tuple argument in first position does not have a fixed runtime representation. Its type is: - a0 :: TYPE k00 + GUnboxed f rf :: TYPE k00 Cannot unify ‘rf’ with the type variable ‘k00’ because it is not a concrete ‘RuntimeRep’. • In the expression: (# gunbox x, gunbox y #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2ad5ba81bd998afa2947add6a9187e9f97dcf35 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2ad5ba81bd998afa2947add6a9187e9f97dcf35 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 29 21:09:08 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sat, 29 Apr 2023 17:09:08 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] Use the eager unifier in the constraint solver Message-ID: <644d8774ef961_178e7412d883c58226443@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 68b73ac0 by Simon Peyton Jones at 2023-04-29T22:10:47+01:00 Use the eager unifier in the constraint solver This patch continues the refactoring of the constraint solver described in #23070. The Big Deal in this patch is to call the regular, eager unifier from the constraint solver, when we want to create new equalities. This replaces the existing, unifyWanted which amounted to yet-another-unifier, so it reduces duplication of a rather subtle piece of technology. See * Note [The eager unifier] in GHC.Tc.Utils.Unify * GHC.Tc.Solver.Monad.wrapUnifierTcS I did lots of other refactoring along the way * I simplified the treatment of right hand sides that contain CoercionHoles. Now, a constraint that contains a hetero-kind CoercionHole is non-canonical, and cannot be used for rewriting or unification alike. This required me to add the ch_hertero_kind flag to CoercionHole, with consequent knock-on effects. See wrinkle (2) of `Note [Equalities with incompatible kinds]` in GHC.Tc.Solver.Equality. * I refactored the StopOrContinue type to add StartAgain, so that after a fundep improvement (for example) we can simply start the pipeline again. * I got rid of the unpleasant (and inefficient) rewriterSetFromType/Co functions. With Richard I concluded that they are never needed. * I discovered Wrinkle (W1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint, and therefore now prioritise non-rewritten equalities. Quite a few error messages change, I think always for the better. Compiler runtime stays about the same, with one outlier: a 17% improvement in T17836 Metric Decrease: T17836 - - - - - 27 changed files: - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Reduction.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Plugin.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Rewrite.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b73ac0a880e73cbc990acd1464848600c9703b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b73ac0a880e73cbc990acd1464848600c9703b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Apr 29 23:24:00 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 29 Apr 2023 19:24:00 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 14 commits: ci: update ci.sh to actually run the entire testsuite for wasm backend Message-ID: <644da710e5860_178e7412fa575782283994@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d5c4629b by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: update ci.sh to actually run the entire testsuite for wasm backend For the time being, we still need to use in-tree mode and can't test the bindist yet. - - - - - 533d075e by Cheng Shao at 2023-04-27T16:00:35-04:00 ci: additional wasm32 manual jobs in validate pipelines This patch enables bignum native & unregisterised wasm32 jobs as manual jobs in validate pipelines, which can be useful to prevent breakage when working on wasm32 related patches. - - - - - b5f00811 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix cross prefix stripping This patch fixes cross prefix stripping in the testsuite driver. The normalization logic used to only handle prefixes of the triple form <arch>-<vendor>-<os>, now it's relaxed to allow any number of tokens in the prefix tuple, so the cross prefix stripping logic would work when ghc is configured with something like --target=wasm32-wasi. - - - - - 6f511c36 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: include target exe extension in heap profile filenames This patch fixes hp2ps related framework failures when testing the wasm backend by including target exe extension in heap profile filenames. - - - - - e6416b10 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: exclude ghci ways if no rts linker is present This patch implements logic to automatically exclude ghci ways when there is no rts linker. It's way better than having to annotate individual test cases. - - - - - 791cce64 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: fix permission bits in copy_files When the testsuite driver copy files instead of symlinking them, it should also copy the permission bits, otherwise there'll be permission denied errors. Also, enforce file copying when testing wasm32, since wasmtime doesn't handle host symlinks quite well (https://github.com/bytecodealliance/wasmtime/issues/6227). - - - - - aa6afe8a by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_ghc_with_threaded_rts predicate This patch adds the req_ghc_with_threaded_rts predicate to the testsuite to assert the platform has threaded RTS, and mark some tests as req_ghc_with_threaded_rts. Also makes ghc_with_threaded_rts a config field instead of a global variable. - - - - - ce580426 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_process predicate This patch adds the req_process predicate to the testsuite to assert the platform has a process model, also marking tests that involve spawning processes as req_process. Also bumps hpc & process submodule. - - - - - cb933665 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add the req_host_target_ghc predicate This patch adds the req_host_target_ghc predicate to the testsuite to assert the ghc compiler being tested can compile both host/target code. When testing cross GHCs this is not supported yet, but it may change in the future. - - - - - b174a110 by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: add missing annotations for some tests This patch adds missing annotations (req_th, req_dynamic_lib_support, req_rts_linker) to some tests. They were discovered when testing wasm32, though it's better to be explicit about what features they require, rather than simply adding when(arch('wasm32'), skip). - - - - - bd2bfdec by Cheng Shao at 2023-04-27T16:00:35-04:00 testsuite: wasm32-specific fixes This patch includes all wasm32-specific testsuite fixes. - - - - - 4eaf2c2a by Josh Meredith at 2023-04-27T16:01:11-04:00 JS: change GHC.JS.Transform.identsS/E/V to take a saturated IR (#23304) - - - - - 57277662 by sheaf at 2023-04-29T20:23:06+02:00 Add the Unsatisfiable class This commit implements GHC proposal #433, adding the Unsatisfiable class to the GHC.TypeError module. This provides an alternative to TypeError for which error reporting is more predictable: we report it when we are reporting unsolved Wanted constraints. Fixes #14983 #16249 #16906 #18310 #20835 - - - - - 694f6c04 by Torsten Schmits at 2023-04-29T19:23:56-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30 changed files: - .gitlab/ci.sh - .gitlab/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/JS/Transform.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToJS/Monad.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Instance/FunDeps.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Types.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - docs/users_guide/9.8.1-notes.rst - hadrian/src/Settings/Builders/RunTest.hs - libraries/base/GHC/TypeError.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94b8119a9038dd9f6bd0da600f11ac037fe59abb...694f6c04c0629d74fc2c984a0a686a56aff5bf1f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94b8119a9038dd9f6bd0da600f11ac037fe59abb...694f6c04c0629d74fc2c984a0a686a56aff5bf1f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 30 02:44:21 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 29 Apr 2023 22:44:21 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Add structured error messages for GHC.Rename.Names Message-ID: <644dd60585ca7_178e74133155db823048db@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ef4c44f0 by Torsten Schmits at 2023-04-29T22:44:18-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - testsuite/tests/deriving/should_compile/T17324.stderr - testsuite/tests/driver/t22391/t22391.stderr - testsuite/tests/driver/t22391/t22391j.stderr - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T4127a.stderr - testsuite/tests/ghci/scripts/ghci048.stderr - testsuite/tests/module/T1074.stderr - testsuite/tests/module/T11970A.stderr - testsuite/tests/module/mod176.stderr - testsuite/tests/module/mod177.stderr - testsuite/tests/module/mod18.stderr - testsuite/tests/module/mod19.stderr - testsuite/tests/module/mod20.stderr - testsuite/tests/module/mod21.stderr - testsuite/tests/module/mod22.stderr - testsuite/tests/module/mod38.stderr - testsuite/tests/module/mod66.stderr - testsuite/tests/overloadedrecflds/should_fail/FieldSelectors.stderr - testsuite/tests/overloadedrecflds/should_fail/NFSDuplicate.stderr - testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail03.stderr - testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail06.stderr - testsuite/tests/patsyn/should_compile/T9975a.stderr - testsuite/tests/rename/should_compile/T13064.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef4c44f038657ae3a51e859a5e571386a5be34d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef4c44f038657ae3a51e859a5e571386a5be34d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 30 07:44:58 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 30 Apr 2023 03:44:58 -0400 Subject: [Git][ghc/ghc][master] Add the Unsatisfiable class Message-ID: <644e1c7ac3154_178e74137d424382334516@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 57277662 by sheaf at 2023-04-29T20:23:06+02:00 Add the Unsatisfiable class This commit implements GHC proposal #433, adding the Unsatisfiable class to the GHC.TypeError module. This provides an alternative to TypeError for which error reporting is more predictable: we report it when we are reporting unsolved Wanted constraints. Fixes #14983 #16249 #16906 #18310 #20835 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Instance/FunDeps.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Types.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.8.1-notes.rst - libraries/base/GHC/TypeError.hs - libraries/base/changelog.md - + testsuite/tests/unsatisfiable/T11503_Unsat.hs - + testsuite/tests/unsatisfiable/T14141_Unsat.hs - + testsuite/tests/unsatisfiable/T14141_Unsat.stderr - + testsuite/tests/unsatisfiable/T14339_Unsat.hs - + testsuite/tests/unsatisfiable/T14339_Unsat.stderr - + testsuite/tests/unsatisfiable/T15232_Unsat.hs - + testsuite/tests/unsatisfiable/T22696_Unsat.stderr - + testsuite/tests/unsatisfiable/UnsatClassMethods.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57277662989b97dbf5ddc034d6c41ce39ab674ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57277662989b97dbf5ddc034d6c41ce39ab674ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 30 07:45:26 2023 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 30 Apr 2023 03:45:26 -0400 Subject: [Git][ghc/ghc][master] Add structured error messages for GHC.Rename.Names Message-ID: <644e1c96e6854_178e74137d4243823390ec@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 00a8a5ff by Torsten Schmits at 2023-04-30T03:45:09-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - 30 changed files: - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - testsuite/tests/deriving/should_compile/T17324.stderr - testsuite/tests/driver/t22391/t22391.stderr - testsuite/tests/driver/t22391/t22391j.stderr - testsuite/tests/ghci/prog018/prog018.stdout - testsuite/tests/ghci/scripts/T4127a.stderr - testsuite/tests/ghci/scripts/ghci048.stderr - testsuite/tests/module/T1074.stderr - testsuite/tests/module/T11970A.stderr - testsuite/tests/module/mod176.stderr - testsuite/tests/module/mod177.stderr - testsuite/tests/module/mod18.stderr - testsuite/tests/module/mod19.stderr - testsuite/tests/module/mod20.stderr - testsuite/tests/module/mod21.stderr - testsuite/tests/module/mod22.stderr - testsuite/tests/module/mod38.stderr - testsuite/tests/module/mod66.stderr - testsuite/tests/overloadedrecflds/should_fail/FieldSelectors.stderr - testsuite/tests/overloadedrecflds/should_fail/NFSDuplicate.stderr - testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail03.stderr - testsuite/tests/overloadedrecflds/should_fail/overloadedrecfldsfail06.stderr - testsuite/tests/patsyn/should_compile/T9975a.stderr - testsuite/tests/rename/should_compile/T13064.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00a8a5ff9abf5bb1a0c2a9225c7bca5ec3bdf306 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00a8a5ff9abf5bb1a0c2a9225c7bca5ec3bdf306 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 30 19:50:57 2023 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 30 Apr 2023 15:50:57 -0400 Subject: [Git][ghc/ghc][wip/supersven/riscv-ncg] 4 commits: Little cleanup Message-ID: <644ec6a19a948_178e74143fb1d2023864b5@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-ncg at Glasgow Haskell Compiler / GHC Commits: 61bfc2b4 by Sven Tennie at 2023-04-28T17:10:48+00:00 Little cleanup - - - - - 607ad010 by Sven Tennie at 2023-04-28T17:13:24+00:00 Connect mkVirtualReg - - - - - f9cf903c by Sven Tennie at 2023-04-28T19:08:41+00:00 Print registers with better names - - - - - 11fdb719 by Sven Tennie at 2023-04-30T19:50:01+00:00 Double precision (64bit) float literals - - - - - 5 changed files: - compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs - compiler/GHC/CmmToAsm/RISCV64/Instr.hs - compiler/GHC/CmmToAsm/RISCV64/Ppr.hs - compiler/GHC/CmmToAsm/RISCV64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Target.hs Changes: ===================================== compiler/GHC/CmmToAsm/RISCV64/CodeGen.hs ===================================== @@ -24,6 +24,8 @@ import GHC.Utils.Panic import GHC.Cmm.BlockId import GHC.Utils.Trace import Debug.Trace +import Data.Word (Word64) +import GHC.Float (castDoubleToWord64) -- | Don't try to compile all GHC Cmm files in the beginning. -- Ignore them. There's a flag to decide we really want to emit something. @@ -111,7 +113,7 @@ stmtToInstrs stmt = do a -> error $ "TODO: stmtToInstrs " ++ (showSDocUnsafe . pdoc platform) a assignReg_FltCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock -assignReg_FltCode _ _ _ = error "TODO: assignReg_FltCode" +assignReg_FltCode = assignReg_IntCode -- TODO: Format parameter unused assignReg_IntCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock @@ -122,7 +124,7 @@ assignReg_IntCode _ reg src r <- getRegister src return $ case r of Any _ code -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL` code dst - Fixed format freg fcode -> error "TODO: assignReg_IntCode - Fixed" + Fixed _format freg fcode -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL` (fcode `snocOL` MV dst freg) -- | Grab the Reg for a CmmReg getRegisterReg :: Platform -> CmmReg -> Reg @@ -168,6 +170,17 @@ getRegister' config plat expr CmmInt i W64 -> return (Any II64 (\dst -> unitOL $ annExpr expr (LI dst i))) CmmInt i w -> error ("TODO: getRegister' CmmInt " ++ show i ++ show w ++ " " ++show expr) + CmmFloat f W64 -> do + let word = castDoubleToWord64 (fromRational f) :: Word64 + tmp <- getNewRegNat (intFormat W64) + return (Any FF64 (\dst -> toOL [ + annExpr expr$ + LI tmp (fromIntegral word), + FMV_D_X dst tmp + ] + ) + ) + CmmLabel lbl -> return (Any II64 (\dst -> unitOL $ annExpr expr (LA dst lbl))) e -> error ("TODO: getRegister' other " ++ show e) @@ -313,9 +326,16 @@ genCCall target dest_regs arg_regs = do code_r `snocOL` ann (text "Pass gp argument: " <> ppr r) mov passArguments gpRegs fpRegs args stackSpace (gpReg:accumRegs) accumCode' + passArguments gpRegs (fpReg:fpRegs) ((r, format, hint, code_r):args) stackSpace accumRegs accumCode | isFloatFormat format = do + traceM $ "passArguments - float reg " ++ show r + let w = formatToWidth format + mov = FMV_D fpReg r + accumCode' = accumCode `appOL` + code_r `snocOL` + ann (text "Pass fp argument: " <> ppr r) mov + passArguments gpRegs fpRegs args stackSpace (fpReg:accumRegs) accumCode' passArguments _ _ _ _ _ _ = error $ "TODO: passArguments" - readResults :: [Reg] -> [Reg] -> [LocalReg] -> [Reg]-> InstrBlock -> NatM ([Reg], InstrBlock) readResults _ _ [] accumRegs accumCode = return (accumRegs, accumCode) readResults _ _ _ _ _ = error $ "TODO: readResults" ===================================== compiler/GHC/CmmToAsm/RISCV64/Instr.hs ===================================== @@ -47,6 +47,9 @@ data Instr | JALR Reg | -- copy register MV Reg Reg + | FMV_S Reg Reg + | FMV_D Reg Reg + | FMV_D_X Reg Reg data Target = TBlock BlockId @@ -105,6 +108,9 @@ regUsageOfInstr platform instr = case instr of LI dst _ -> usage ([], [dst]) LA dst _ -> usage ([], [dst]) MV dst src -> usage ([src], [dst]) + FMV_S dst src -> usage ([src], [dst]) + FMV_D dst src -> usage ([src], [dst]) + FMV_D_X dst src -> usage ([src], [dst]) -- Looks like J doesn't change registers (beside PC) -- This might be wrong. J {} -> none @@ -147,6 +153,9 @@ patchRegsOfInstr instr env = case instr of CALL {} -> instr JALR reg -> JALR (env reg) MV dst src -> MV (env dst) (env src) + FMV_S dst src -> FMV_S (env dst) (env src) + FMV_D dst src -> FMV_D (env dst) (env src) + FMV_D_X dst src -> FMV_D_X (env dst) (env src) -- | Checks whether this instruction is a jump/branch instruction. -- One that can change the flow of control in a way that the @@ -159,6 +168,9 @@ isJumpishInstr DELTA {} = False isJumpishInstr LDATA {} = False isJumpishInstr NEWBLOCK {} = False isJumpishInstr MV {} = False +isJumpishInstr FMV_S {} = False +isJumpishInstr FMV_D {} = False +isJumpishInstr FMV_D_X {} = False isJumpishInstr LA {} = False isJumpishInstr LI {} = False isJumpishInstr J {} = True @@ -236,6 +248,9 @@ isMetaInstr instr = LA {} -> False J {} -> False MV {} -> False + FMV_S {} -> False + FMV_D {} -> False + FMV_D_X {} -> False CALL {} -> False JALR {} -> False @@ -265,6 +280,9 @@ takeRegRegMoveInstr LI {} = Nothing takeRegRegMoveInstr LA {} = Nothing takeRegRegMoveInstr J {} = Nothing takeRegRegMoveInstr (MV dst src) = Just (src, dst) +takeRegRegMoveInstr (FMV_S dst src) = Just (src, dst) +takeRegRegMoveInstr (FMV_D dst src) = Just (src, dst) +takeRegRegMoveInstr (FMV_D_X _ _) = Nothing -- Just (src, dst) takeRegRegMoveInstr CALL {} = Nothing takeRegRegMoveInstr JALR {} = Nothing ===================================== compiler/GHC/CmmToAsm/RISCV64/Ppr.hs ===================================== @@ -147,22 +147,27 @@ pprInstr platform instr = case instr of LI reg immediate -> line $ pprLI reg immediate LA reg label -> line $ text "\tla" <+> pprReg reg <> char ',' <+> pprAsmLabel platform label MV dst src -> line $ text "\tmv" <+> pprReg dst <> char ',' <+> pprReg src + FMV_S dst src -> line $ text "\tfmv.s" <+> pprReg dst <> char ',' <+> pprReg src + FMV_D dst src -> line $ text "\tfmv.d" <+> pprReg dst <> char ',' <+> pprReg src + FMV_D_X dst src -> line $ text "\tfmv.d.x" <+> pprReg dst <> char ',' <+> pprReg src where pprLI :: IsLine doc => Reg -> Integer -> doc pprLI reg immediate = text "\tli" <+> pprReg reg <> char ',' <+> (text.show) immediate pprReg :: IsLine doc => Reg -> doc - pprReg (RegReal (RealRegSingle r)) = text "x" <> (text.show) r - pprReg (RegVirtual r) = panic $ "RISCV64.Ppr.ppr: Unexpected virtual register " ++ show r + pprReg (RegReal (RealRegSingle regNo)) = (text.regNoToName) regNo + pprReg virtualReg = (text . showPprUnsafe) virtualReg pprJ :: IsLine doc => Target -> doc pprJ (TBlock label) = text "\tj" <+> pprBlockId label pprJ (TLabel label) = text "\tj" <+> pprAsmLabel platform label + pprJ (TReg reg) = panic $ "RISCV64 - Ppr.pprJ: Cannot J (jump) to registers. Requested register " ++ show reg pprBlockId:: IsLine doc => BlockId -> doc pprBlockId blockId = pprAsmLabel platform (mkLocalBlockLabel (getUnique blockId)) + -- aarch64 GNU as uses // for comments. asmComment :: SDoc -> SDoc asmComment c = whenPprDebug $ text "#" <+> c @@ -172,3 +177,70 @@ asmDoubleslashComment c = whenPprDebug $ text "//" <+> c asmMultilineComment :: SDoc -> SDoc asmMultilineComment c = whenPprDebug $ text "/*" $+$ c $+$ text "*/" + +regNoToName :: RegNo -> String +regNoToName 0 = "zero" +regNoToName 1 = "ra" +regNoToName 2 = "sp" +regNoToName 3 = "gp" +regNoToName 4 = "tp" +regNoToName 5 = "t0" +regNoToName 6 = "t1" +regNoToName 7 = "t2" +regNoToName 8 = "s0" +regNoToName 9 = "s1" +regNoToName 10 = "a0" +regNoToName 11 = "a1" +regNoToName 12 = "a2" +regNoToName 13 = "a3" +regNoToName 14 = "a4" +regNoToName 15 = "a5" +regNoToName 16 = "a6" +regNoToName 17 = "a7" +regNoToName 18 = "s2" +regNoToName 19 = "s3" +regNoToName 20 = "s4" +regNoToName 21 = "s5" +regNoToName 22 = "s6" +regNoToName 23 = "s7" +regNoToName 24 = "s8" +regNoToName 25 = "s9" +regNoToName 26 = "s10" +regNoToName 27 = "s11" +regNoToName 28 = "t3" +regNoToName 29 = "t4" +regNoToName 30 = "t5" +regNoToName 31 = "t6" +regNoToName 32 = "ft0" +regNoToName 33 = "ft1" +regNoToName 34 = "ft2" +regNoToName 35 = "ft3" +regNoToName 36 = "ft4" +regNoToName 37 = "ft5" +regNoToName 38 = "ft6" +regNoToName 39 = "ft7" +regNoToName 40 = "fs0" +regNoToName 41 = "fs1" +regNoToName 42 = "fa0" +regNoToName 43 = "fa1" +regNoToName 44 = "fa2" +regNoToName 45 = "fa3" +regNoToName 46 = "fa4" +regNoToName 47 = "fa5" +regNoToName 48 = "fa6" +regNoToName 49 = "fa7" +regNoToName 50 = "fs2" +regNoToName 51 = "fs3" +regNoToName 52 = "fs4" +regNoToName 53 = "fs5" +regNoToName 54 = "fs6" +regNoToName 55 = "fs7" +regNoToName 56 = "fs8" +regNoToName 57 = "fs9" +regNoToName 58 = "fs10" +regNoToName 59 = "fs11" +regNoToName 60 = "ft8" +regNoToName 61 = "ft9" +regNoToName 62 = "ft10" +regNoToName 63 = "ft11" +regNoToName regNo = panic $ "RISCV64: regToName: Unknown register number " ++ show regNo ===================================== compiler/GHC/CmmToAsm/RISCV64/Regs.hs ===================================== @@ -29,6 +29,7 @@ mkVirtualReg u format | not (isFloatFormat format) = VirtualRegI u | otherwise = case format of - FF32 -> VirtualRegD u - FF64 -> VirtualRegD u - _ -> panic "RISCV64.mkVirtualReg" + -- TODO: Do we really need to widen FF32? + FF32 -> VirtualRegD u + FF64 -> VirtualRegD u + _ -> panic "RISCV64.mkVirtualReg" ===================================== compiler/GHC/CmmToAsm/Reg/Target.hs ===================================== @@ -34,6 +34,7 @@ import qualified GHC.CmmToAsm.X86.Regs as X86 import qualified GHC.CmmToAsm.X86.RegInfo as X86 import qualified GHC.CmmToAsm.PPC.Regs as PPC import qualified GHC.CmmToAsm.AArch64.Regs as AArch64 +import qualified GHC.CmmToAsm.RISCV64.Regs as RISCV64 targetVirtualRegSqueeze :: Platform -> RegClass -> VirtualReg -> Int @@ -107,7 +108,7 @@ targetMkVirtualReg platform ArchAlpha -> panic "targetMkVirtualReg ArchAlpha" ArchMipseb -> panic "targetMkVirtualReg ArchMipseb" ArchMipsel -> panic "targetMkVirtualReg ArchMipsel" - ArchRISCV64 -> panic "targetMkVirtualReg ArchRISCV64" + ArchRISCV64 -> RISCV64.mkVirtualReg ArchLoongArch64->panic "targetMkVirtualReg ArchLoongArch64" ArchJavaScript-> panic "targetMkVirtualReg ArchJavaScript" ArchWasm32 -> panic "targetMkVirtualReg ArchWasm32" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4481208a93ddfe0a1d7ba979aff80928b2955354...11fdb7194f6a4a15f3897b0889e2f7648fecd594 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4481208a93ddfe0a1d7ba979aff80928b2955354...11fdb7194f6a4a15f3897b0889e2f7648fecd594 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Apr 30 23:03:52 2023 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 30 Apr 2023 19:03:52 -0400 Subject: [Git][ghc/ghc][wip/T23070-unify] 3 commits: Add the Unsatisfiable class Message-ID: <644ef3d870bb6_178e74147278f1024019ac@gitlab.mail> Simon Peyton Jones pushed to branch wip/T23070-unify at Glasgow Haskell Compiler / GHC Commits: 57277662 by sheaf at 2023-04-29T20:23:06+02:00 Add the Unsatisfiable class This commit implements GHC proposal #433, adding the Unsatisfiable class to the GHC.TypeError module. This provides an alternative to TypeError for which error reporting is more predictable: we report it when we are reporting unsolved Wanted constraints. Fixes #14983 #16249 #16906 #18310 #20835 - - - - - 00a8a5ff by Torsten Schmits at 2023-04-30T03:45:09-04:00 Add structured error messages for GHC.Rename.Names Tracking ticket: #20115 MR: !10336 This converts uses of `mkTcRnUnknownMessage` to newly added constructors of `TcRnMessage`. - - - - - d38c4d93 by Simon Peyton Jones at 2023-04-30T22:45:31+01:00 Use the eager unifier in the constraint solver This patch continues the refactoring of the constraint solver described in #23070. The Big Deal in this patch is to call the regular, eager unifier from the constraint solver, when we want to create new equalities. This replaces the existing, unifyWanted which amounted to yet-another-unifier, so it reduces duplication of a rather subtle piece of technology. See * Note [The eager unifier] in GHC.Tc.Utils.Unify * GHC.Tc.Solver.Monad.wrapUnifierTcS I did lots of other refactoring along the way * I simplified the treatment of right hand sides that contain CoercionHoles. Now, a constraint that contains a hetero-kind CoercionHole is non-canonical, and cannot be used for rewriting or unification alike. This required me to add the ch_hertero_kind flag to CoercionHole, with consequent knock-on effects. See wrinkle (2) of `Note [Equalities with incompatible kinds]` in GHC.Tc.Solver.Equality. * I refactored the StopOrContinue type to add StartAgain, so that after a fundep improvement (for example) we can simply start the pipeline again. * I got rid of the unpleasant (and inefficient) rewriterSetFromType/Co functions. With Richard I concluded that they are never needed. * I discovered Wrinkle (W1) in Note [Wanteds rewrite Wanteds] in GHC.Tc.Types.Constraint, and therefore now prioritise non-rewritten equalities. Quite a few error messages change, I think always for the better. Compiler runtime stays about the same, with one outlier: a 17% improvement in T17836 Metric Decrease: T17836 T18223 - - - - - 27 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion.hs-boot - compiler/GHC/Core/Predicate.hs - compiler/GHC/Core/Reduction.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/Bag.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Instance/Class.hs - compiler/GHC/Tc/Instance/FunDeps.hs - compiler/GHC/Tc/Plugin.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/InertSet.hs - compiler/GHC/Tc/Solver/Interact.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68b73ac0a880e73cbc990acd1464848600c9703b...d38c4d93c18b531683de19e2057b476d7fd89ca1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68b73ac0a880e73cbc990acd1464848600c9703b...d38c4d93c18b531683de19e2057b476d7fd89ca1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: