[Git][ghc/ghc][wip/ipe-optimisation-9.4] IPE data compression

Ben Gamari (@bgamari) gitlab at gitlab.haskell.org
Thu Jun 22 21:04:24 UTC 2023



Ben Gamari pushed to branch wip/ipe-optimisation-9.4 at Glasgow Haskell Compiler / GHC


Commits:
d12dc60b by Finley McIlwaine at 2023-06-22T17:03:54-04:00
IPE data compression

IPE data resulting from the `-finfo-table-map` flag may now be
compressed by configuring the GHC build with the
`--enable-ipe-data-compression` flag. This results in about a 20%
reduction in the size of IPE-enabled build results.

The compression library, zstd, may optionally be statically linked by
configuring with the `--enabled-static-libzstd` flag (on non-darwin
platforms)

libzstd version 1.4.0 or greater is required.

- - - - -


27 changed files:

- .gitlab-ci.yml
- .gitlab/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/GHC/Data/FastString.hs
- compiler/GHC/StgToCmm/InfoTableProv.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/debug-info.rst
- hadrian/cfg/system.config.in
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Settings/Packages.hs
- libraries/bytestring
- libraries/containers
- libraries/ghc-bignum/gmp/gmp-tarballs
- libraries/parsec
- libraries/text
- m4/fp_find_libnuma.m4
- + m4/fp_find_libzstd.m4
- rts/IPE.c
- rts/IPE.h
- rts/include/rts/IPE.h
- rts/rts.cabal.in
- testsuite/tests/rts/ipe/ipeEventLog_fromMap.c
- testsuite/tests/rts/ipe/ipeMap.c
- testsuite/tests/rts/ipe/ipe_lib.c
- testsuite/tests/rts/ipe/ipe_lib.h


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: 58d08589371e78829a3279c6f8b1241e155d7f70
+  DOCKER_REV: 243a00f06550e6b9a00fa0f1530d1bb761e8b7cc
 
   # Sequential version number of all cached things.
   # Bump to invalidate GitLab CI cache.


=====================================
.gitlab/gen_ci.hs
=====================================
@@ -116,6 +116,7 @@ data BuildConfig
                 , llvmBootstrap  :: Bool
                 , withAssertions :: Bool
                 , withNuma       :: Bool
+                , withZstd       :: Bool
                 , fullyStatic    :: Bool
                 , tablesNextToCode :: Bool
                 , threadSanitiser :: Bool
@@ -126,6 +127,7 @@ configureArgsStr :: BuildConfig -> String
 configureArgsStr bc = intercalate " " $
   ["--enable-unregisterised"| unregisterised bc ]
   ++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
+  ++ ["--enable-ipe-data-compression" | withZstd bc ]
 
 -- Compute the hadrian flavour from the BuildConfig
 mkJobFlavour :: BuildConfig -> Flavour
@@ -156,6 +158,7 @@ vanilla = BuildConfig
   , llvmBootstrap  = False
   , withAssertions = False
   , withNuma = False
+  , withZstd = False
   , fullyStatic = False
   , tablesNextToCode = True
   , threadSanitiser = False
@@ -180,6 +183,9 @@ debug = vanilla { buildFlavour = SlowValidate
                 , withNuma = True
                 }
 
+zstdIpe :: BuildConfig
+zstdIpe = vanilla { withZstd = True }
+
 static :: BuildConfig
 static = vanilla { fullyStatic = True }
 
@@ -494,7 +500,8 @@ data Rule = FastCI       -- ^ Run this job when the fast-ci label is set
           | Nightly      -- ^ Only run this job in the nightly pipeline
           | LLVMBackend  -- ^ Only run this job when the "LLVM backend" label is present
           | FreeBSDLabel -- ^ Only run this job when the "FreeBSD" label is set.
-          | ARMLabel    -- ^ Only run this job when the "ARM" label is set.
+          | ARMLabel     -- ^ Only run this job when the "ARM" label is set.
+          | IpeData      -- ^ Only run this job when the "IPE" label is set.
           | Disable      -- ^ Don't run this job.
           deriving (Bounded, Enum, Ord, Eq)
 
@@ -521,6 +528,8 @@ ruleString On ReleaseOnly = "$RELEASE_JOB == \"yes\""
 ruleString Off ReleaseOnly = "$RELEASE_JOB != \"yes\""
 ruleString On Nightly = "$NIGHTLY"
 ruleString Off Nightly = "$NIGHTLY == null"
+ruleString On IpeData = "$CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/"
+ruleString Off IpeData = true
 ruleString On Disable = false
 ruleString Off Disable = true
 
@@ -791,6 +800,7 @@ jobs = M.fromList $ concatMap flattenJobGroup $
      , standardBuilds I386 (Linux Debian9)
      , allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) static)
      , disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) staticNativeInt))
+     , addValidateRule IpeData (validateBuilds Amd64 (Linux Debian10) zstdIpe)
      ]
 
   where


=====================================
.gitlab/jobs.yaml
=====================================
@@ -35,7 +35,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -97,7 +97,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -155,7 +155,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/) && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -216,7 +216,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -274,7 +274,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -337,7 +337,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -396,7 +396,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -458,7 +458,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -517,7 +517,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -582,7 +582,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -643,7 +643,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -705,7 +705,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -767,7 +767,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -827,7 +827,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -886,7 +886,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -945,7 +945,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1005,7 +1005,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1064,7 +1064,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1083,7 +1083,7 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "",
+      "CONFIGURE_ARGS": "--enable-ipe-data-compression",
       "TEST_ENV": "x86_64-linux-deb10-validate",
       "XZ_OPT": "-9"
     }
@@ -1123,7 +1123,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1182,7 +1182,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1241,7 +1241,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1302,7 +1302,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1361,7 +1361,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1420,7 +1420,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1482,7 +1482,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1543,7 +1543,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1605,7 +1605,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1666,7 +1666,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1721,7 +1721,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1780,7 +1780,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1843,7 +1843,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1907,7 +1907,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1967,7 +1967,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2030,7 +2030,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2090,7 +2090,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2156,7 +2156,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2218,7 +2218,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2281,7 +2281,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2344,7 +2344,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2405,7 +2405,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2465,7 +2465,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2525,7 +2525,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2585,7 +2585,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2645,7 +2645,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2708,7 +2708,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2770,7 +2770,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2832,7 +2832,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2895,7 +2895,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2951,7 +2951,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3011,7 +3011,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3075,7 +3075,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3139,7 +3139,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3199,7 +3199,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3260,7 +3260,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3321,7 +3321,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3380,7 +3380,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3439,7 +3439,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3497,7 +3497,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3556,7 +3556,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3614,7 +3614,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*IPE.*/) && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3633,7 +3633,7 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "",
+      "CONFIGURE_ARGS": "--enable-ipe-data-compression",
       "TEST_ENV": "x86_64-linux-deb10-validate"
     }
   },
@@ -3672,7 +3672,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3730,7 +3730,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3789,7 +3789,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3849,7 +3849,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3907,7 +3907,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3965,7 +3965,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -4026,7 +4026,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -4086,7 +4086,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4147,7 +4147,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4207,7 +4207,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4261,7 +4261,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4319,7 +4319,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],


=====================================
compiler/GHC/Data/FastString.hs
=====================================
@@ -52,6 +52,9 @@ module GHC.Data.FastString
         fastStringToShortByteString,
         mkFastStringShortByteString,
 
+        -- * ShortText
+        fastStringToShortText,
+
         -- * FastZString
         FastZString,
         hPutFZS,
@@ -118,6 +121,7 @@ import GHC.Utils.IO.Unsafe
 import GHC.Utils.Panic.Plain
 import GHC.Utils.Misc
 import GHC.Data.FastMutInt
+import GHC.Data.ShortText (ShortText(..))
 
 import Control.Concurrent.MVar
 import Control.DeepSeq
@@ -526,6 +530,9 @@ mkFastStringShortByteString :: ShortByteString -> FastString
 mkFastStringShortByteString sbs =
   inlinePerformIO $ mkFastStringWith (mkNewFastStringShortByteString sbs) sbs
 
+fastStringToShortText :: FastString -> ShortText
+fastStringToShortText = ShortText . fs_sbs
+
 -- | Creates a UTF-8 encoded 'FastString' from a 'String'
 mkFastString :: String -> FastString
 {-# NOINLINE[1] mkFastString #-}


=====================================
compiler/GHC/StgToCmm/InfoTableProv.hs
=====================================
@@ -1,66 +1,188 @@
+{-# LANGUAGE CPP #-}
+
 module GHC.StgToCmm.InfoTableProv (emitIpeBufferListNode) where
 
+import Foreign
+
+#if defined(HAVE_LIBZSTD)
+import Foreign.C.Types
+import qualified Data.ByteString.Internal as BSI
+import GHC.IO (unsafePerformIO)
+#endif
+
 import GHC.Prelude
 import GHC.Platform
+import GHC.Types.SrcLoc (pprUserRealSpan, srcSpanFile)
 import GHC.Unit.Module
 import GHC.Utils.Outputable
-import GHC.Types.SrcLoc (pprUserRealSpan, srcSpanFile)
-import GHC.Data.FastString (unpackFS)
+import GHC.Data.FastString (fastStringToShortText)
 
+import GHC.Cmm
 import GHC.Cmm.CLabel
-import GHC.Cmm.Expr
 import GHC.Cmm.Utils
+
 import GHC.StgToCmm.Config
-import GHC.StgToCmm.Lit (newByteStringCLit)
 import GHC.StgToCmm.Monad
-import GHC.StgToCmm.Utils
 
 import GHC.Data.ShortText (ShortText)
 import qualified GHC.Data.ShortText as ST
 
-import qualified Data.Map.Strict as M
 import Control.Monad.Trans.State.Strict
+
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Builder as BSB
 import qualified Data.ByteString.Lazy as BSL
+import qualified Data.Map.Strict as M
+
+{-
+Note [Compression and Decompression of IPE data]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Compiling with `-finfo-table-map` causes build results to include a map from
+info tables to source positions called the info table provenance entry (IPE)
+map. See Note [Mapping Info Tables to Source Positions]. The IPE information
+can grow the size of build results significantly. At the time of writing, a
+default build of GHC results in a total of 109M of libHSghc-*.so build results.
+A default+ipe build of GHC (see ./hadrian/doc/flavours.md) results in 262M of
+libHSghc-*.so build results without compression.
 
-emitIpeBufferListNode :: Module
-                      -> [InfoProvEnt]
-                      -> FCode ()
+We reduce the impact of IPE data on the size of build results by compressing
+the data before it is emitted using the zstd compression library. See
+Note [The Info Table Provenance Entry (IPE) Map] for information on the layout
+of IPE data on disk and in the RTS. We cannot simply compress all data held in
+the IPE entry buffer, as the pointers to info tables must be converted to
+memory addresses during linking. Therefore, we can only compress the strings
+table and the IPE entries themselves (which essentially only consist of indices
+into the strings table).
+
+With compression, a default+ipe build of GHC results in a total of 205M of
+libHSghc-*.so build results. This is over a 20% reduction from the uncompressed
+case.
+
+Decompression happens lazily, as it only occurs when the IPE map is
+constructed (which is also done lazily on first lookup or traversal). During
+construction, the 'compressed' field of each IPE buffer list node is examined.
+If the field indicates that the data has been compressed, the entry data and
+strings table are decompressed before continuing with the normal IPE map
+construction.
+-}
+
+emitIpeBufferListNode ::
+     Module
+  -> [InfoProvEnt]
+  -> FCode ()
 emitIpeBufferListNode _ [] = return ()
 emitIpeBufferListNode this_mod ents = do
     cfg <- getStgToCmmConfig
-    let ctx      = stgToCmmContext  cfg
+
+    tables_lbl  <- mkStringLitLabel <$> newUnique
+    strings_lbl <- mkStringLitLabel <$> newUnique
+    entries_lbl <- mkStringLitLabel <$> newUnique
+
+    let ctx      = stgToCmmContext cfg
         platform = stgToCmmPlatform cfg
+        int n    = mkIntCLit platform n
+
+        (cg_ipes, strtab) = flip runState emptyStringTable $ do
+          module_name <- lookupStringTable $ ST.pack $ renderWithContext ctx (ppr this_mod)
+          mapM (toCgIPE platform ctx module_name) ents
+
+        tables :: [CmmStatic]
+        tables = map (CmmStaticLit . CmmLabel . ipeInfoTablePtr) cg_ipes
+
+        uncompressed_strings :: BS.ByteString
+        uncompressed_strings = getStringTableStrings strtab
+
+        strings_bytes :: BS.ByteString
+        strings_bytes = compress defaultCompressionLevel uncompressed_strings
+
+        strings :: [CmmStatic]
+        strings = [CmmString strings_bytes]
+
+        uncompressed_entries :: BS.ByteString
+        uncompressed_entries = toIpeBufferEntries (platformByteOrder platform) cg_ipes
 
-    let (cg_ipes, strtab) = flip runState emptyStringTable $ do
-            module_name <- lookupStringTable $ ST.pack $ renderWithContext ctx (ppr this_mod)
-            mapM (toCgIPE platform ctx module_name) ents
-
-    let -- Emit the fields of an IpeBufferEntry struct.
-        toIpeBufferEntry :: CgInfoProvEnt -> [CmmLit]
-        toIpeBufferEntry cg_ipe =
-            [ CmmLabel (ipeInfoTablePtr cg_ipe)
-            , strtab_offset (ipeTableName cg_ipe)
-            , strtab_offset (ipeClosureDesc cg_ipe)
-            , strtab_offset (ipeTypeDesc cg_ipe)
-            , strtab_offset (ipeLabel cg_ipe)
-            , strtab_offset (ipeModuleName cg_ipe)
-            , strtab_offset (ipeSrcFile cg_ipe)
-            , strtab_offset (ipeSrcSpan cg_ipe)
-            , int32 0
-            ]
-
-        int n = mkIntCLit platform n
-        int32 n = CmmInt n W32
-        strtab_offset (StrTabOffset n) = int32 (fromIntegral n)
-
-    strings <- newByteStringCLit (getStringTableStrings strtab)
-    let lits = [ zeroCLit platform     -- 'next' field
-               , strings               -- 'strings' field
-               , int $ length cg_ipes  -- 'count' field
-               ] ++ concatMap toIpeBufferEntry cg_ipes
-    emitDataLits (mkIPELabel this_mod) lits
+        entries_bytes :: BS.ByteString
+        entries_bytes = compress defaultCompressionLevel uncompressed_entries
+
+        entries :: [CmmStatic]
+        entries = [CmmString entries_bytes]
+
+        ipe_buffer_lbl :: CLabel
+        ipe_buffer_lbl = mkIPELabel this_mod
+
+        ipe_buffer_node :: [CmmStatic]
+        ipe_buffer_node = map CmmStaticLit
+          [ -- 'next' field
+            zeroCLit platform
+
+            -- 'compressed' field
+          , int do_compress
+
+            -- 'count' field
+          , int $ length cg_ipes
+
+            -- 'tables' field
+          , CmmLabel tables_lbl
+
+            -- 'entries' field
+          , CmmLabel entries_lbl
+
+            -- 'entries_size' field (decompressed size)
+          , int $ BS.length uncompressed_entries
+
+            -- 'string_table' field
+          , CmmLabel strings_lbl
+
+            -- 'string_table_size' field (decompressed size)
+          , int $ BS.length uncompressed_strings
+          ]
+
+    -- Emit the list of info table pointers
+    emitDecl $ CmmData
+      (Section Data tables_lbl)
+      (CmmStaticsRaw tables_lbl tables)
+
+    -- Emit the strings table
+    emitDecl $ CmmData
+      (Section Data strings_lbl)
+      (CmmStaticsRaw strings_lbl strings)
+
+    -- Emit the list of IPE buffer entries
+    emitDecl $ CmmData
+      (Section Data entries_lbl)
+      (CmmStaticsRaw entries_lbl entries)
+
+    -- Emit the IPE buffer list node
+    emitDecl $ CmmData
+      (Section Data ipe_buffer_lbl)
+      (CmmStaticsRaw ipe_buffer_lbl ipe_buffer_node)
+
+-- | Emit the fields of an IpeBufferEntry struct for each entry in a given list.
+toIpeBufferEntries ::
+     ByteOrder       -- ^ Byte order to write the data in
+  -> [CgInfoProvEnt] -- ^ List of IPE buffer entries
+  -> BS.ByteString
+toIpeBufferEntries byte_order cg_ipes =
+      BSL.toStrict . BSB.toLazyByteString . mconcat
+    $ map (mconcat . map word32Builder . to_ipe_buf_ent) cg_ipes
+  where
+    to_ipe_buf_ent :: CgInfoProvEnt -> [Word32]
+    to_ipe_buf_ent cg_ipe =
+      [ ipeTableName cg_ipe
+      , ipeClosureDesc cg_ipe
+      , ipeTypeDesc cg_ipe
+      , ipeLabel cg_ipe
+      , ipeModuleName cg_ipe
+      , ipeSrcFile cg_ipe
+      , ipeSrcSpan cg_ipe
+      , 0 -- padding
+      ]
+
+    word32Builder :: Word32 -> BSB.Builder
+    word32Builder = case byte_order of
+      BigEndian    -> BSB.word32BE
+      LittleEndian -> BSB.word32LE
 
 toCgIPE :: Platform -> SDocContext -> StrTabOffset -> InfoProvEnt -> State StringTable CgInfoProvEnt
 toCgIPE platform ctx module_name ipe = do
@@ -70,13 +192,13 @@ toCgIPE platform ctx module_name ipe = do
     let label_str = maybe "" snd (infoTableProv ipe)
     let (src_loc_file, src_loc_span) =
             case infoTableProv ipe of
-              Nothing -> ("", "")
+              Nothing -> (mempty, "")
               Just (span, _) ->
-                  let file = unpackFS $ srcSpanFile span
+                  let file = fastStringToShortText $ srcSpanFile span
                       coords = renderWithContext ctx (pprUserRealSpan False span)
                   in (file, coords)
-    label <- lookupStringTable $ ST.pack label_str
-    src_file <- lookupStringTable $ ST.pack src_loc_file
+    label    <- lookupStringTable $ ST.pack label_str
+    src_file <- lookupStringTable src_loc_file
     src_span <- lookupStringTable $ ST.pack src_loc_span
     return $ CgInfoProvEnt { ipeInfoTablePtr = infoTablePtr ipe
                            , ipeTableName = table_name
@@ -104,7 +226,7 @@ data StringTable = StringTable { stStrings :: DList ShortText
                                , stLookup :: !(M.Map ShortText StrTabOffset)
                                }
 
-newtype StrTabOffset = StrTabOffset Int
+type StrTabOffset = Word32
 
 emptyStringTable :: StringTable
 emptyStringTable =
@@ -129,9 +251,50 @@ lookupStringTable str = state $ \st ->
                         , stLength  = stLength st + ST.byteLength str + 1
                         , stLookup  = M.insert str res (stLookup st)
                         }
-              res = StrTabOffset (stLength st)
+              res = fromIntegral (stLength st)
           in (res, st')
 
+do_compress :: Int
+compress    :: Int -> BS.ByteString -> BS.ByteString
+#if !defined(HAVE_LIBZSTD)
+do_compress   = 0
+compress _ bs = bs
+#else
+do_compress = 1
+
+compress clvl (BSI.PS srcForeignPtr off len) = unsafePerformIO $
+    withForeignPtr srcForeignPtr $ \srcPtr -> do
+      maxCompressedSize <- zstd_compress_bound $ fromIntegral len
+      dstForeignPtr <- BSI.mallocByteString (fromIntegral maxCompressedSize)
+      withForeignPtr dstForeignPtr $ \dstPtr -> do
+        compressedSize <- fromIntegral <$>
+          zstd_compress
+            dstPtr
+            maxCompressedSize
+            (srcPtr `plusPtr` off)
+            (fromIntegral len)
+            (fromIntegral clvl)
+        BSI.create compressedSize $ \p -> BSI.memcpy p dstPtr compressedSize
+
+foreign import ccall unsafe "ZSTD_compress"
+    zstd_compress ::
+         Ptr dst -- ^ Destination buffer
+      -> CSize   -- ^ Capacity of destination buffer
+      -> Ptr src -- ^ Source buffer
+      -> CSize   -- ^ Size of source buffer
+      -> CInt    -- ^ Compression level
+      -> IO CSize
+
+-- | Compute the maximum compressed size for a given source buffer size
+foreign import ccall unsafe "ZSTD_compressBound"
+    zstd_compress_bound ::
+         CSize -- ^ Size of source buffer
+      -> IO CSize
+#endif
+
+defaultCompressionLevel :: Int
+defaultCompressionLevel = 3
+
 newtype DList a = DList ([a] -> [a])
 
 emptyDList :: DList a


=====================================
compiler/ghc.cabal.in
=====================================
@@ -62,6 +62,14 @@ Flag build-tool-depends
     Description: Use build-tool-depends
     Default: True
 
+Flag with-libzstd
+    Default: False
+    Manual: True
+
+Flag static-libzstd
+    Default: False
+    Manual: True
+
 Library
     Default-Language: Haskell2010
     Exposed: False
@@ -76,6 +84,16 @@ Library
     if flag(build-tool-depends)
       build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants
 
+    if flag(with-libzstd)
+      if flag(static-libzstd)
+        if os(darwin)
+          buildable: False
+        else
+          extra-libraries: :libzstd.a
+      else
+        extra-libraries: zstd
+      CPP-Options: -DHAVE_LIBZSTD
+
     Build-Depends: base       >= 4.11 && < 4.18,
                    deepseq    >= 1.4 && < 1.5,
                    directory  >= 1   && < 1.4,


=====================================
configure.ac
=====================================
@@ -1148,6 +1148,10 @@ AS_IF([test x"${UseLibffiForAdjustors}" = x"YES"],
 )
 AC_SUBST([CabalLibffiAdjustors])
 
+dnl ** IPE data compression
+dnl --------------------------------------------------------------
+FP_FIND_LIBZSTD
+
 dnl ** Other RTS features
 dnl --------------------------------------------------------------
 FP_FIND_LIBDW
@@ -1318,6 +1322,19 @@ echo "\
    makeinfo     : $MAKEINFO
    git          : $GIT
    cabal-install : $CABAL
+"
+
+USING_LIBNUMA=$(if [ "$HaveLibNuma" = "1" ]; then echo "YES"; else echo "NO"; fi;)
+USING_LIBZSTD=$(if [ "$HaveLibZstd" = "1" ]; then echo "YES"; else echo "NO"; fi;)
+STATIC_LIBZSTD=$(if [ "$StaticLibZstd" = "1" ]; then echo "YES"; else echo "NO"; fi;)
+USING_LIBDW=$(if [ "$USE_LIBDW" = "1" ]; then echo "YES"; else echo "NO"; fi;)
+
+echo "\
+   Using optional dependencies:
+      libnuma : $USING_LIBNUMA
+      libzstd : $USING_LIBZSTD
+         statically linked? : $STATIC_LIBZSTD
+      libdw   : $USING_LIBDW
 
    Using LLVM tools
       clang : $ClangCmd


=====================================
docs/users_guide/debug-info.rst
=====================================
@@ -370,9 +370,26 @@ to a source location. This lookup table is generated by using the ``-finfo-table
     also want more precise information about constructor info tables then you
     should also use :ghc-flag:`-fdistinct-constructor-tables`.
 
-    This flag will increase the binary size by quite a lot, depending on how
-    big your project is. For compiling a project the size of GHC the overhead was
-    about 200 megabytes.
+    The :ghc-flag:`-finfo-table-map` flag will increase the binary size by quite
+    a lot, depending on how big your project is. For compiling a project the
+    size of GHC the overhead was about 200 megabytes.
+
+    :since: 9.8
+
+    If you wish to reduce the size of :ghc-flag:`-finfo-table-map` enabled
+    binaries, consider building GHC from source and supplying the
+    ``--enable-ipe-data-compression`` flag to the ``configure`` script. This
+    will cause GHC to compress the :ghc-flag:`-finfo-table-map` related
+    debugging information included in binaries using the
+    `libzstd <https://github.com/facebook/zstd/>`_ compression library.
+    **Note**: This feature requires that the machine building GHC has
+    `libzstd <https://github.com/facebook/zstd/>`_ installed. The compression
+    library ``libzstd`` may optionally be statically linked in the resulting
+    compiler (on non-darwin machines) using the ``--enable-static-libzstd``
+    configure flag.
+
+    In a test compiling GHC itself, the size of the :ghc-flag:`-finfo-table-map`
+    enabled build results was reduced by over 20% when compression was enabled.
 
 .. ghc-flag:: -fdistinct-constructor-tables
     :shortdesc: Generate a fresh info table for each usage


=====================================
hadrian/cfg/system.config.in
=====================================
@@ -201,8 +201,13 @@ libdw-lib-dir       = @LibdwLibDir@
 libnuma-include-dir   = @LibNumaIncludeDir@
 libnuma-lib-dir       = @LibNumaLibDir@
 
+libzstd-include-dir   = @LibZstdIncludeDir@
+libzstd-lib-dir       = @LibZstdLibDir@
+
 # Optional Dependencies:
 #=======================
 
 with-libdw = @UseLibdw@
 with-libnuma = @UseLibNuma@
+use-lib-zstd      = @UseLibZstd@
+static-lib-zstd   = @UseStaticLibZstd@


=====================================
hadrian/src/Oracles/Flag.hs
=====================================
@@ -34,6 +34,8 @@ data Flag = ArSupportsAtFile
           | BootstrapThreadedRts
           | BootstrapEventLoggingRts
           | UseLibffiForAdjustors
+          | UseLibzstd
+          | StaticLibzstd
 
 -- Note, if a flag is set to empty string we treat it as set to NO. This seems
 -- fragile, but some flags do behave like this.
@@ -58,6 +60,8 @@ flag f = do
             BootstrapThreadedRts -> "bootstrap-threaded-rts"
             BootstrapEventLoggingRts -> "bootstrap-event-logging-rts"
             UseLibffiForAdjustors -> "use-libffi-for-adjustors"
+            UseLibzstd           -> "use-lib-zstd"
+            StaticLibzstd        -> "static-lib-zstd"
     value <- lookupSystemConfig key
     when (value `notElem` ["YES", "NO", ""]) . error $ "Configuration flag "
         ++ quote (key ++ " = " ++ value) ++ " cannot be parsed."


=====================================
hadrian/src/Oracles/Setting.hs
=====================================
@@ -60,6 +60,8 @@ data Setting = BuildArch
              | LibdwLibDir
              | LibnumaIncludeDir
              | LibnumaLibDir
+             | LibZstdIncludeDir
+             | LibZstdLibDir
              | LlvmTarget
              | ProjectGitCommitId
              | ProjectName
@@ -162,6 +164,8 @@ setting key = lookupSystemConfig $ case key of
     LibdwLibDir        -> "libdw-lib-dir"
     LibnumaIncludeDir  -> "libnuma-include-dir"
     LibnumaLibDir      -> "libnuma-lib-dir"
+    LibZstdIncludeDir  -> "libzstd-include-dir"
+    LibZstdLibDir      -> "libzstd-lib-dir"
     LlvmTarget         -> "llvm-target"
     ProjectGitCommitId -> "project-git-commit-id"
     ProjectName        -> "project-name"


=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -75,6 +75,8 @@ packageArgs = do
             [ andM [expr ghcWithInterpreter, notStage0] `cabalFlag` "internal-interpreter"
             , notM cross `cabalFlag` "terminfo"
             , arg "-build-tool-depends"
+            , flag UseLibzstd `cabalFlag` "with-libzstd"
+            , flag StaticLibzstd `cabalFlag` "static-libzstd"
             ]
 
           , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ]
@@ -290,6 +292,8 @@ rtsPackageArgs = package rts ? do
     libdwLibraryDir   <- getSetting LibdwLibDir
     libnumaIncludeDir <- getSetting LibnumaIncludeDir
     libnumaLibraryDir <- getSetting LibnumaLibDir
+    libzstdIncludeDir <- getSetting LibZstdIncludeDir
+    libzstdLibraryDir <- getSetting LibZstdLibDir
 
     -- Arguments passed to GHC when compiling C and .cmm sources.
     let ghcArgs = mconcat
@@ -397,6 +401,7 @@ rtsPackageArgs = package rts ? do
         , builder (Cabal Setup) ? mconcat
               [ cabalExtraDirs libdwIncludeDir libdwLibraryDir
               , cabalExtraDirs libnumaIncludeDir libnumaLibraryDir
+              , cabalExtraDirs libzstdIncludeDir libzstdLibraryDir
               , useSystemFfi ? cabalExtraDirs ffiIncludeDir ffiLibraryDir
               ]
         , builder (Cc (FindCDependencies CDep)) ? cArgs


=====================================
libraries/bytestring
=====================================
@@ -1 +1 @@
-Subproject commit 9cab76dc861f651c3940e873ce921d9e09733cc8
+Subproject commit 1543e054a314865d89a259065921d5acba03d966


=====================================
libraries/containers
=====================================
@@ -1 +1 @@
-Subproject commit 9f4a93604c66a5e605ce46fc30003b71802b3cfd
+Subproject commit 50175b72dc781f82a419bddafba1bdd758fbee4b


=====================================
libraries/ghc-bignum/gmp/gmp-tarballs
=====================================
@@ -1 +1 @@
-Subproject commit 4f26049af40afb380eaf033ab91404cd2e214919
+Subproject commit 31f9909680ba8fe00d27fd8a6f5d198a0a96c1ac


=====================================
libraries/parsec
=====================================
@@ -1 +1 @@
-Subproject commit 1f542120d9adc5e22f8791a6d595210e93c6c389
+Subproject commit a74c68e948c99621100447014f48ccac7ee0448e


=====================================
libraries/text
=====================================
@@ -1 +1 @@
-Subproject commit e815d4d9bc362f4a3a36a850931fd3504eda967e
+Subproject commit fdb06ff327519f3c0fc6cc9997b7cb7fe8ab8178


=====================================
m4/fp_find_libnuma.m4
=====================================
@@ -30,7 +30,7 @@ AC_DEFUN([FP_FIND_LIBNUMA],
           [Enable NUMA memory policy and thread affinity support in the
            runtime system via numactl's libnuma [default=auto]])])
 
-  if test "$enable_numa" != "no" ; then
+  if test "$enable_numa" = "yes" ; then
     CFLAGS2="$CFLAGS"
     CFLAGS="$LIBNUMA_CFLAGS $CFLAGS"
     LDFLAGS2="$LDFLAGS"
@@ -41,7 +41,7 @@ AC_DEFUN([FP_FIND_LIBNUMA],
     if test "$ac_cv_header_numa_h$ac_cv_header_numaif_h" = "yesyes" ; then
       AC_CHECK_LIB(numa, numa_available,HaveLibNuma=1)
     fi
-    if test "$enable_numa:$HaveLibNuma" = "yes:0" ; then
+    if test "$HaveLibNuma" = "0" ; then
         AC_MSG_ERROR([Cannot find system libnuma (required by --enable-numa)])
     fi
 


=====================================
m4/fp_find_libzstd.m4
=====================================
@@ -0,0 +1,120 @@
+AC_DEFUN([FP_FIND_LIBZSTD],
+[
+  dnl ** Is IPE data compression enabled?
+  dnl --------------------------------------------------------------
+  AC_ARG_ENABLE(
+      ipe-data-compression,
+      [AS_HELP_STRING(
+          [--enable-ipe-data-compression],
+          [Enable compression of info table provenance entries using the
+          zstd compression library [default=no]]
+        )],
+      [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableIpeDataCompression])],
+      [EnableIpeDataCompression=NO]
+    )
+
+  StaticLibZstd=0
+  AC_ARG_ENABLE(
+      static-libzstd,
+      [AS_HELP_STRING(
+          [--enable-static-libzstd],
+          [Statically link the libzstd compression library with the compiler
+          (not compatible with darwin) [default=no]]
+        )],
+      [StaticLibZstd=1],
+      [StaticLibZstd=0]
+    )
+
+  HaveLibZstd=0
+  if test "$EnableIpeDataCompression" = "YES"; then
+    dnl ** Have zstd >= 1.4.0?
+    dnl --------------------------------------------------------------
+    AC_ARG_WITH(
+        libzstd-libraries,
+        [AS_HELP_STRING(
+            [--with-libzstd-libraries=ARG],
+            [Find libraries for libzstd in ARG [default=system default]]
+          )],
+        [
+          LibZstdLibDir="$withval"
+          LIBZSTD_LDFLAGS="-L$withval"
+        ]
+      )
+
+    AC_SUBST(LibZstdLibDir)
+
+    AC_ARG_WITH(
+        libzstd-includes,
+        [AS_HELP_STRING(
+            [--with-libzstd-includes=ARG],
+            [Find includes for libzstd in ARG [default=system default]]
+          )],
+        [
+          LibZstdIncludeDir="$withval"
+          LIBZSTD_CFLAGS="-I$withval"
+        ]
+      )
+
+    AC_SUBST(LibZstdIncludeDir)
+
+    CFLAGS2="$CFLAGS"
+    CFLAGS="$LIBZSTD_CFLAGS $CFLAGS"
+    LDFLAGS2="$LDFLAGS"
+    LDFLAGS="$LIBZSTD_LDFLAGS $LDFLAGS"
+
+    AC_CHECK_HEADERS([zstd.h])
+
+    if test "$ac_cv_header_zstd_h" = "yes" ; then
+      AC_CHECK_LIB(zstd,ZSTD_versionString,HaveLibZstd=1)
+    fi
+    if test "$HaveLibZstd" = "0" ; then
+      AC_MSG_ERROR(
+            [Cannot find system libzstd (required by
+            --enable-ipe-data-compression)]
+          )
+    fi
+
+    # libzstd >= 1.4.0 is required for IPE data compression
+    fp_libzstd_version="`pkg-config --modversion libzstd`"
+    FP_COMPARE_VERSIONS(
+        [$fp_libzstd_version],
+        [-lt],
+        [1.4.0],
+        [AC_MSG_ERROR(
+            [Need at least libzstd version 1.4.0 for
+            --enable-ipe-data-compression])
+          ]
+      )
+
+    CFLAGS="$CFLAGS2"
+    LDFLAGS="$LDFLAGS2"
+  fi
+
+  AC_DEFINE_UNQUOTED([HAVE_LIBZSTD], [$HaveLibZstd], [Define to 1 if you
+    wish to compress IPE data in compiler results (requires libzstd)])
+
+  AC_DEFINE_UNQUOTED([STATIC_LIBZSTD], [$StaticLibZstd], [Define to 1 if you
+    wish to statically link the libzstd compression library in the compiler
+    (requires libzstd)])
+
+  if test $HaveLibZstd = "1" ; then
+    AC_SUBST([UseLibZstd],[YES])
+    AC_SUBST([CabalHaveLibZstd],[True])
+    if test $StaticLibZstd = "1" ; then
+      case "${host_os}" in
+          darwin*)
+            AC_MSG_ERROR(
+                  [--enable-static-libzstd is not compatible with darwin]
+                )
+      esac
+      AC_SUBST([UseStaticLibZstd],[YES])
+      AC_SUBST([CabalStaticLibZstd],[True])
+    else
+      AC_SUBST([UseStaticLibZstd],[NO])
+      AC_SUBST([CabalStaticLibZstd],[False])
+    fi
+  else
+    AC_SUBST([UseLibZstd],[NO])
+    AC_SUBST([CabalHaveLibZstd],[False])
+  fi
+])


=====================================
rts/IPE.c
=====================================
@@ -20,6 +20,10 @@
 #include <fs_rts.h>
 #include <string.h>
 
+#if HAVE_LIBZSTD == 1
+#include <zstd.h>
+#endif
+
 #if defined(TRACING)
 #include "Trace.h"
 #endif
@@ -36,8 +40,9 @@ collecting IPE lists on registration.
 
 It's a singly linked list of IPE list buffers (IpeBufferListNode). These are
 emitted by the code generator, with generally one produced per module. Each
-contains an array of IPE entries and a link field (which is used to link
-buffers onto the pending list.
+contains a pointer to a list of IPE entries, a pointer to a list of info
+table pointers, and a link field (which is used to link buffers onto the
+pending list.
 
 For reasons of space efficiency, IPE entries are represented slightly
 differently in the object file than the InfoProvEnt which we ultimately expose
@@ -77,19 +82,18 @@ void exitIpe(void) { }
 
 #endif // THREADED_RTS
 
-static InfoProvEnt ipeBufferEntryToIpe(const IpeBufferListNode *node, const IpeBufferEntry *ent)
+static InfoProvEnt ipeBufferEntryToIpe(const char *strings, const StgInfoTable *tbl, const IpeBufferEntry ent)
 {
-    const char *strings = node->string_table;
     return (InfoProvEnt) {
-            .info = ent->info,
+            .info = tbl,
             .prov = {
-                .table_name = &strings[ent->table_name],
-                .closure_desc = &strings[ent->closure_desc],
-                .ty_desc = &strings[ent->ty_desc],
-                .label = &strings[ent->label],
-                .module = &strings[ent->module_name],
-                .src_file = &strings[ent->src_file],
-                .src_span = &strings[ent->src_span]
+                .table_name = &strings[ent.table_name],
+                .closure_desc = &strings[ent.closure_desc],
+                .ty_desc = &strings[ent.ty_desc],
+                .label = &strings[ent.label],
+                .module = &strings[ent.module_name],
+                .src_file = &strings[ent.src_file],
+                .src_span = &strings[ent.src_span]
             }
     };
 }
@@ -105,8 +109,18 @@ void dumpIPEToEventLog(void) {
     // Dump pending entries
     IpeBufferListNode *cursor = RELAXED_LOAD(&ipeBufferList);
     while (cursor != NULL) {
+        IpeBufferEntry *entries;
+        char *strings;
+
+        // Decompress if compressed
+        decompressIPEBufferListNodeIfCompressed(cursor, &entries, &strings);
+
         for (uint32_t i = 0; i < cursor->count; i++) {
-            const InfoProvEnt ent = ipeBufferEntryToIpe(cursor, &cursor->entries[i]);
+            const InfoProvEnt ent = ipeBufferEntryToIpe(
+                strings,
+                cursor->tables[i],
+                entries[i]
+            );
             traceIPE(&ent);
         }
         cursor = cursor->next;
@@ -169,16 +183,85 @@ void updateIpeMap() {
     }
 
     while (pending != NULL) {
-        IpeBufferListNode *currentNode = pending;
-        InfoProvEnt *ip_ents = stgMallocBytes(sizeof(InfoProvEnt) * currentNode->count, "updateIpeMap");
-        for (uint32_t i = 0; i < currentNode->count; i++) {
-            const IpeBufferEntry *ent = &currentNode->entries[i];
-            ip_ents[i] = ipeBufferEntryToIpe(currentNode, ent);
-            insertHashTable(ipeMap, (StgWord) ent->info, &ip_ents[i]);
+        IpeBufferListNode *current_node = pending;
+        IpeBufferEntry *entries;
+        char *strings;
+
+        // Decompress if compressed
+        decompressIPEBufferListNodeIfCompressed(current_node, &entries, &strings);
+
+        // Convert the on-disk IPE buffer entry representation (IpeBufferEntry)
+        // into the runtime representation (InfoProvEnt)
+        InfoProvEnt *ip_ents = stgMallocBytes(
+            sizeof(InfoProvEnt) * current_node->count,
+            "updateIpeMap: ip_ents"
+        );
+        for (uint32_t i = 0; i < current_node->count; i++) {
+            const IpeBufferEntry ent = entries[i];
+            const StgInfoTable *tbl = current_node->tables[i];
+            ip_ents[i] = ipeBufferEntryToIpe(strings, tbl, ent);
+            insertHashTable(ipeMap, (StgWord) tbl, &ip_ents[i]);
         }
 
-        pending = currentNode->next;
+        pending = current_node->next;
     }
 
     RELEASE_LOCK(&ipeMapLock);
 }
+
+/* Decompress the IPE data and strings table referenced by an IPE buffer list
+node if it is compressed. No matter whether the data is compressed, the pointers
+referenced by the 'entries_dst' and 'string_table_dst' parameters will point at
+the decompressed IPE data and string table for the given node, respectively,
+upon return from this function.
+*/
+void decompressIPEBufferListNodeIfCompressed(IpeBufferListNode *node, IpeBufferEntry **entries_dst, char **string_table_dst) {
+    if (node->compressed == 1) {
+        // The IPE list buffer node indicates that the strings table and
+        // entries list has been compressed. If zstd is not available, fail.
+        // If zstd is available, decompress.
+#if HAVE_LIBZSTD == 0
+        barf("An IPE buffer list node has been compressed, but the "
+             "decompression library (zstd) is not available."
+);
+#else
+        size_t compressed_sz = ZSTD_findFrameCompressedSize(
+            node->string_table,
+            node->string_table_size
+        );
+        char *decompressed_strings = stgMallocBytes(
+            node->string_table_size,
+            "updateIpeMap: decompressed_strings"
+        );
+        ZSTD_decompress(
+            decompressed_strings,
+            node->string_table_size,
+            node->string_table,
+            compressed_sz
+        );
+        *string_table_dst = decompressed_strings;
+
+        // Decompress the IPE data
+        compressed_sz = ZSTD_findFrameCompressedSize(
+            node->entries,
+            node->entries_size
+        );
+        void *decompressed_entries = stgMallocBytes(
+            node->entries_size,
+            "updateIpeMap: decompressed_entries"
+        );
+        ZSTD_decompress(
+            decompressed_entries,
+            node->entries_size,
+            node->entries,
+            compressed_sz
+        );
+        *entries_dst = decompressed_entries;
+#endif // HAVE_LIBZSTD == 0
+
+    } else {
+        // Not compressed, no need to decompress
+        *entries_dst = node->entries;
+        *string_table_dst = node->string_table;
+    }
+}


=====================================
rts/IPE.h
=====================================
@@ -17,5 +17,6 @@ void dumpIPEToEventLog(void);
 void updateIpeMap(void);
 void initIpe(void);
 void exitIpe(void);
+void decompressIPEBufferListNodeIfCompressed(IpeBufferListNode*, IpeBufferEntry**, char**);
 
 #include "EndPrivate.h"


=====================================
rts/include/rts/IPE.h
=====================================
@@ -52,9 +52,6 @@ typedef uint32_t StringIdx;
 // The size of this must be a multiple of the word size
 // to ensure correct packing.
 typedef struct {
-    // When TNTC is enabled this will point to the entry code
-    // not the info table itself.
-    const StgInfoTable *info;
     StringIdx table_name;
     StringIdx closure_desc;
     StringIdx ty_desc;
@@ -69,10 +66,23 @@ GHC_STATIC_ASSERT(sizeof(IpeBufferEntry) % (WORD_SIZE_IN_BITS / 8) == 0, "sizeof
 
 typedef struct IpeBufferListNode_ {
     struct IpeBufferListNode_ *next;
+
     // Everything below is read-only and generated by the codegen
-    const char *string_table;
+
+    // This flag should be treated as a boolean
+    StgWord compressed;
+
     StgWord count;
-    IpeBufferEntry entries[];
+
+    // When TNTC is enabled, these will point to the entry code
+    // not the info table itself.
+    StgInfoTable **tables;
+
+    IpeBufferEntry *entries;
+    StgWord entries_size; // decompressed size
+
+    char *string_table;
+    StgWord string_table_size; // decompressed size
 } IpeBufferListNode;
 
 void registerInfoProvList(IpeBufferListNode *node);


=====================================
rts/rts.cabal.in
=====================================
@@ -30,6 +30,10 @@ flag libdw
   default: @CabalHaveLibdw@
 flag libnuma
   default: @CabalHaveLibNuma@
+flag libzstd
+  default: @CabalHaveLibZstd@
+flag static-libzstd
+  default: @CabalStaticLibZstd@
 flag 64bit
   default: @Cabal64bit@
 flag leading-underscore
@@ -148,6 +152,14 @@ library
        extra-libraries: elf dw
     if flag(libnuma)
        extra-libraries: numa
+    if flag(libzstd)
+       if flag(static-libzstd)
+          if os(darwin)
+             buildable: False
+          else
+             extra-libraries: :libzstd.a
+       else
+          extra-libraries: zstd
     if !flag(smp)
        cpp-options: -DNOSMP
 


=====================================
testsuite/tests/rts/ipe/ipeEventLog_fromMap.c
=====================================
@@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
     registerInfoProvList(list2);
 
     // Query an IPE to initialize the underlying hash map.
-    lookupIPE(list1->entries[0].info);
+    lookupIPE(list1->tables[0]);
 
     // Trace all IPE events.
     dumpIPEToEventLog();


=====================================
testsuite/tests/rts/ipe/ipeMap.c
=====================================
@@ -40,15 +40,23 @@ void shouldFindNothingInAnEmptyIPEMap(Capability *cap) {
 }
 
 HaskellObj shouldFindOneIfItHasBeenRegistered(Capability *cap) {
-    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode) + sizeof(IpeBufferEntry));
+    // Allocate buffers for IPE buffer list node
+    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode));
+    node->tables = malloc(sizeof(StgInfoTable *));
+    node->entries = malloc(sizeof(IpeBufferEntry));
+
     StringTable st;
     init_string_table(&st);
 
     HaskellObj fortyTwo = UNTAG_CLOSURE(rts_mkInt(cap, 42));
-    node->entries[0] = makeAnyProvEntry(cap, &st, fortyTwo, 42);
-    node->count = 1;
     node->next = NULL;
+    node->compressed = 0;
+    node->count = 1;
+    node->tables[0] = get_itbl(fortyTwo);
+    node->entries[0] = makeAnyProvEntry(cap, &st, 42);
+    node->entries_size = sizeof(IpeBufferEntry);
     node->string_table = st.buffer;
+    node->string_table_size = st.size;
 
     registerInfoProvList(node);
 
@@ -72,15 +80,23 @@ HaskellObj shouldFindOneIfItHasBeenRegistered(Capability *cap) {
 
 void shouldFindTwoIfTwoHaveBeenRegistered(Capability *cap,
                                           HaskellObj fortyTwo) {
-    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode) + sizeof(IpeBufferEntry));
+    // Allocate buffers for IPE buffer list node
+    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode));
+    node->tables = malloc(sizeof(StgInfoTable *));
+    node->entries = malloc(sizeof(IpeBufferEntry));
+
     StringTable st;
     init_string_table(&st);
 
     HaskellObj twentyThree = UNTAG_CLOSURE(rts_mkInt8(cap, 23));
-    node->entries[0] = makeAnyProvEntry(cap, &st, twentyThree, 23);
-    node->count = 1;
     node->next = NULL;
+    node->compressed = 0;
+    node->count = 1;
+    node->tables[0] = get_itbl(twentyThree);
+    node->entries[0] = makeAnyProvEntry(cap, &st, 23);
+    node->entries_size = sizeof(IpeBufferEntry);
     node->string_table = st.buffer;
+    node->string_table_size = st.size;
 
     registerInfoProvList(node);
 
@@ -103,17 +119,26 @@ void shouldFindTwoIfTwoHaveBeenRegistered(Capability *cap,
 }
 
 void shouldFindTwoFromTheSameList(Capability *cap) {
-    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode) + 2 * sizeof(IpeBufferEntry));
+    // Allocate buffers for IPE buffer list node
+    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode));
+    node->tables = malloc(sizeof(StgInfoTable *) * 2);
+    node->entries = malloc(sizeof(IpeBufferEntry) * 2);
+
     StringTable st;
     init_string_table(&st);
 
     HaskellObj one = UNTAG_CLOSURE(rts_mkInt16(cap, 1));
     HaskellObj two = UNTAG_CLOSURE(rts_mkInt32(cap, 2));
-    node->entries[0] = makeAnyProvEntry(cap, &st, one, 1);
-    node->entries[1] = makeAnyProvEntry(cap, &st, two, 2);
-    node->count = 2;
     node->next = NULL;
+    node->compressed = 0;
+    node->count = 2;
+    node->tables[0] = get_itbl(one);
+    node->tables[1] = get_itbl(two);
+    node->entries[0] = makeAnyProvEntry(cap, &st, 1);
+    node->entries[1] = makeAnyProvEntry(cap, &st, 2);
+    node->entries_size = sizeof(IpeBufferEntry) * 2;
     node->string_table = st.buffer;
+    node->string_table_size = st.size;
 
     registerInfoProvList(node);
 


=====================================
testsuite/tests/rts/ipe/ipe_lib.c
=====================================
@@ -25,9 +25,8 @@ uint32_t add_string(StringTable *st, const char *s) {
     return n;
 }
 
-IpeBufferEntry makeAnyProvEntry(Capability *cap, StringTable *st, HaskellObj closure, int i) {
+IpeBufferEntry makeAnyProvEntry(Capability *cap, StringTable *st, int i) {
     IpeBufferEntry provEnt;
-    provEnt.info = get_itbl(closure);
 
     unsigned int tableNameLength = strlen("table_name_") + 3 /* digits */ + 1 /* null character */;
     char *tableName = malloc(sizeof(char) * tableNameLength);
@@ -69,15 +68,27 @@ IpeBufferEntry makeAnyProvEntry(Capability *cap, StringTable *st, HaskellObj clo
 
 IpeBufferListNode *makeAnyProvEntries(Capability *cap, int start, int end) {
     const int n = end - start;
-    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode) + n * sizeof(IpeBufferEntry));
+
+    // Allocate buffers for IpeBufferListNode
+    IpeBufferListNode *node = malloc(sizeof(IpeBufferListNode));
+    node->tables = malloc(sizeof(StgInfoTable *) * n);
+    node->entries = malloc(sizeof(IpeBufferEntry) * n);
+
     StringTable st;
     init_string_table(&st);
+
+    // Make the entries and fill the buffers
     for (int i=start; i < end; i++) {
         HaskellObj closure = rts_mkInt(cap, 42);
-        node->entries[i] = makeAnyProvEntry(cap, &st, closure, i);
+        node->tables[i]  = get_itbl(closure);
+        node->entries[i] = makeAnyProvEntry(cap, &st, i);
     }
+
+    // Set the rest of the fields
     node->next = NULL;
+    node->compressed = 0;
     node->count = n;
     node->string_table = st.buffer;
+
     return node;
 }


=====================================
testsuite/tests/rts/ipe/ipe_lib.h
=====================================
@@ -12,6 +12,6 @@ void init_string_table(StringTable *st);
 uint32_t add_string(StringTable *st, const char *s);
 
 IpeBufferListNode *makeAnyProvEntries(Capability *cap, int start, int end);
-IpeBufferEntry makeAnyProvEntry(Capability *cap, StringTable *st, HaskellObj closure, int i);
+IpeBufferEntry makeAnyProvEntry(Capability *cap, StringTable *st, int i);
 void dumpIPEToEventLog(void);
 



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d12dc60bf8b9c2d6a8c060564ec3e92eb2c755eb

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d12dc60bf8b9c2d6a8c060564ec3e92eb2c755eb
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230622/ac4c52ec/attachment-0001.html>


More information about the ghc-commits mailing list