[Git][ghc/ghc][master] testsuite: improve coverage of foundation test
by Marge Bot (@marge-bot) 18 Dec '25
by Marge Bot (@marge-bot) 18 Dec '25
18 Dec '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
bd38b76c by Cheng Shao at 2025-12-18T13:20:31-05:00
testsuite: improve coverage of foundation test
This patch refactors the `foundation` test a bit to improve coverage:
- Instead of using a hard-coded seed, a random seed is now taken from
the command line, and printed upon test failure. This improves test
coverage over many future CI runs, and shall a failure occur, the
seed is available in the CI log for local reproduction.
- The iterations count is bumped to 1000 instead of 100, similar to
the bump in `test-primops`. Runtime timeout is bumped 2x just to be
safe.
- Improve `newLCGGen` by using non-atomic loads/stores on a
`MutableByteArray#` for storing mutable `Word64`, this test doesn't
use parallelism in the first place
- Fixed a few compiler warnings and removed redundant pragmas and
imports
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
3 changed files:
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- testsuite/tests/numeric/should_run/foundation.stdout
Changes:
=====================================
testsuite/tests/numeric/should_run/all.T
=====================================
@@ -3,6 +3,8 @@
# extra run flags
# expected process return value, if not zero
+import random
+
test('arith001', normal, compile_and_run, [''])
test('arith002', normal, compile_and_run, [''])
test('arith003', normal, compile_and_run, [''])
@@ -82,7 +84,7 @@ test('IntegerToFloat', normal, compile_and_run, [''])
test('T20291', normal, compile_and_run, [''])
test('T22282', normal, compile_and_run, [''])
test('T22671', js_fragile(24259), compile_and_run, [''])
-test('foundation', [when(js_arch(), run_timeout_multiplier(2)), js_fragile(24259), extra_ways(['optasm','ghci','ghci-opt'])], compile_and_run, ['-package transformers -fno-break-points'])
+test('foundation', [run_timeout_multiplier(2), js_fragile(24259), extra_ways(['optasm','ghci','ghci-opt']), extra_run_opts(str(random.getrandbits(64)))], compile_and_run, ['-fno-break-points'])
test('T24066', normal, compile_and_run, [''])
test('div01', normal, compile_and_run, [''])
test('T24245', normal, compile_and_run, [''])
=====================================
testsuite/tests/numeric/should_run/foundation.hs
=====================================
@@ -10,9 +10,7 @@
compare the result of the primop wrappers with the results of interpretation.
-}
-{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeAbstractions #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DerivingStrategies #-}
@@ -25,28 +23,23 @@ module Main
( main
) where
+import Data.Array.Byte
import Data.Bits (Bits((.&.), bit), FiniteBits, finiteBitSize)
import Data.Word
import Data.Int
import GHC.Natural
import Data.Typeable
-import Data.Proxy
import GHC.Int
import GHC.Word
-import GHC.Word
import Data.Function
import GHC.Prim
import Control.Monad.Reader
-import System.IO
-import Foreign.Marshal.Alloc
-import Foreign.Storable
-import Foreign.Ptr
import Data.List (intercalate)
-import Data.IORef
+import System.Environment (getArgs)
+import Text.Read (readMaybe)
import Unsafe.Coerce
import GHC.Types
import Data.Char
-import Data.Semigroup
import System.Exit
import qualified GHC.Internal.PrimopWrappers as Wrapper
@@ -194,11 +187,16 @@ newtype LCGGen = LCGGen { randomWord64 :: IO Word64 }
data LCGParams = LCGParams { seed :: Word64, a :: Word64, c :: Word64, m :: Word64 }
newLCGGen :: LCGParams -> IO LCGGen
-newLCGGen LCGParams{..} = do
- var <- newIORef (fromIntegral seed)
- return $ LCGGen $ do
- atomicModifyIORef' var (\old_v -> let new_val = (old_v * a + c) `mod` m in (new_val, new_val))
-
+newLCGGen LCGParams {seed = W64# seed#, ..} = do
+ MutableByteArray mba# <- IO $ \s0 -> case newByteArray# 8# s0 of
+ (# s1, mba# #) -> case writeWord64Array# mba# 0# seed# s1 of
+ s2 -> (# s2, MutableByteArray mba# #)
+ pure $ LCGGen $ IO $ \s0 -> case readWord64Array# mba# 0# s0 of
+ (# s1, old_val# #) ->
+ let old_val = W64# old_val#
+ !new_val@(W64# new_val#) = (old_val * a + c) `mod` m
+ in case writeWord64Array# mba# 0# new_val# s1 of
+ s2 -> (# s2, new_val #)
runPropertyCheck (PropertyBinaryOp res desc s1 s2) =
if res then return Success
@@ -211,7 +209,7 @@ runPropertyCheck (PropertyAnd a1 a2) = (<>) <$> runPropertyCheck a1 <*> runPrope
runProperty :: Property -> ReaderT RunS IO Result
runProperty (Prop p) = do
- let iterations = 100
+ let iterations = 1000 :: Int
loop iterations iterations
where
loop iterations 0 = do
@@ -257,14 +255,15 @@ runTestInternal (Property name p) = do
nest label $ runProperty (property p)
-runTests :: Test -> IO ()
-runTests t = do
+runTests :: Word64 -> Test -> IO ()
+runTests seed t = do
-- These params are the same ones as glibc uses.
- h <- newLCGGen (LCGParams { seed = 1238123213, m = 2^31, a = 1103515245, c = 12345 })
+ h <- newLCGGen (LCGParams { seed, m = 2 ^ (31 :: Int), a = 1103515245, c = 12345 })
res <- runReaderT (runTestInternal t) (RunS 0 h [])
case res of
Success -> return ()
Failure tests -> do
+ putStrLn $ "Seed: " ++ show seed
putStrLn $ "These tests failed: \n" ++ intercalate " \n" (map (showStack 0 . reverse) tests)
exitFailure
@@ -455,7 +454,19 @@ instance TestPrimop LowerBitsAreDefined where
twoNonZero :: (a -> a -> b) -> a -> NonZero a -> b
twoNonZero f x (NonZero y) = f x y
-main = runTests (Group "ALL" [testNumberRefs, testPrimops])
+getSeedFromArgs :: IO Word64
+getSeedFromArgs = do
+ args <- getArgs
+ case args of
+ [arg] -> case readMaybe arg of
+ Just seed -> pure seed
+ Nothing -> die $ "Invalid seed (expected Word64): " ++ show arg
+ _ -> die "Usage: foundation <seed>"
+
+main :: IO ()
+main = do
+ seed <- getSeedFromArgs
+ runTests seed (Group "ALL" [testNumberRefs, testPrimops])
-- Test an interpreted primop vs a compiled primop
testPrimops = Group "primop"
=====================================
testsuite/tests/numeric/should_run/foundation.stdout
=====================================
@@ -3,1048 +3,1048 @@ Group ALL
Group Int
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Int8
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Int16
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Int32
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Int64
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Integer
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Word
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Word8
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Word16
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Word32
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group Word64
Group Integral
Running FromIntegral(Integer(a)) == a
- Passed 100 iterations
+ Passed 1000 iterations
Group Property
Running Eq
- Passed 100 iterations
+ Passed 1000 iterations
Running Show
- Passed 100 iterations
+ Passed 1000 iterations
Running Ord
- Passed 100 iterations
+ Passed 1000 iterations
Running <
- Passed 100 iterations
+ Passed 1000 iterations
Group Additive
Running a + azero == a
- Passed 100 iterations
+ Passed 1000 iterations
Running azero + a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running a + b == b + a
- Passed 100 iterations
+ Passed 1000 iterations
Group Multiplicative
Running a * 1 == a
- Passed 100 iterations
+ Passed 1000 iterations
Running 1 * a == a
- Passed 100 iterations
+ Passed 1000 iterations
Running multiplication commutative
- Passed 100 iterations
+ Passed 1000 iterations
Running a * b == Integer(a) * Integer(b)
- Passed 100 iterations
+ Passed 1000 iterations
Group Divisible
Running (x `div` y) * y + (x `mod` y) == x
- Passed 100 iterations
+ Passed 1000 iterations
Group Precedence
Running + and - (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and - (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running + and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running - and * (2)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (1)
- Passed 100 iterations
+ Passed 1000 iterations
Running * and ^ (2)
- Passed 100 iterations
+ Passed 1000 iterations
Group primop
Running gtChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running geChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running neChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running leChar#
- Passed 100 iterations
+ Passed 1000 iterations
Running ord#
- Passed 100 iterations
+ Passed 1000 iterations
Running int8ToInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running intToInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running negateInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running subInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running remInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRAInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running int8ToWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running geInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running leInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running neInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running word8ToWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running wordToWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running subWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running remWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running andWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running orWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running xorWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running notWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running word8ToInt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running geWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running leWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running neWord8#
- Passed 100 iterations
+ Passed 1000 iterations
Running int16ToInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running intToInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running negateInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running subInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running remInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRAInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running int16ToWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running geInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running leInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running neInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running word16ToWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running wordToWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running subWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running remWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running andWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running orWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running xorWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running notWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running word16ToInt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running geWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running leWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running neWord16#
- Passed 100 iterations
+ Passed 1000 iterations
Running int32ToInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running intToInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running negateInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running subInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running remInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRAInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running int32ToWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running geInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running leInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running neInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running word32ToWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running wordToWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running subWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running remWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running andWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running orWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running xorWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running notWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftLWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRLWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running word32ToInt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running geWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running leWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running neWord32#
- Passed 100 iterations
+ Passed 1000 iterations
Running int64ToInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running intToInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running negateInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running subInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running remInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftL64#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftRA64#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftRL64#
- Passed 100 iterations
+ Passed 1000 iterations
Running int64ToWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running geInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running leInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running neInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running word64ToWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running wordToWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running subWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running remWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running and64#
- Passed 100 iterations
+ Passed 1000 iterations
Running or64#
- Passed 100 iterations
+ Passed 1000 iterations
Running xor64#
- Passed 100 iterations
+ Passed 1000 iterations
Running not64#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftL64#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRL64#
- Passed 100 iterations
+ Passed 1000 iterations
Running word64ToInt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running geWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running leWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running neWord64#
- Passed 100 iterations
+ Passed 1000 iterations
Running +#
- Passed 100 iterations
+ Passed 1000 iterations
Running -#
- Passed 100 iterations
+ Passed 1000 iterations
Running *#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesInt2#
- Passed 100 iterations
+ Passed 1000 iterations
Running mulIntMayOflo#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running remInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running andI#
- Passed 100 iterations
+ Passed 1000 iterations
Running orI#
- Passed 100 iterations
+ Passed 1000 iterations
Running xorI#
- Passed 100 iterations
+ Passed 1000 iterations
Running notI#
- Passed 100 iterations
+ Passed 1000 iterations
Running negateInt#
- Passed 100 iterations
+ Passed 1000 iterations
Running addIntC#
- Passed 100 iterations
+ Passed 1000 iterations
Running subIntC#
- Passed 100 iterations
+ Passed 1000 iterations
Running >#
- Passed 100 iterations
+ Passed 1000 iterations
Running >=#
- Passed 100 iterations
+ Passed 1000 iterations
Running ==#
- Passed 100 iterations
+ Passed 1000 iterations
Running /=#
- Passed 100 iterations
+ Passed 1000 iterations
Running <#
- Passed 100 iterations
+ Passed 1000 iterations
Running <=#
- Passed 100 iterations
+ Passed 1000 iterations
Running chr#
- Passed 100 iterations
+ Passed 1000 iterations
Running int2Word#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftL#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftRA#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedIShiftRL#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running addWordC#
- Passed 100 iterations
+ Passed 1000 iterations
Running subWordC#
- Passed 100 iterations
+ Passed 1000 iterations
Running plusWord2#
- Passed 100 iterations
+ Passed 1000 iterations
Running minusWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running timesWord2#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running remWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running quotRemWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running and#
- Passed 100 iterations
+ Passed 1000 iterations
Running or#
- Passed 100 iterations
+ Passed 1000 iterations
Running xor#
- Passed 100 iterations
+ Passed 1000 iterations
Running not#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftL#
- Passed 100 iterations
+ Passed 1000 iterations
Running uncheckedShiftRL#
- Passed 100 iterations
+ Passed 1000 iterations
Running word2Int#
- Passed 100 iterations
+ Passed 1000 iterations
Running gtWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running geWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running eqWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running neWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running ltWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running leWord#
- Passed 100 iterations
+ Passed 1000 iterations
Running popCnt8#
- Passed 100 iterations
+ Passed 1000 iterations
Running popCnt16#
- Passed 100 iterations
+ Passed 1000 iterations
Running popCnt32#
- Passed 100 iterations
+ Passed 1000 iterations
Running popCnt64#
- Passed 100 iterations
+ Passed 1000 iterations
Running popCnt#
- Passed 100 iterations
+ Passed 1000 iterations
Running pdep8#
- Passed 100 iterations
+ Passed 1000 iterations
Running pdep16#
- Passed 100 iterations
+ Passed 1000 iterations
Running pdep32#
- Passed 100 iterations
+ Passed 1000 iterations
Running pdep64#
- Passed 100 iterations
+ Passed 1000 iterations
Running pdep#
- Passed 100 iterations
+ Passed 1000 iterations
Running pext8#
- Passed 100 iterations
+ Passed 1000 iterations
Running pext16#
- Passed 100 iterations
+ Passed 1000 iterations
Running pext32#
- Passed 100 iterations
+ Passed 1000 iterations
Running pext64#
- Passed 100 iterations
+ Passed 1000 iterations
Running pext#
- Passed 100 iterations
+ Passed 1000 iterations
Running clz8#
- Passed 100 iterations
+ Passed 1000 iterations
Running clz16#
- Passed 100 iterations
+ Passed 1000 iterations
Running clz32#
- Passed 100 iterations
+ Passed 1000 iterations
Running clz64#
- Passed 100 iterations
+ Passed 1000 iterations
Running clz#
- Passed 100 iterations
+ Passed 1000 iterations
Running ctz8#
- Passed 100 iterations
+ Passed 1000 iterations
Running ctz16#
- Passed 100 iterations
+ Passed 1000 iterations
Running ctz32#
- Passed 100 iterations
+ Passed 1000 iterations
Running ctz64#
- Passed 100 iterations
+ Passed 1000 iterations
Running ctz#
- Passed 100 iterations
+ Passed 1000 iterations
Running byteSwap16#
- Passed 100 iterations
+ Passed 1000 iterations
Running byteSwap32#
- Passed 100 iterations
+ Passed 1000 iterations
Running byteSwap64#
- Passed 100 iterations
+ Passed 1000 iterations
Running byteSwap#
- Passed 100 iterations
+ Passed 1000 iterations
Running bitReverse8#
- Passed 100 iterations
+ Passed 1000 iterations
Running bitReverse16#
- Passed 100 iterations
+ Passed 1000 iterations
Running bitReverse32#
- Passed 100 iterations
+ Passed 1000 iterations
Running bitReverse64#
- Passed 100 iterations
+ Passed 1000 iterations
Running bitReverse#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow8Int#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow16Int#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow32Int#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow8Word#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow16Word#
- Passed 100 iterations
+ Passed 1000 iterations
Running narrow32Word#
- Passed 100 iterations
+ Passed 1000 iterations
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd38b76cff47bcb27d737b15f8ad097…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd38b76cff47bcb27d737b15f8ad097…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: Removing the 'Data' instance for 'InstEnv'.
by Marge Bot (@marge-bot) 18 Dec '25
by Marge Bot (@marge-bot) 18 Dec '25
18 Dec '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
eac418bb by Recursion Ninja at 2025-12-18T13:19:48-05:00
Removing the 'Data' instance for 'InstEnv'.
The 'Data' instance is blocking work on Trees that Grow, and the
'Data' instance seem to have been added without a clear purpose.
- - - - -
e920e038 by Recursion Ninja at 2025-12-18T13:19:48-05:00
'Decouple Language.Haskell.Syntax.Decls' from 'GHC.Unit.Module.Warnings'
- - - - -
23 changed files:
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Warnings.hs
- compiler/GHC/Parser.y
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Utils.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Types/DefaultEnv.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- utils/check-exact/ExactPrint.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
Changes:
=====================================
compiler/GHC/Builtin/Utils.hs
=====================================
@@ -79,6 +79,7 @@ import GHC.Utils.Panic
import GHC.Utils.Constants (debugIsOn)
import GHC.Parser.Annotation
import GHC.Hs.Doc
+import GHC.Hs.Extension (GhcPass)
import GHC.Unit.Module.ModIface (IfaceExport)
import GHC.Unit.Module.Warnings
@@ -263,7 +264,7 @@ ghcPrimNames
]
-- See Note [GHC.Prim Deprecations]
-ghcPrimWarns :: Warnings a
+ghcPrimWarns :: Warnings (GhcPass p)
ghcPrimWarns = WarnSome
-- declaration warnings
(map mk_decl_dep primOpDeprecations)
=====================================
compiler/GHC/Core/InstEnv.hs
=====================================
@@ -7,7 +7,6 @@
The bits common to GHC.Tc.TyCl.Instance and GHC.Tc.Deriv.
-}
-
module GHC.Core.InstEnv (
DFunId, InstMatch, ClsInstLookupResult,
CanonicalEvidence(..), PotentialUnifiers(..), getCoherentUnifiers, nullUnifiers,
@@ -54,7 +53,6 @@ import GHC.Types.Name.Set
import GHC.Types.Basic
import GHC.Types.Id
import GHC.Generics (Generic)
-import Data.Data ( Data )
import Data.List.NonEmpty ( NonEmpty (..), nonEmpty )
import qualified Data.List.NonEmpty as NE
import Data.Maybe ( isJust )
@@ -113,7 +111,6 @@ data ClsInst
-- See Note [Implementation of deprecated instances]
-- in GHC.Tc.Solver.Dict
}
- deriving Data
-- | A fuzzy comparison function for class instances, intended for sorting
-- instances before displaying them to the user.
=====================================
compiler/GHC/Hs/Decls.hs
=====================================
@@ -1384,7 +1384,6 @@ type instance XWarning (GhcPass _) = (NamespaceSpecifier, (EpToken "[", EpT
type instance XXWarnDecl (GhcPass _) = DataConCantHappen
-
instance OutputableBndrId p
=> Outputable (WarnDecls (GhcPass p)) where
ppr (Warnings ext decls)
@@ -1404,7 +1403,7 @@ instance OutputableBndrId p
<+> ppr txt
where
ppr_category = case txt of
- WarningTxt (Just cat) _ _ -> ppr cat
+ WarningTxt _ (Just cat) _ -> ppr cat
_ -> empty
{-
=====================================
compiler/GHC/Hs/Instances.hs
=====================================
@@ -31,6 +31,7 @@ import GHC.Hs.ImpExp
import GHC.Parser.Annotation
import GHC.Types.Name.Reader (WithUserRdr(..))
import GHC.Data.BooleanFormula (BooleanFormula(..))
+import Language.Haskell.Syntax.Decls
import Language.Haskell.Syntax.Extension (Anno)
-- ---------------------------------------------------------------------
@@ -272,6 +273,14 @@ deriving instance Data (WarnDecl GhcPs)
deriving instance Data (WarnDecl GhcRn)
deriving instance Data (WarnDecl GhcTc)
+deriving instance Data (WarningTxt GhcPs)
+deriving instance Data (WarningTxt GhcRn)
+deriving instance Data (WarningTxt GhcTc)
+
+deriving instance Data (InWarningCategory GhcPs)
+deriving instance Data (InWarningCategory GhcRn)
+deriving instance Data (InWarningCategory GhcTc)
+
-- deriving instance (DataIdLR p p) => Data (AnnDecl p)
deriving instance Data (AnnProvenance GhcPs)
deriving instance Data (AnnProvenance GhcRn)
=====================================
compiler/GHC/Iface/Syntax.hs
=====================================
@@ -422,8 +422,8 @@ data IfaceWarnings
[(IfExtName, IfaceWarningTxt)]
data IfaceWarningTxt
- = IfWarningTxt (Maybe WarningCategory) SourceText [(IfaceStringLiteral, [IfExtName])]
- | IfDeprecatedTxt SourceText [(IfaceStringLiteral, [IfExtName])]
+ = IfWarningTxt SourceText (Maybe WarningCategory) [(IfaceStringLiteral, [IfExtName])]
+ | IfDeprecatedTxt SourceText [(IfaceStringLiteral, [IfExtName])]
data IfaceStringLiteral
= IfStringLiteral SourceText FastString
@@ -662,7 +662,7 @@ fromIfaceWarnings = \case
fromIfaceWarningTxt :: IfaceWarningTxt -> WarningTxt GhcRn
fromIfaceWarningTxt = \case
- IfWarningTxt mb_cat src strs -> WarningTxt (noLocA . fromWarningCategory <$> mb_cat) src (noLocA <$> map fromIfaceStringLiteralWithNames strs)
+ IfWarningTxt src mb_cat strs -> WarningTxt src (noLocA . fromWarningCategory <$> mb_cat) (noLocA <$> map fromIfaceStringLiteralWithNames strs)
IfDeprecatedTxt src strs -> DeprecatedTxt src (noLocA <$> map fromIfaceStringLiteralWithNames strs)
fromIfaceStringLiteralWithNames :: (IfaceStringLiteral, [IfExtName]) -> WithHsDocIdentifiers StringLiteral GhcRn
=====================================
compiler/GHC/Iface/Warnings.hs
=====================================
@@ -23,7 +23,7 @@ toIfaceWarnings (WarnSome vs ds) = IfWarnSome vs' ds'
ds' = [(occ, toIfaceWarningTxt txt) | (occ, txt) <- ds]
toIfaceWarningTxt :: WarningTxt GhcRn -> IfaceWarningTxt
-toIfaceWarningTxt (WarningTxt mb_cat src strs) = IfWarningTxt (unLoc . iwc_wc . unLoc <$> mb_cat) src (map (toIfaceStringLiteralWithNames . unLoc) strs)
+toIfaceWarningTxt (WarningTxt src mb_cat strs) = IfWarningTxt src (unLoc . iwc_wc . unLoc <$> mb_cat) (map (toIfaceStringLiteralWithNames . unLoc) strs)
toIfaceWarningTxt (DeprecatedTxt src strs) = IfDeprecatedTxt src (map (toIfaceStringLiteralWithNames . unLoc) strs)
toIfaceStringLiteralWithNames :: WithHsDocIdentifiers StringLiteral GhcRn -> (IfaceStringLiteral, [IfExtName])
=====================================
compiler/GHC/Parser.y
=====================================
@@ -2047,12 +2047,12 @@ maybe_warning_pragma :: { Maybe (LWarningTxt GhcPs) }
{% fmap Just $ amsr (sLL $1 $> $ DeprecatedTxt (getDEPRECATED_PRAGs $1) (map stringLiteralToHsDocWst $ snd $ unLoc $2))
(AnnPragma (glR $1) (epTok $3) (fst $ unLoc $2) noAnn noAnn noAnn noAnn) }
| '{-# WARNING' warning_category strings '#-}'
- {% fmap Just $ amsr (sLL $1 $> $ WarningTxt $2 (getWARNING_PRAGs $1) (map stringLiteralToHsDocWst $ snd $ unLoc $3))
+ {% fmap Just $ amsr (sLL $1 $> $ WarningTxt (getWARNING_PRAGs $1) $2 (map stringLiteralToHsDocWst $ snd $ unLoc $3))
(AnnPragma (glR $1) (epTok $4) (fst $ unLoc $3) noAnn noAnn noAnn noAnn)}
| {- empty -} { Nothing }
-warning_category :: { Maybe (LocatedE InWarningCategory) }
- : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1) (getSTRINGs $2)
+warning_category :: { Maybe (LocatedE (InWarningCategory GhcPs)) }
+ : 'in' STRING { Just (reLoc $ sLL $1 $> $ InWarningCategory (epTok $1, getSTRINGs $2)
(reLoc $ sL1 $2 $ mkWarningCategory (getSTRING $2))) }
| {- empty -} { Nothing }
@@ -2077,7 +2077,7 @@ warning :: { OrdList (LWarnDecl GhcPs) }
: warning_category namespace_spec namelist strings
{% fmap unitOL $ amsA' (L (comb4 $1 $2 $3 $4)
(Warning (unLoc $2, fst $ unLoc $4) (unLoc $3)
- (WarningTxt $1 NoSourceText $ map stringLiteralToHsDocWst $ snd $ unLoc $4))) }
+ (WarningTxt NoSourceText $1 (map stringLiteralToHsDocWst $ snd $ unLoc $4)))) }
namespace_spec :: { Located NamespaceSpecifier }
: 'type' { sL1 $1 $ TypeNamespaceSpecifier (epTok $1) }
=====================================
compiler/GHC/Rename/Module.hs
=====================================
@@ -314,12 +314,16 @@ rnSrcWarnDecls bndr_set decls'
rdrNameOcc (unLoc x) == rdrNameOcc (unLoc y))
rnWarningTxt :: WarningTxt GhcPs -> RnM (WarningTxt GhcRn)
-rnWarningTxt (WarningTxt mb_cat st wst) = do
- forM_ mb_cat $ \(L _ (InWarningCategory _ _ (L loc cat))) ->
- unless (validWarningCategory cat) $
- addErrAt (locA loc) (TcRnInvalidWarningCategory cat)
+rnWarningTxt (WarningTxt st mb_cat wst) = do
+ mb_cat' <- case mb_cat of
+ Nothing -> pure Nothing
+ Just (L x (InWarningCategory y (L loc cat))) -> do
+ unless (validWarningCategory cat) $
+ addErrAt (locA loc) (TcRnInvalidWarningCategory cat)
+ pure . Just $ L x (InWarningCategory y (L loc cat))
wst' <- traverse (traverse rnHsDoc) wst
- pure (WarningTxt mb_cat st wst')
+ pure (WarningTxt st mb_cat' wst')
+
rnWarningTxt (DeprecatedTxt st wst) = do
wst' <- traverse (traverse rnHsDoc) wst
pure (DeprecatedTxt st wst')
=====================================
compiler/GHC/Rename/Utils.hs
=====================================
@@ -66,7 +66,6 @@ import GHC.Data.Bag ( mapBagM, headMaybe )
import Control.Monad
import GHC.Settings.Constants ( mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE )
import GHC.Unit.Module
-import GHC.Unit.Module.Warnings ( WarningTxt(..) )
import GHC.Iface.Load
import qualified GHC.LanguageExtensions as LangExt
=====================================
compiler/GHC/Tc/Deriv.hs
=====================================
@@ -56,7 +56,6 @@ import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.SrcLoc
-import GHC.Unit.Module.Warnings
import GHC.Builtin.Names
import GHC.Utils.Error
=====================================
compiler/GHC/Tc/Deriv/Utils.hs
=====================================
@@ -52,7 +52,6 @@ import GHC.Core.Type
import GHC.Hs
import GHC.Driver.Session
import GHC.Unit.Module (getModule)
-import GHC.Unit.Module.Warnings
import GHC.Unit.Module.ModIface (mi_fix)
import GHC.Iface.Load (loadInterfaceForName)
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -1835,7 +1835,7 @@ instance Diagnostic TcRnMessage where
nest 2 (vcat (map (ppr . hsDocString . unLoc) msg)) ]
where
(extra, msg) = case txt of
- WarningTxt _ _ msg -> ("", msg)
+ WarningTxt _ _ msg -> ("", msg)
DeprecatedTxt _ msg -> (" is deprecated", msg)
TcRnRedundantSourceImport mod_name
-> mkSimpleDecorated $
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -213,7 +213,6 @@ import GHC.Types.DefaultEnv (ClassDefaults)
import GHC.Unit.Types (Module)
import GHC.Unit.State (UnitState)
-import GHC.Unit.Module.Warnings (WarningCategory, WarningTxt)
import GHC.Unit.Module.ModIface (ModIface)
import GHC.Utils.Outputable
=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -60,7 +60,6 @@ import GHC.Core.PatSyn
import GHC.Core.Multiplicity ( scaledThing )
import GHC.Unit.Module
-import GHC.Unit.Module.Warnings
import GHC.Types.Id
import GHC.Types.Name
import GHC.Types.Name.Reader
=====================================
compiler/GHC/Tc/Utils/Instantiate.hs
=====================================
@@ -89,7 +89,6 @@ import GHC.Utils.Unique (sameUnique)
import GHC.Unit.State
import GHC.Unit.External
-import GHC.Unit.Module.Warnings
import Data.List ( mapAccumL )
import qualified Data.List.NonEmpty as NE
=====================================
compiler/GHC/Types/DefaultEnv.hs
=====================================
@@ -18,13 +18,12 @@ where
import GHC.Core.Class (Class (className))
import GHC.Prelude
-import GHC.Hs.Extension (GhcRn)
+import GHC.Hs
import GHC.Tc.Utils.TcType (Type)
import GHC.Types.Name (Name, nameUnique, stableNameCmp)
import GHC.Types.Name.Env
import GHC.Types.Unique.FM (lookupUFM_Directly)
import GHC.Types.SrcLoc (SrcSpan)
-import GHC.Unit.Module.Warnings (WarningTxt)
import GHC.Unit.Types (Module)
import GHC.Utils.Outputable
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -761,6 +761,7 @@ type family GhcDiagnosticCode c = n | n -> c where
-- TcRnPragmaWarning
GhcDiagnosticCode "WarningTxt" = 63394
GhcDiagnosticCode "DeprecatedTxt" = 68441
+ GhcDiagnosticCode "XWarningTxt" = 68077
-- TcRnRunSliceFailure/ConversionFail
GhcDiagnosticCode "IllegalOccName" = 55017
=====================================
compiler/GHC/Unit/Module/Warnings.hs
=====================================
@@ -1,6 +1,9 @@
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}
+-- Eq instances for WarningTxt, InWarningCategory
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
-- | Warnings for a module
module GHC.Unit.Module.Warnings
( WarningCategory(..)
@@ -38,7 +41,7 @@ where
import GHC.Prelude
-import GHC.Data.FastString (FastString, mkFastString, unpackFS)
+import GHC.Data.FastString (mkFastString, unpackFS)
import GHC.Types.SourceText
import GHC.Types.Name.Occurrence
import GHC.Types.Name.Env
@@ -55,77 +58,15 @@ import GHC.Utils.Binary
import GHC.Unicode
import Language.Haskell.Syntax.Extension
+import Language.Haskell.Syntax.Decls
-import Data.Data
import Data.List (isPrefixOf)
-import GHC.Generics ( Generic )
-import Control.DeepSeq
-
-
-{-
-Note [Warning categories]
-~~~~~~~~~~~~~~~~~~~~~~~~~
-See GHC Proposal 541 for the design of the warning categories feature:
-https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0541-warning-pragmas-with-categories.rst
-
-A WARNING pragma may be annotated with a category such as "x-partial" written
-after the 'in' keyword, like this:
-
- {-# WARNING in "x-partial" head "This function is partial..." #-}
-
-This is represented by the 'Maybe (Located WarningCategory)' field in
-'WarningTxt'. The parser will accept an arbitrary string as the category name,
-then the renamer (in 'rnWarningTxt') will check it contains only valid
-characters, so we can generate a nicer error message than a parse error.
-
-The corresponding warnings can then be controlled with the -Wx-partial,
--Wno-x-partial, -Werror=x-partial and -Wwarn=x-partial flags. Such a flag is
-distinguished from an 'unrecognisedWarning' by the flag parser testing
-'validWarningCategory'. The 'x-' prefix means we can still usually report an
-unrecognised warning where the user has made a mistake.
-
-A DEPRECATED pragma may not have a user-defined category, and is always treated
-as belonging to the special category 'deprecations'. Similarly, a WARNING
-pragma without a category belongs to the 'deprecations' category.
-Thus the '-Wdeprecations' flag will enable all of the following:
-
- {-# WARNING in "deprecations" foo "This function is deprecated..." #-}
- {-# WARNING foo "This function is deprecated..." #-}
- {-# DEPRECATED foo "This function is deprecated..." #-}
-
-The '-Wwarnings-deprecations' flag is supported for backwards compatibility
-purposes as being equivalent to '-Wdeprecations'.
-
-The '-Wextended-warnings' warning group collects together all warnings with
-user-defined categories, so they can be enabled or disabled
-collectively. Moreover they are treated as being part of other warning groups
-such as '-Wdefault' (see 'warningGroupIncludesExtendedWarnings').
-
-'DynFlags' and 'DiagOpts' each contain a set of enabled and a set of fatal
-warning categories, just as they do for the finite enumeration of 'WarningFlag's
-built in to GHC. These are represented as 'WarningCategorySet's to allow for
-the possibility of them being infinite.
-
--}
-data InWarningCategory
- = InWarningCategory
- { iwc_in :: !(EpToken "in"),
- iwc_st :: !SourceText,
- iwc_wc :: (LocatedE WarningCategory)
- } deriving Data
-fromWarningCategory :: WarningCategory -> InWarningCategory
-fromWarningCategory wc = InWarningCategory noAnn NoSourceText (noLocA wc)
-
-
--- See Note [Warning categories]
-newtype WarningCategory = WarningCategory FastString
- deriving stock Data
- deriving newtype (Binary, Eq, Outputable, Show, Uniquable, NFData)
-
-mkWarningCategory :: FastString -> WarningCategory
-mkWarningCategory = WarningCategory
+fromWarningCategory ::
+ HasAnnotation (Anno WarningCategory) =>
+ WarningCategory -> InWarningCategory (GhcPass p)
+fromWarningCategory wc = InWarningCategory (noAnn, NoSourceText) (noLocA wc)
-- | The @deprecations@ category is used for all DEPRECATED pragmas and for
-- WARNING pragmas that do not specify a category.
@@ -143,7 +84,6 @@ validWarningCategory cat@(WarningCategory c) =
s = unpackFS c
is_allowed c = isAlphaNum c || c == '\'' || c == '-'
-
-- | A finite or infinite set of warning categories.
--
-- Unlike 'WarningFlag', there are (in principle) infinitely many warning
@@ -188,66 +128,74 @@ deleteWarningCategorySet c (CofiniteWarningCategorySet s) = CofiniteWarningCateg
type LWarningTxt pass = XRec pass (WarningTxt pass)
--- | Warning Text
---
--- reason/explanation from a WARNING or DEPRECATED pragma
-data WarningTxt pass
- = WarningTxt
- (Maybe (LocatedE InWarningCategory))
- -- ^ Warning category attached to this WARNING pragma, if any;
- -- see Note [Warning categories]
- SourceText
- [LocatedE (WithHsDocIdentifiers StringLiteral pass)]
- | DeprecatedTxt
- SourceText
- [LocatedE (WithHsDocIdentifiers StringLiteral pass)]
- deriving Generic
-
-- | To which warning category does this WARNING or DEPRECATED pragma belong?
-- See Note [Warning categories].
-warningTxtCategory :: WarningTxt pass -> WarningCategory
-warningTxtCategory (WarningTxt (Just (L _ (InWarningCategory _ _ (L _ cat)))) _ _) = cat
+warningTxtCategory :: WarningTxt (GhcPass p) -> WarningCategory
+warningTxtCategory (WarningTxt _ (Just (L _ (InWarningCategory _ (L _ cat)))) _) = cat
warningTxtCategory _ = defaultWarningCategory
+
-- | The message that the WarningTxt was specified to output
-warningTxtMessage :: WarningTxt p -> [LocatedE (WithHsDocIdentifiers StringLiteral p)]
-warningTxtMessage (WarningTxt _ _ m) = m
+warningTxtMessage :: WarningTxt (GhcPass p) -> [LocatedE (WithHsDocIdentifiers StringLiteral (GhcPass p))]
+warningTxtMessage (WarningTxt _ _ m) = m
warningTxtMessage (DeprecatedTxt _ m) = m
-- | True if the 2 WarningTxts have the same category and messages
-warningTxtSame :: WarningTxt p1 -> WarningTxt p2 -> Bool
+warningTxtSame :: WarningTxt (GhcPass p) -> WarningTxt (GhcPass p) -> Bool
warningTxtSame w1 w2
= warningTxtCategory w1 == warningTxtCategory w2
&& literal_message w1 == literal_message w2
&& same_type
where
- literal_message :: WarningTxt p -> [StringLiteral]
+ literal_message :: WarningTxt (GhcPass p) -> [StringLiteral]
literal_message = map (hsDocString . unLoc) . warningTxtMessage
same_type | DeprecatedTxt {} <- w1, DeprecatedTxt {} <- w2 = True
- | WarningTxt {} <- w1, WarningTxt {} <- w2 = True
+ | WarningTxt {} <- w1, WarningTxt {} <- w2 = True
| otherwise = False
-deriving instance Eq InWarningCategory
+instance Outputable (InWarningCategory (GhcPass pass)) where
+ ppr (InWarningCategory _ wt) = text "in" <+> doubleQuotes (ppr wt)
-deriving instance (Eq (IdP pass)) => Eq (WarningTxt pass)
-deriving instance (Data pass, Data (IdP pass)) => Data (WarningTxt pass)
+type instance XDeprecatedTxt (GhcPass _) = SourceText
+type instance XWarningTxt (GhcPass _) = SourceText
+type instance XXWarningTxt (GhcPass _) = DataConCantHappen
+type instance XInWarningCategory (GhcPass _) = (EpToken "in", SourceText)
+type instance XXInWarningCategory (GhcPass _) = DataConCantHappen
+type instance Anno (WithHsDocIdentifiers StringLiteral pass) = EpaLocation
+type instance Anno (InWarningCategory (GhcPass pass)) = EpaLocation
+type instance Anno (WarningCategory) = EpaLocation
type instance Anno (WarningTxt (GhcPass pass)) = SrcSpanAnnP
-instance Outputable InWarningCategory where
- ppr (InWarningCategory _ _ wt) = text "in" <+> doubleQuotes (ppr wt)
+deriving stock instance Eq (WarningTxt GhcPs)
+deriving stock instance Eq (WarningTxt GhcRn)
+deriving stock instance Eq (WarningTxt GhcTc)
+
+deriving stock instance Eq (InWarningCategory GhcPs)
+deriving stock instance Eq (InWarningCategory GhcRn)
+deriving stock instance Eq (InWarningCategory GhcTc)
+
+-- TODO: Move to respecitive type-class definition modules after removing
+-- the Language.Haskell.Syntax.Decls module's dependency on GHC.Hs.Doc.
+-- Subsequently, create a Language.Haskell.Syntax.Decls.Warnings sub-module
+-- with the "warning declaration" types and have Language.Haskell.Syntax.Decls
+-- re-export Language.Haskell.Syntax.Decls.Warnings. This will prevent cyclic
+-- import, but it will only work once GHC.Hs.Doc is no longer a GHC dependency.
+deriving instance Binary WarningCategory
+deriving instance Outputable WarningCategory
-instance Outputable (WarningTxt pass) where
- ppr (WarningTxt mcat lsrc ws)
+deriving instance Uniquable WarningCategory
+
+instance Outputable (WarningTxt (GhcPass pass)) where
+ ppr (WarningTxt lsrc mcat ws)
= case lsrc of
NoSourceText -> pp_ws ws
SourceText src -> ftext src <+> ctg_doc <+> pp_ws ws <+> text "#-}"
where
ctg_doc = maybe empty (\ctg -> ppr ctg) mcat
-
- ppr (DeprecatedTxt lsrc ds)
+ ppr (DeprecatedTxt lsrc ds)
= case lsrc of
NoSourceText -> pp_ws ds
SourceText src -> ftext src <+> pp_ws ds <+> text "#-}"
@@ -260,7 +208,7 @@ pp_ws ws
<+> text "]"
-pprWarningTxtForMsg :: WarningTxt p -> SDoc
+pprWarningTxtForMsg :: WarningTxt (GhcPass pass) -> SDoc
pprWarningTxtForMsg (WarningTxt _ _ ws)
= doubleQuotes (vcat (map (ftext . sl_fs . hsDocString . unLoc) ws))
pprWarningTxtForMsg (DeprecatedTxt _ ds)
@@ -306,8 +254,6 @@ type DeclWarnOccNames pass = [(OccName, WarningTxt pass)]
-- | Names that are deprecated as exports
type ExportWarnNames pass = [(Name, WarningTxt pass)]
-deriving instance Eq (IdP pass) => Eq (Warnings pass)
-
emptyWarn :: Warnings p
emptyWarn = WarnSome [] []
=====================================
compiler/Language/Haskell/Syntax/Decls.hs
=====================================
@@ -72,7 +72,18 @@ module Language.Haskell.Syntax.Decls (
FamilyResultSig(..), LFamilyResultSig, InjectivityAnn(..), LInjectivityAnn,
-- * Grouping
- HsGroup(..)
+ HsGroup(..),
+
+ -- * Warnings
+ WarningTxt(..),
+ WarningCategory(..),
+ mkWarningCategory,
+ InWarningCategory(..),
+ -- ** Extension
+ XDeprecatedTxt,
+ XWarningTxt,
+ XXWarningTxt,
+ XInWarningCategory,
) where
-- friends:
@@ -90,12 +101,14 @@ import GHC.Types.Basic (TopLevelFlag, OverlapMode, RuleName, Activation
,TyConFlavour(..), TypeOrData(..), NewOrData(..))
import GHC.Types.ForeignCall (CType, CCallConv, Safety, Header, CLabelString, CCallTarget, CExportSpec)
-import GHC.Unit.Module.Warnings (WarningTxt)
-
+import GHC.Data.FastString (FastString)
import GHC.Hs.Doc (LHsDoc) -- ROMES:TODO Discuss in #21592 whether this is parsed AST or base AST
+import GHC.Hs.Doc (WithHsDocIdentifiers)
+import GHC.Types.SourceText (StringLiteral)
-import Control.Monad
+import Control.DeepSeq
import Control.Exception (assert)
+import Control.Monad
import Data.Data hiding (TyCon, Fixity, Infix)
import Data.Maybe
import Data.String
@@ -106,6 +119,8 @@ import Prelude (Show)
import Data.Foldable
import Data.Traversable
import Data.List.NonEmpty (NonEmpty (..))
+import GHC.Generics ( Generic )
+
{-
************************************************************************
@@ -1578,3 +1593,85 @@ data RoleAnnotDecl pass
(LIdP pass) -- type constructor
[XRec pass (Maybe Role)] -- optional annotations
| XRoleAnnotDecl !(XXRoleAnnotDecl pass)
+
+{-
+************************************************************************
+* *
+\subsection[WarnAnnot]{Warning annotations}
+* *
+************************************************************************
+-}
+
+-- | Warning Text
+--
+-- reason/explanation from a WARNING or DEPRECATED pragma
+data WarningTxt pass
+ = DeprecatedTxt
+ (XDeprecatedTxt pass)
+ [XRec pass (WithHsDocIdentifiers StringLiteral pass)]
+ | WarningTxt
+ (XWarningTxt pass)
+ (Maybe (XRec pass (InWarningCategory pass)))
+ -- ^ Warning category attached to this WARNING pragma, if any;
+ -- see Note [Warning categories]
+ [XRec pass (WithHsDocIdentifiers StringLiteral pass)]
+ | XWarningTxt !(XXWarningTxt pass)
+ deriving Generic
+
+{-
+Note [Warning categories]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+See GHC Proposal 541 for the design of the warning categories feature:
+https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0541-warning-pragmas-with-categories.rst
+
+A WARNING pragma may be annotated with a category such as "x-partial" written
+after the 'in' keyword, like this:
+
+ {-# WARNING in "x-partial" head "This function is partial..." #-}
+
+This is represented by the 'Maybe (Located WarningCategory)' field in
+'WarningTxt'. The parser will accept an arbitrary string as the category name,
+then the renamer (in 'rnWarningTxt') will check it contains only valid
+characters, so we can generate a nicer error message than a parse error.
+
+The corresponding warnings can then be controlled with the -Wx-partial,
+-Wno-x-partial, -Werror=x-partial and -Wwarn=x-partial flags. Such a flag is
+distinguished from an 'unrecognisedWarning' by the flag parser testing
+'validWarningCategory'. The 'x-' prefix means we can still usually report an
+unrecognised warning where the user has made a mistake.
+
+A DEPRECATED pragma may not have a user-defined category, and is always treated
+as belonging to the special category 'deprecations'. Similarly, a WARNING
+pragma without a category belongs to the 'deprecations' category.
+Thus the '-Wdeprecations' flag will enable all of the following:
+
+ {-# WARNING in "deprecations" foo "This function is deprecated..." #-}
+ {-# WARNING foo "This function is deprecated..." #-}
+ {-# DEPRECATED foo "This function is deprecated..." #-}
+The '-Wwarnings-deprecations' flag is supported for backwards compatibility
+purposes as being equivalent to '-Wdeprecations'.
+
+The '-Wextended-warnings' warning group collects together all warnings with
+user-defined categories, so they can be enabled or disabled
+collectively. Moreover they are treated as being part of other warning groups
+such as '-Wdefault' (see 'warningGroupIncludesExtendedWarnings').
+
+'DynFlags' and 'DiagOpts' each contain a set of enabled and a set of fatal
+warning categories, just as they do for the finite enumeration of 'WarningFlag's
+built in to GHC. These are represented as 'WarningCategorySet's to allow for
+the possibility of them being infinite.
+
+-}
+data InWarningCategory pass
+ = InWarningCategory
+ { iwc_st :: (XInWarningCategory pass),
+ iwc_wc :: (XRec pass WarningCategory)
+ }
+ | XInWarningCategory !(XXInWarningCategory pass)
+
+newtype WarningCategory = WarningCategory FastString
+ deriving stock (Data)
+ deriving newtype (Eq, Show, NFData)
+
+mkWarningCategory :: FastString -> WarningCategory
+mkWarningCategory = WarningCategory
=====================================
compiler/Language/Haskell/Syntax/Extension.hs
=====================================
@@ -410,6 +410,17 @@ type family XXWarnDecls x
type family XWarning x
type family XXWarnDecl x
+-- -------------------------------------
+-- WarningTxt type families
+type family XDeprecatedTxt x
+type family XWarningTxt x
+type family XXWarningTxt x
+
+-- -------------------------------------
+-- InWarningCategory type families
+type family XInWarningCategory x
+type family XXInWarningCategory x
+
-- -------------------------------------
-- AnnDecl type families
type family XHsAnnotation x
=====================================
testsuite/tests/diagnostic-codes/codes.stdout
=====================================
@@ -70,6 +70,7 @@
[GHC-99991] is untested (constructor = TyVarMissingInEnv)
[GHC-92834] is untested (constructor = BadCoercionRole)
[GHC-93008] is untested (constructor = HsigShapeSortMismatch)
+[GHC-68077] is untested (constructor = XWarningTxt)
[GHC-68444] is untested (constructor = SumAltArityExceeded)
[GHC-63966] is untested (constructor = IllegalSumAlt)
[GHC-28709] is untested (constructor = MalformedType)
=====================================
utils/check-exact/ExactPrint.hs
=====================================
@@ -53,7 +53,6 @@ import GHC.Types.PkgQual
import GHC.Types.SourceText
import GHC.Types.SrcLoc
import GHC.Types.Var
-import GHC.Unit.Module.Warnings
import GHC.Utils.Misc
import GHC.Utils.Outputable hiding ( (<>) )
import GHC.Utils.Panic
@@ -1570,14 +1569,14 @@ instance ExactPrint (LocatedP (WarningTxt GhcPs)) where
getAnnotationEntry = entryFromLocatedA
setAnnotationAnchor = setAnchorAn
- exact (L (EpAnn l (AnnPragma o c (os,cs) l1 l2 t m) css) (WarningTxt mb_cat src ws)) = do
+ exact (L (EpAnn l (AnnPragma o c (os,cs) l1 l2 t m) css) (WarningTxt src mb_cat ws)) = do
o' <- markAnnOpen'' o src "{-# WARNING"
mb_cat' <- markAnnotated mb_cat
os' <- markEpToken os
ws' <- markAnnotated ws
cs' <- markEpToken cs
c' <- markEpToken c
- return (L (EpAnn l (AnnPragma o' c' (os',cs') l1 l2 t m) css) (WarningTxt mb_cat' src ws'))
+ return (L (EpAnn l (AnnPragma o' c' (os',cs') l1 l2 t m) css) (WarningTxt src mb_cat' ws'))
exact (L (EpAnn l (AnnPragma o c (os,cs) l1 l2 t m) css) (DeprecatedTxt src ws)) = do
o' <- markAnnOpen'' o src "{-# DEPRECATED"
@@ -1587,14 +1586,14 @@ instance ExactPrint (LocatedP (WarningTxt GhcPs)) where
c' <- markEpToken c
return (L (EpAnn l (AnnPragma o' c' (os',cs') l1 l2 t m) css) (DeprecatedTxt src ws'))
-instance ExactPrint InWarningCategory where
+instance Typeable p => ExactPrint (InWarningCategory (GhcPass p)) where
getAnnotationEntry _ = NoEntryVal
setAnnotationAnchor a _ _ _ = a
- exact (InWarningCategory tkIn source (L l wc)) = do
+ exact (InWarningCategory (tkIn, source) (L l wc)) = do
tkIn' <- markEpToken tkIn
L l' (_,wc') <- markAnnotated (L l (source, wc))
- return (InWarningCategory tkIn' source (L l' wc'))
+ return (InWarningCategory (tkIn', source) (L l' wc'))
instance ExactPrint (SourceText, WarningCategory) where
getAnnotationEntry _ = NoEntryVal
@@ -1935,14 +1934,14 @@ instance ExactPrint (WarnDecl GhcPs) where
getAnnotationEntry _ = NoEntryVal
setAnnotationAnchor a _ _ _ = a
- exact (Warning (ns_spec, (o,c)) lns (WarningTxt mb_cat src ls )) = do
+ exact (Warning (ns_spec, (o,c)) lns (WarningTxt src mb_cat ls )) = do
mb_cat' <- markAnnotated mb_cat
ns_spec' <- exactNsSpec ns_spec
lns' <- markAnnotated lns
o' <- markEpToken o
ls' <- markAnnotated ls
c' <- markEpToken c
- return (Warning (ns_spec', (o',c')) lns' (WarningTxt mb_cat' src ls'))
+ return (Warning (ns_spec', (o',c')) lns' (WarningTxt src mb_cat' ls'))
exact (Warning (ns_spec, (o,c)) lns (DeprecatedTxt src ls)) = do
ns_spec' <- exactNsSpec ns_spec
=====================================
utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
=====================================
@@ -354,7 +354,7 @@ parseWarning
-> IfM m (Doc Name)
parseWarning parserOpts sDocContext w = case w of
IfDeprecatedTxt _ msg -> format "Deprecated: " (map dstToDoc msg)
- IfWarningTxt _ _ msg -> format "Warning: " (map dstToDoc msg)
+ IfWarningTxt _ _ msg -> format "Warning: " (map dstToDoc msg)
where
dstToDoc :: (IfaceStringLiteral, [Name]) -> HsDoc GhcRn
dstToDoc ((IfStringLiteral _ fs), ids) = WithHsDocIdentifiers (fsToDoc fs) (map noLoc ids)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47d83d960e334ceed4ac59c7ebd1db…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47d83d960e334ceed4ac59c7ebd1db…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: Parser: improve mkModuleImpExp, remove checkImportSpec
by Marge Bot (@marge-bot) 18 Dec '25
by Marge Bot (@marge-bot) 18 Dec '25
18 Dec '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
951402ed by Vladislav Zavialov at 2025-12-18T13:19:05-05:00
Parser: improve mkModuleImpExp, remove checkImportSpec
1. The `mkModuleImpExp` helper now knows whether it is processing an import or
export list item, and uses this information to produce a more accurate error
message for `import M (T(..,x))` with PatternSynonyms disabled.
The old message incorrectly referred to this case as an export form.
2. The `checkImportSpec` helper is removed in favor of more comprehensive error
checking in `mkModuleImpExp`.
3. Additionaly, the invariants of `ImpExpList` and `ImpExpAllWith` have been
made more explicit in the comments and assertions (calls to 'panic').
Test case: import-syntax-no-ext
- - - - -
47d83d96 by Vladislav Zavialov at 2025-12-18T13:19:06-05:00
Subordinate namespace-specified wildcards (#25901)
Add support for subordinate namespace-specified wildcards
`X(type ..)` and `X(data ..)` to import and export lists.
Examples:
import M (Cls(type ..)) -- imports Cls and all its associated types
import M (Cls(data ..)) -- imports Cls and all its methods
module M (R(data ..), C(type ..)) where
-- exports R and all its data constructors and record fields;
-- exports C and all its associated types, but not its methods
The scope of this change is limited to the case where the wildcard is the only
subordinate import/export item, whereas the more complex forms `X(type .., f)`
or `X(type .., data ..)` are unsupported and raise the newly introduced
PsErrUnsupportedExplicitNamespace error. This restriction may be lifted later.
Summary of the changes:
1. Refactor IEThingAll to store its extension field XIEThingAll as a record
IEThingAllExt instead of a tuple.
2. Extend the AST by adding a NamespaceSpecifier field to IEThingAllExt,
representing an optional namespace specifier `type` or `data` in front
of a subordinate wildcard `X(..)`.
3. Extend the grammar in Parser.y with productions for `type ..` and `data ..`
in subordinate import/export items.
4. Introduce `filterByNamespaceGREs` to filter [GlobalRdrElt] by a
NamespaceSpecifier; use it in `filterImports` and `exports_from_avail`
to account for the namespace specifier in IEThingAll.
5. Improve diagnostics by storing more information in DodgyImportsEmptyParent
and DodgyExportsEmptyParent.
Test cases:
T25901_sub_e T25901_sub_f T25901_sub_g T25901_sub_a
T25901_sub_b T25901_sub_c T25901_sub_d T25901_sub_w
DodgyImports02 DodgyImports03 DodgyImports04
- - - - -
50 changed files:
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/PostProcess.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/Codes.hs
- compiler/GHC/Types/Name/Reader.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/patsyn/should_fail/all.T
- + testsuite/tests/patsyn/should_fail/import-syntax-no-ext.hs
- + testsuite/tests/patsyn/should_fail/import-syntax-no-ext.stderr
- + testsuite/tests/rename/should_compile/T25901_sub_e.hs
- + testsuite/tests/rename/should_compile/T25901_sub_f.hs
- + testsuite/tests/rename/should_compile/T25901_sub_f.stderr
- + testsuite/tests/rename/should_compile/T25901_sub_g.hs
- + testsuite/tests/rename/should_compile/T25901_sub_g.stderr
- + testsuite/tests/rename/should_compile/T25901_sub_g_helper.hs
- testsuite/tests/rename/should_compile/all.T
- testsuite/tests/rename/should_fail/T23570b.stderr
- + testsuite/tests/rename/should_fail/T25901_sub_a.hs
- + testsuite/tests/rename/should_fail/T25901_sub_a.stderr
- + testsuite/tests/rename/should_fail/T25901_sub_b.hs
- + testsuite/tests/rename/should_fail/T25901_sub_b.stderr
- + testsuite/tests/rename/should_fail/T25901_sub_c.hs
- + testsuite/tests/rename/should_fail/T25901_sub_c.stderr
- + testsuite/tests/rename/should_fail/T25901_sub_c_helper.hs
- + testsuite/tests/rename/should_fail/T25901_sub_d.hs
- + testsuite/tests/rename/should_fail/T25901_sub_d.stderr
- + testsuite/tests/rename/should_fail/T25901_sub_d_helper.hs
- + testsuite/tests/rename/should_fail/T25901_sub_w.hs
- + testsuite/tests/rename/should_fail/T25901_sub_w.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/warnings/should_compile/DodgyExports03.stderr
- testsuite/tests/warnings/should_compile/DodgyImports.stderr
- + testsuite/tests/warnings/should_compile/DodgyImports02.hs
- + testsuite/tests/warnings/should_compile/DodgyImports02.stderr
- + testsuite/tests/warnings/should_compile/DodgyImports03.hs
- + testsuite/tests/warnings/should_compile/DodgyImports03.stderr
- + testsuite/tests/warnings/should_compile/DodgyImports03_helper.hs
- + testsuite/tests/warnings/should_compile/DodgyImports04.hs
- + testsuite/tests/warnings/should_compile/DodgyImports04.stderr
- testsuite/tests/warnings/should_compile/DodgyImports_hiding.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55ab583b40ecdc1abc3307cea1d6a2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55ab583b40ecdc1abc3307cea1d6a2…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 5 commits: X86 CodeGen: fix assign_eax_sse_regs
by Marge Bot (@marge-bot) 18 Dec '25
by Marge Bot (@marge-bot) 18 Dec '25
18 Dec '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
fca9cd7c by sheaf at 2025-12-18T13:18:18-05:00
X86 CodeGen: fix assign_eax_sse_regs
We must set %al to the number of SSE2 registers that contain arguments
(in case we are dealing with a varargs function). The logic for counting
how many arguments reside in SSE2 registers was incorrect, as it used
'isFloatFormat', which incorrectly ignores vector registers.
We now instead do case analysis on the register class:
is_sse_reg r =
case targetClassOfReg platform r of
RcFloatOrVector -> True
RcInteger -> False
This change is necessary to prevent segfaults in T20030_test1j, because
subsequent commits change the format calculations, resulting in vector
formats more often.
- - - - -
53150617 by sheaf at 2025-12-18T13:18:19-05:00
X86 regUsageOfInstr: fix format for IMUL
When used with 8-bit operands, the IMUL instruction returns the result
in the lower 16 bits of %rax (also known as %ax). This is different
than for the other sizes, where an input at 16, 32 or 64 bits will
result in 16, 32 or 64 bits of output in both %rax and %rdx.
This doesn't affect the behaviour of the compiler, because we don't
allow partial writes at sub-word sizes. The rationale is explained
in Wrinkle [Don't allow scalar partial writes] in Note [Register formats in liveness analysis],
in GHC.CmmToAsm.Reg.Liveness.
- - - - -
c7a56dd1 by sheaf at 2025-12-18T13:18:19-05:00
Liveness analysis: consider register formats
This commit updates the register allocator to be a bit more careful in
situations in which a single register is used at multiple different
formats, e.g. when xmm1 is used both to store a Double# and a DoubleX2#.
This is done by introducing the 'Regs' newtype around 'UniqSet RegWithFormat',
for which the combining operations take the larger of the two formats
instead of overriding the format.
Operations on 'Regs' are defined in 'GHC.CmmToAsm.Reg.Regs'. There is
a modest compile-time cost for the additional overhead for tracking
register formats, which causes the metric increases of this commit.
The subtle aspects of the implementation are outlined in
Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.
Fixes #26411 #26611
-------------------------
Metric Increase:
T12707
T26425
T3294
-------------------------
- - - - -
c2e83339 by sheaf at 2025-12-18T13:18:19-05:00
Register allocator: reload at same format as spill
This commit ensures that if we spill a register onto the stack at a
given format, we then always reload the register at this same format.
This ensures we don't end up in a situation where we spill F64x2 but end
up only reloading the lower F64. This first reload would make us believe
the whole data is in a register, thus silently losing the upper 64 bits
of the spilled register's contents.
Fixes #26526
- - - - -
55ab583b by sheaf at 2025-12-18T13:18:19-05:00
Register allocation: writes redefine format
As explained in Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear,
we consider all writes to redefine the format of the register.
This ensures that in a situation such as
movsd .Ln6m(%rip),%v1
shufpd $0,%v1,%v1
we properly consider the broadcast operation to change the format of %v1
from F64 to F64x2.
This completes the fix to #26411 (test in T26411b).
- - - - -
20 changed files:
- compiler/GHC/CmmToAsm/Reg/Graph.hs
- compiler/GHC/CmmToAsm/Reg/Graph/Coalesce.hs
- compiler/GHC/CmmToAsm/Reg/Graph/Spill.hs
- compiler/GHC/CmmToAsm/Reg/Graph/SpillCost.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Linear/Base.hs
- compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- + compiler/GHC/CmmToAsm/Reg/Regs.hs
- compiler/GHC/CmmToAsm/Reg/Target.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Unique/Set.hs
- compiler/ghc.cabal.in
- + testsuite/tests/simd/should_run/T26411.hs
- + testsuite/tests/simd/should_run/T26411.stdout
- + testsuite/tests/simd/should_run/T26411b.hs
- + testsuite/tests/simd/should_run/T26411b.stdout
- testsuite/tests/simd/should_run/all.T
Changes:
=====================================
compiler/GHC/CmmToAsm/Reg/Graph.hs
=====================================
@@ -335,14 +335,14 @@ buildGraph platform code
-- Conflicts between virtual and real regs are recorded as exclusions.
graphAddConflictSet
:: Platform
- -> UniqSet RegWithFormat
+ -> Regs
-> Color.Graph VirtualReg RegClass RealReg
-> Color.Graph VirtualReg RegClass RealReg
graphAddConflictSet platform regs graph
= let arch = platformArch platform
- virtuals = takeVirtualRegs regs
- reals = takeRealRegs regs
+ virtuals = takeVirtualRegs $ getRegs regs
+ reals = takeRealRegs $ getRegs regs
graph1 = Color.addConflicts virtuals (classOfVirtualReg arch) graph
-- NB: we could add "arch" as argument to functions such as "addConflicts"
=====================================
compiler/GHC/CmmToAsm/Reg/Graph/Coalesce.hs
=====================================
@@ -13,10 +13,8 @@ import GHC.Cmm
import GHC.Data.Bag
import GHC.Data.Graph.Directed
import GHC.Platform (Platform)
-import GHC.Types.Unique (getUnique)
import GHC.Types.Unique.FM
import GHC.Types.Unique.Supply
-import GHC.Types.Unique.Set
-- | Do register coalescing on this top level thing
--
@@ -88,8 +86,8 @@ slurpJoinMovs platform live
slurpLI rs (LiveInstr _ Nothing) = rs
slurpLI rs (LiveInstr instr (Just live))
| Just (r1, r2) <- takeRegRegMoveInstr platform instr
- , elemUniqSet_Directly (getUnique r1) $ liveDieRead live
- , elemUniqSet_Directly (getUnique r2) $ liveBorn live
+ , r1 `elemRegs` liveDieRead live
+ , r2 `elemRegs` liveBorn live
-- only coalesce movs between two virtuals for now,
-- else we end up with allocatable regs in the live
=====================================
compiler/GHC/CmmToAsm/Reg/Graph/Spill.hs
=====================================
@@ -144,7 +144,7 @@ regSpill_top platform regSlotMap cmm
-- then record the fact that these slots are now live in those blocks
-- in the given slotmap.
patchLiveSlot
- :: BlockMap IntSet -> BlockId -> UniqSet RegWithFormat-> BlockMap IntSet
+ :: BlockMap IntSet -> BlockId -> Regs -> BlockMap IntSet
patchLiveSlot slotMap blockId regsLive
= let
@@ -154,7 +154,8 @@ regSpill_top platform regSlotMap cmm
moreSlotsLive = IntSet.fromList
$ mapMaybe (lookupUFM regSlotMap . regWithFormat_reg)
- $ nonDetEltsUniqSet regsLive
+ $ nonDetEltsUniqSet
+ $ getRegs regsLive
-- See Note [Unique Determinism and code generation]
slotMap'
=====================================
compiler/GHC/CmmToAsm/Reg/Graph/SpillCost.hs
=====================================
@@ -98,7 +98,7 @@ slurpSpillCostInfo platform cfg cmm
countBlock info freqMap (BasicBlock blockId instrs)
| LiveInfo _ _ blockLive _ <- info
, Just rsLiveEntry <- mapLookup blockId blockLive
- , rsLiveEntry_virt <- takeVirtualRegs rsLiveEntry
+ , rsLiveEntry_virt <- takeVirtualRegs $ getRegs rsLiveEntry
= countLIs (ceiling $ blockFreq freqMap blockId) rsLiveEntry_virt instrs
| otherwise
@@ -132,9 +132,9 @@ slurpSpillCostInfo platform cfg cmm
mapM_ (incDefs scale) $ nub $ mapMaybe (takeVirtualReg . regWithFormat_reg) written
-- Compute liveness for entry to next instruction.
- let liveDieRead_virt = takeVirtualRegs (liveDieRead live)
- let liveDieWrite_virt = takeVirtualRegs (liveDieWrite live)
- let liveBorn_virt = takeVirtualRegs (liveBorn live)
+ let liveDieRead_virt = takeVirtualRegs $ getRegs (liveDieRead live)
+ let liveDieWrite_virt = takeVirtualRegs $ getRegs (liveDieWrite live)
+ let liveBorn_virt = takeVirtualRegs $ getRegs (liveBorn live)
let rsLiveAcross
= rsLiveEntry `minusUniqSet` liveDieRead_virt
=====================================
compiler/GHC/CmmToAsm/Reg/Linear.hs
=====================================
@@ -207,7 +207,7 @@ linearRegAlloc
:: forall instr. (Instruction instr)
=> NCGConfig
-> [BlockId] -- ^ entry points
- -> BlockMap (UniqSet RegWithFormat)
+ -> BlockMap Regs
-- ^ live regs on entry to each basic block
-> [SCC (LiveBasicBlock instr)]
-- ^ instructions annotated with "deaths"
@@ -246,7 +246,7 @@ linearRegAlloc'
=> NCGConfig
-> freeRegs
-> [BlockId] -- ^ entry points
- -> BlockMap (UniqSet RegWithFormat) -- ^ live regs on entry to each basic block
+ -> BlockMap Regs -- ^ live regs on entry to each basic block
-> [SCC (LiveBasicBlock instr)] -- ^ instructions annotated with "deaths"
-> UniqDSM ([NatBasicBlock instr], RegAllocStats, Int)
@@ -260,7 +260,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs
linearRA_SCCs :: OutputableRegConstraint freeRegs instr
=> [BlockId]
- -> BlockMap (UniqSet RegWithFormat)
+ -> BlockMap Regs
-> [NatBasicBlock instr]
-> [SCC (LiveBasicBlock instr)]
-> RegM freeRegs [NatBasicBlock instr]
@@ -295,7 +295,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs)
process :: forall freeRegs instr. (OutputableRegConstraint freeRegs instr)
=> [BlockId]
- -> BlockMap (UniqSet RegWithFormat)
+ -> BlockMap Regs
-> [GenBasicBlock (LiveInstr instr)]
-> RegM freeRegs [[NatBasicBlock instr]]
process entry_ids block_live =
@@ -334,7 +334,7 @@ process entry_ids block_live =
--
processBlock
:: OutputableRegConstraint freeRegs instr
- => BlockMap (UniqSet RegWithFormat) -- ^ live regs on entry to each basic block
+ => BlockMap Regs -- ^ live regs on entry to each basic block
-> LiveBasicBlock instr -- ^ block to do register allocation on
-> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated
@@ -351,7 +351,7 @@ processBlock block_live (BasicBlock id instrs)
-- | Load the freeregs and current reg assignment into the RegM state
-- for the basic block with this BlockId.
initBlock :: FR freeRegs
- => BlockId -> BlockMap (UniqSet RegWithFormat) -> RegM freeRegs ()
+ => BlockId -> BlockMap Regs -> RegM freeRegs ()
initBlock id block_live
= do platform <- getPlatform
block_assig <- getBlockAssigR
@@ -368,7 +368,7 @@ initBlock id block_live
setFreeRegsR (frInitFreeRegs platform)
Just live ->
setFreeRegsR $ foldl' (flip $ frAllocateReg platform) (frInitFreeRegs platform)
- (nonDetEltsUniqSet $ takeRealRegs live)
+ (nonDetEltsUniqSet $ takeRealRegs $ getRegs live)
-- See Note [Unique Determinism and code generation]
setAssigR emptyRegMap
@@ -381,7 +381,7 @@ initBlock id block_live
-- | Do allocation for a sequence of instructions.
linearRA
:: forall freeRegs instr. (OutputableRegConstraint freeRegs instr)
- => BlockMap (UniqSet RegWithFormat) -- ^ map of what vregs are live on entry to each block.
+ => BlockMap Regs -- ^ map of what vregs are live on entry to each block.
-> BlockId -- ^ id of the current block, for debugging.
-> [LiveInstr instr] -- ^ liveness annotated instructions in this block.
-> RegM freeRegs
@@ -406,7 +406,7 @@ linearRA block_live block_id = go [] []
-- | Do allocation for a single instruction.
raInsn
:: OutputableRegConstraint freeRegs instr
- => BlockMap (UniqSet RegWithFormat) -- ^ map of what vregs are love on entry to each block.
+ => BlockMap Regs -- ^ map of what vregs are love on entry to each block.
-> [instr] -- ^ accumulator for instructions already processed.
-> BlockId -- ^ the id of the current block, for debugging
-> LiveInstr instr -- ^ the instr to have its regs allocated, with liveness info.
@@ -427,7 +427,7 @@ raInsn _ new_instrs _ (LiveInstr ii@(Instr i) Nothing)
raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
= do
platform <- getPlatform
- assig <- getAssigR :: RegM freeRegs (UniqFM Reg Loc)
+ assig <- getAssigR
-- If we have a reg->reg move between virtual registers, where the
-- src register is not live after this instruction, and the dst
@@ -437,12 +437,12 @@ raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
-- (we can't eliminate it if the source register is on the stack, because
-- we do not want to use one spill slot for different virtual registers)
case takeRegRegMoveInstr platform instr of
- Just (src,dst) | Just (RegWithFormat _ fmt) <- lookupUniqSet_Directly (liveDieRead live) (getUnique src),
+ Just (src,dst) | Just fmt <- lookupReg src (liveDieRead live),
isVirtualReg dst,
not (dst `elemUFM` assig),
isRealReg src || isInReg src assig -> do
case src of
- RegReal rr -> setAssigR (addToUFM assig dst (InReg $ RealRegUsage rr fmt))
+ RegReal rr -> setAssigR (addToUFM assig dst (Loc (InReg rr) fmt))
-- if src is a fixed reg, then we just map dest to this
-- reg in the assignment. src must be an allocatable reg,
-- otherwise it wouldn't be in r_dying.
@@ -461,8 +461,8 @@ raInsn block_live new_instrs id (LiveInstr (Instr instr) (Just live))
return (new_instrs, [])
_ -> genRaInsn block_live new_instrs id instr
- (map regWithFormat_reg $ nonDetEltsUniqSet $ liveDieRead live)
- (map regWithFormat_reg $ nonDetEltsUniqSet $ liveDieWrite live)
+ (map regWithFormat_reg $ nonDetEltsUniqSet $ getRegs $ liveDieRead live)
+ (map regWithFormat_reg $ nonDetEltsUniqSet $ getRegs $ liveDieWrite live)
-- See Note [Unique Determinism and code generation]
raInsn _ _ _ instr
@@ -485,13 +485,16 @@ raInsn _ _ _ instr
isInReg :: Reg -> RegMap Loc -> Bool
-isInReg src assig | Just (InReg _) <- lookupUFM assig src = True
- | otherwise = False
+isInReg src assig
+ | Just (Loc (InReg _) _) <- lookupUFM assig src
+ = True
+ | otherwise
+ = False
genRaInsn :: forall freeRegs instr.
(OutputableRegConstraint freeRegs instr)
- => BlockMap (UniqSet RegWithFormat)
+ => BlockMap Regs
-> [instr]
-> BlockId
-> instr
@@ -643,14 +646,16 @@ releaseRegs regs = do
loop assig !free (RegReal rr : rs) = loop assig (frReleaseReg platform rr free) rs
loop assig !free (r:rs) =
case lookupUFM assig r of
- Just (InBoth real _) -> loop (delFromUFM assig r)
- (frReleaseReg platform (realReg real) free) rs
- Just (InReg real) -> loop (delFromUFM assig r)
- (frReleaseReg platform (realReg real) free) rs
- _ -> loop (delFromUFM assig r) free rs
+ Just (Loc (InBoth real _) _) ->
+ loop (delFromUFM assig r)
+ (frReleaseReg platform real free) rs
+ Just (Loc (InReg real) _) ->
+ loop (delFromUFM assig r)
+ (frReleaseReg platform real free) rs
+ _ ->
+ loop (delFromUFM assig r) free rs
loop assig free regs
-
-- -----------------------------------------------------------------------------
-- Clobber real registers
@@ -668,17 +673,18 @@ releaseRegs regs = do
saveClobberedTemps
:: forall instr freeRegs.
(Instruction instr, FR freeRegs)
- => [RealReg] -- real registers clobbered by this instruction
- -> [Reg] -- registers which are no longer live after this insn
- -> RegM freeRegs [instr] -- return: instructions to spill any temps that will
- -- be clobbered.
+ => [RealReg] -- ^ real registers clobbered by this instruction
+ -> [Reg] -- ^ registers which are no longer live after this instruction,
+ -- because read for the last time
+ -> RegM freeRegs [instr] -- return: instructions to spill any temps that will
+ -- be clobbered.
saveClobberedTemps [] _
= return []
saveClobberedTemps clobbered dying
= do
- assig <- getAssigR :: RegM freeRegs (UniqFM Reg Loc)
+ assig <- getAssigR
(assig',instrs) <- nonDetStrictFoldUFM_DirectlyM maybe_spill (assig,[]) assig
setAssigR assig'
return $ -- mkComment (text "<saveClobberedTemps>") ++
@@ -687,19 +693,21 @@ saveClobberedTemps clobbered dying
where
-- Unique represents the VirtualReg
-- Here we separate the cases which we do want to spill from these we don't.
- maybe_spill :: Unique -> (RegMap Loc,[instr]) -> (Loc) -> RegM freeRegs (RegMap Loc,[instr])
+ maybe_spill :: Unique
+ -> (RegMap Loc,[instr])
+ -> Loc
+ -> RegM freeRegs (RegMap Loc,[instr])
maybe_spill !temp !(assig,instrs) !loc =
case loc of
-- This is non-deterministic but we do not
-- currently support deterministic code-generation.
-- See Note [Unique Determinism and code generation]
- InReg reg
- | any (realRegsAlias $ realReg reg) clobbered
+ Loc (InReg reg) fmt
+ | any (realRegsAlias reg) clobbered
, temp `notElem` map getUnique dying
- -> clobber temp (assig,instrs) reg
+ -> clobber temp (assig,instrs) (RealRegUsage reg fmt)
_ -> return (assig,instrs)
-
-- See Note [UniqFM and the register allocator]
clobber :: Unique -> (RegMap Loc,[instr]) -> RealRegUsage -> RegM freeRegs (RegMap Loc,[instr])
clobber temp (assig,instrs) (RealRegUsage reg fmt)
@@ -718,7 +726,7 @@ saveClobberedTemps clobbered dying
(my_reg : _) -> do
setFreeRegsR (frAllocateReg platform my_reg freeRegs)
- let new_assign = addToUFM_Directly assig temp (InReg (RealRegUsage my_reg fmt))
+ let new_assign = addToUFM_Directly assig temp (Loc (InReg my_reg) fmt)
let instr = mkRegRegMoveInstr config fmt
(RegReal reg) (RegReal my_reg)
@@ -726,12 +734,13 @@ saveClobberedTemps clobbered dying
-- (2) no free registers: spill the value
[] -> do
+
(spill, slot) <- spillR (RegWithFormat (RegReal reg) fmt) temp
-- record why this reg was spilled for profiling
recordSpill (SpillClobber temp)
- let new_assign = addToUFM_Directly assig temp (InBoth (RealRegUsage reg fmt) slot)
+ let new_assign = addToUFM_Directly assig temp (Loc (InBoth reg slot) fmt)
return (new_assign, (spill ++ instrs))
@@ -779,9 +788,9 @@ clobberRegs clobbered
clobber assig []
= assig
- clobber assig ((temp, InBoth reg slot) : rest)
- | any (realRegsAlias $ realReg reg) clobbered
- = clobber (addToUFM_Directly assig temp (InMem slot)) rest
+ clobber assig ((temp, Loc (InBoth reg slot) regFmt) : rest)
+ | any (realRegsAlias reg) clobbered
+ = clobber (addToUFM_Directly assig temp (Loc (InMem slot) regFmt)) rest
clobber assig (_:rest)
= clobber assig rest
@@ -790,9 +799,9 @@ clobberRegs clobbered
-- allocateRegsAndSpill
-- Why are we performing a spill?
-data SpillLoc = ReadMem StackSlot -- reading from register only in memory
- | WriteNew -- writing to a new variable
- | WriteMem -- writing to register only in memory
+data SpillLoc = ReadMem StackSlot Format -- reading from register only in memory
+ | WriteNew -- writing to a new variable
+ | WriteMem -- writing to register only in memory
-- Note that ReadNew is not valid, since you don't want to be reading
-- from an uninitialized register. We also don't need the location of
-- the register in memory, since that will be invalidated by the write.
@@ -818,28 +827,36 @@ allocateRegsAndSpill
allocateRegsAndSpill _ _ spills alloc []
= return (spills, reverse alloc)
-allocateRegsAndSpill reading keep spills alloc (r@(VirtualRegWithFormat vr _fmt):rs)
+allocateRegsAndSpill reading keep spills alloc (r@(VirtualRegWithFormat vr vrFmt):rs)
= do assig <- toVRegMap <$> getAssigR
-- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig)
-- See Note [UniqFM and the register allocator]
let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig
case lookupUFM assig vr of
-- case (1a): already in a register
- Just (InReg my_reg) ->
- allocateRegsAndSpill reading keep spills (realReg my_reg:alloc) rs
+ Just (Loc (InReg my_reg) in_reg_fmt) -> do
+ -- (RF1) from Note [Allocated register formats]:
+ -- writes redefine the format the register is used at.
+ when (not reading && vrFmt /= in_reg_fmt) $
+ setAssigR $ toRegMap $
+ addToUFM assig vr (Loc (InReg my_reg) vrFmt)
+ allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
-- case (1b): already in a register (and memory)
- -- NB1. if we're writing this register, update its assignment to be
- -- InReg, because the memory value is no longer valid.
- -- NB2. This is why we must process written registers here, even if they
- -- are also read by the same instruction.
- Just (InBoth my_reg _)
- -> do when (not reading) (setAssigR $ toRegMap (addToUFM assig vr (InReg my_reg)))
- allocateRegsAndSpill reading keep spills (realReg my_reg:alloc) rs
+ Just (Loc (InBoth my_reg _) _) -> do
+ -- NB1. if we're writing this register, update its assignment to be
+ -- InReg, because the memory value is no longer valid.
+ -- NB2. This is why we must process written registers here, even if they
+ -- are also read by the same instruction.
+ when (not reading) $
+ setAssigR $ toRegMap $
+ addToUFM assig vr (Loc (InReg my_reg) vrFmt)
+ allocateRegsAndSpill reading keep spills (my_reg:alloc) rs
-- Not already in a register, so we need to find a free one...
- Just (InMem slot) | reading -> doSpill (ReadMem slot)
- | otherwise -> doSpill WriteMem
+ Just (Loc (InMem slot) memFmt)
+ | reading -> doSpill (ReadMem slot memFmt)
+ | otherwise -> doSpill WriteMem
Nothing | reading ->
pprPanic "allocateRegsAndSpill: Cannot read from uninitialized register" (ppr vr)
-- NOTE: if the input to the NCG contains some
@@ -875,7 +892,7 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr)
-> UniqFM VirtualReg Loc
-> SpillLoc
-> RegM freeRegs ([instr], [RealReg])
-allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt) rs assig spill_loc
+allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr vrFmt) rs assig spill_loc
= do platform <- getPlatform
freeRegs <- getFreeRegsR
let regclass = classOfVirtualReg (platformArch platform) vr
@@ -897,7 +914,7 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
spills' <- loadTemp r spill_loc final_reg spills
setAssigR $ toRegMap
- $ (addToUFM assig vr $! newLocation spill_loc $ RealRegUsage final_reg fmt)
+ $ (addToUFM assig vr $! newLocation spill_loc $ RealRegUsage final_reg vrFmt)
setFreeRegsR $ frAllocateReg platform final_reg freeRegs
allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs
@@ -911,7 +928,7 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
let candidates' :: UniqFM VirtualReg Loc
candidates' =
flip delListFromUFM (fmap virtualRegWithFormat_reg keep) $
- filterUFM inRegOrBoth $
+ filterUFM (inRegOrBoth . locWithFormat_loc) $
assig
-- This is non-deterministic but we do not
-- currently support deterministic code-generation.
@@ -924,25 +941,25 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
== regclass
candidates_inBoth :: [(Unique, RealRegUsage, StackSlot)]
candidates_inBoth
- = [ (temp, reg, mem)
- | (temp, InBoth reg mem) <- candidates
- , compat (realReg reg) ]
+ = [ (temp, RealRegUsage reg fmt, mem)
+ | (temp, Loc (InBoth reg mem) fmt) <- candidates
+ , compat reg ]
-- the vregs we could kick out that are only in a reg
-- this would require writing the reg to a new slot before using it.
let candidates_inReg
- = [ (temp, reg)
- | (temp, InReg reg) <- candidates
- , compat (realReg reg) ]
+ = [ (temp, RealRegUsage reg fmt)
+ | (temp, Loc (InReg reg) fmt) <- candidates
+ , compat reg ]
let result
-- we have a temporary that is in both register and mem,
-- just free up its register for use.
- | (temp, (RealRegUsage cand_reg _old_fmt), slot) : _ <- candidates_inBoth
+ | (temp, (RealRegUsage cand_reg old_fmt), slot) : _ <- candidates_inBoth
= do spills' <- loadTemp r spill_loc cand_reg spills
- let assig1 = addToUFM_Directly assig temp (InMem slot)
- let assig2 = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg fmt)
+ let assig1 = addToUFM_Directly assig temp $ Loc (InMem slot) old_fmt
+ let assig2 = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg vrFmt)
setAssigR $ toRegMap assig2
allocateRegsAndSpill reading keep spills' (cand_reg:alloc) rs
@@ -962,8 +979,8 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
-- - the old data is now only in memory,
-- - the new data is now allocated to this register;
-- make sure to use the new format (#26542)
- let assig1 = addToUFM_Directly assig temp_to_push_out (InMem slot)
- let assig2 = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg fmt)
+ let assig1 = addToUFM_Directly assig temp_to_push_out $ Loc (InMem slot) old_reg_fmt
+ let assig2 = addToUFM assig1 vr $! newLocation spill_loc (RealRegUsage cand_reg vrFmt)
setAssigR $ toRegMap assig2
-- if need be, load up a spilled temp into the reg we've just freed up.
@@ -980,7 +997,7 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
$ vcat
[ text "allocating vreg: " <> text (show vr)
, text "assignment: " <> ppr assig
- , text "format: " <> ppr fmt
+ , text "format: " <> ppr vrFmt
, text "freeRegs: " <> text (showRegs freeRegs)
, text "initFreeRegs: " <> text (showRegs (frInitFreeRegs platform `asTypeOf` freeRegs))
]
@@ -992,9 +1009,12 @@ allocRegsAndSpill_spill reading keep spills alloc r@(VirtualRegWithFormat vr fmt
-- | Calculate a new location after a register has been loaded.
newLocation :: SpillLoc -> RealRegUsage -> Loc
-- if the tmp was read from a slot, then now its in a reg as well
-newLocation (ReadMem slot) my_reg = InBoth my_reg slot
+newLocation (ReadMem slot memFmt) (RealRegUsage r _regFmt) =
+ -- See Note [Use spilled format when reloading]
+ Loc (InBoth r slot) memFmt
+
-- writes will always result in only the register being available
-newLocation _ my_reg = InReg my_reg
+newLocation _ (RealRegUsage r regFmt) = Loc (InReg r) regFmt
-- | Load up a spilled temporary if we need to (read from memory).
loadTemp
@@ -1005,11 +1025,91 @@ loadTemp
-> [instr]
-> RegM freeRegs [instr]
-loadTemp (VirtualRegWithFormat vreg fmt) (ReadMem slot) hreg spills
+loadTemp (VirtualRegWithFormat vreg _fmt) (ReadMem slot memFmt) hreg spills
= do
- insn <- loadR (RegWithFormat (RegReal hreg) fmt) slot
+ -- See Note [Use spilled format when reloading]
+ insn <- loadR (RegWithFormat (RegReal hreg) memFmt) slot
recordSpill (SpillLoad $ getUnique vreg)
return $ {- mkComment (text "spill load") : -} insn ++ spills
loadTemp _ _ _ spills =
return spills
+
+{- Note [Allocated register formats]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We uphold the following principle for the format at which we keep track of
+alllocated registers:
+
+ RF1. Writes redefine the format.
+
+ When we write to a register 'r' at format 'fmt', we consider the register
+ to hold that format going forwards.
+
+ (In cases where a partial write is desired, the move instruction should
+ specify that the destination format is the full register, even if, say,
+ the instruction only writes to the low 64 bits of the register.
+ See also Wrinkle [Don't allow scalar partial writes] in
+ Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.)
+
+ RF2. Reads from a register do not redefine its format.
+
+ Generally speaking, as explained in Note [Register formats in liveness analysis]
+ in GHC.CmmToAsm.Reg.Liveness, when computing the used format from a collection
+ of reads, we take a least upper bound.
+
+It is particularly important to get (RF1) correct, as otherwise we can end up in
+the situation of T26411b, where code such as
+
+ movsd .Ln6m(%rip),%v1
+ shufpd $0,%v1,%v1
+
+we start off with %v1 :: F64, but after shufpd (which broadcasts the low part
+to the high part) we must consider that %v1 :: F64x2. If we fail to do that,
+then we will silently discard the top bits in spill/reload operations.
+-}
+
+{- Note [Use spilled format when reloading]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We always reload at the full format that a register was spilled at. The rationale
+is as follows:
+
+ 1. If later instructions only need the lower 64 bits of an XMM register,
+ then we should have only spilled the lower 64 bits in the first place.
+ (Whether this is true currently is another question.)
+ 2. If later instructions need say 128 bits, then we should immediately load
+ the entire 128 bits, as this avoids multiple load instructions.
+
+For (2), consider the situation of #26526, where we need to spill around a C
+call (because we are using the System V ABI with no callee saved XMM registers).
+Before register allocation, we have:
+
+ vmovupd %v1 %v0
+ call ...
+ movsd %v0 %v3
+ movhlps %v0 %v4
+
+The contents of %v0 need to be preserved across the call. We must spill %v0 at
+format F64x2 (as later instructions need the entire 128 bits), and reload it
+later. We thus expect something like:
+
+ vmovupd %xmm1 %xmm0
+ vmovupd %xmm0 72(%rsp) -- spill to preserve
+ call ...
+ vmovupd 72(%rsp) %xmm0 -- restore
+ movsd %xmm0 %xmm3
+ movhlps %xmm0 %xmm4
+
+This is certainly better than doing two loads from the stack, e.g.
+
+ call ...
+ movsd 72(%rsp) %xmm0 -- restore only lower 64 bits
+ movsd %xmm0 %xmm3
+ vmovupd 72(%rsp) %xmm0 -- restore the full 128 bits
+ movhlps %xmm0 %xmm4
+
+The latter being especially risky because we don't want to believe %v0 is 'InBoth'
+with format F64. The risk is that, when allocating registers for the 'VMOVUPD'
+instruction, we think our data is already in a register and thus doesn't need to
+be reloaded from memory, when in fact we have only loaded the lower 64 bits of
+the data.
+-}
=====================================
compiler/GHC/CmmToAsm/Reg/Linear/Base.hs
=====================================
@@ -1,3 +1,4 @@
+{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
-- | Put common type definitions here to break recursive module dependencies.
@@ -9,7 +10,7 @@ module GHC.CmmToAsm.Reg.Linear.Base (
emptyBlockAssignment,
updateBlockAssignment,
- Loc(..),
+ VLoc(..), Loc(..), IgnoreFormat(..),
regsOfLoc,
RealRegUsage(..),
@@ -39,8 +40,6 @@ import GHC.Cmm.Dataflow.Label
import GHC.CmmToAsm.Reg.Utils
import GHC.CmmToAsm.Format
-import Data.Function ( on )
-
data ReadingOrWriting = Reading | Writing deriving (Eq,Ord)
-- | Used to store the register assignment on entry to a basic block.
@@ -70,8 +69,13 @@ updateBlockAssignment :: BlockId
-> BlockAssignment freeRegs
-> BlockAssignment freeRegs
updateBlockAssignment dest (freeRegs, regMap) (BlockAssignment {..}) =
- BlockAssignment (mapInsert dest (freeRegs, regMap) blockMap)
- (mergeUFM combWithExisting id (mapMaybeUFM fromLoc) (firstUsed) (toVRegMap regMap))
+ BlockAssignment
+ (mapInsert dest (freeRegs, regMap) blockMap)
+ (mergeUFM combWithExisting id
+ (mapMaybeUFM (fromVLoc . locWithFormat_loc))
+ firstUsed
+ (toVRegMap regMap)
+ )
where
-- The blocks are processed in dependency order, so if there's already an
-- entry in the map then keep that assignment rather than writing the new
@@ -79,13 +83,14 @@ updateBlockAssignment dest (freeRegs, regMap) (BlockAssignment {..}) =
combWithExisting :: RealReg -> Loc -> Maybe RealReg
combWithExisting old_reg _ = Just $ old_reg
- fromLoc :: Loc -> Maybe RealReg
- fromLoc (InReg rr) = Just $ realReg rr
- fromLoc (InBoth rr _) = Just $ realReg rr
- fromLoc _ = Nothing
-
+ fromVLoc :: VLoc -> Maybe RealReg
+ fromVLoc (InReg rr) = Just rr
+ fromVLoc (InBoth rr _) = Just rr
+ fromVLoc _ = Nothing
--- | Where a vreg is currently stored
+-- | Where a vreg is currently stored.
+--
+--
-- A temporary can be marked as living in both a register and memory
-- (InBoth), for example if it was recently loaded from a spill location.
-- This makes it cheap to spill (no save instruction required), but we
@@ -96,22 +101,41 @@ updateBlockAssignment dest (freeRegs, regMap) (BlockAssignment {..}) =
-- save it in a spill location, but mark it as InBoth because the current
-- instruction might still want to read it.
--
-data Loc
+data VLoc
-- | vreg is in a register
- = InReg {-# UNPACK #-} !RealRegUsage
+ = InReg {-# UNPACK #-} !RealReg
-- | vreg is held in stack slots
- | InMem {-# UNPACK #-} !StackSlot
-
+ | InMem {-# UNPACK #-} !StackSlot
-- | vreg is held in both a register and stack slots
- | InBoth {-# UNPACK #-} !RealRegUsage
- {-# UNPACK #-} !StackSlot
+ | InBoth {-# UNPACK #-} !RealReg
+ {-# UNPACK #-} !StackSlot
deriving (Eq, Ord, Show)
-instance Outputable Loc where
+-- | Where a virtual register is stored, together with the format it is stored at.
+--
+-- See 'VLoc'.
+data Loc
+ = Loc
+ { locWithFormat_loc :: {-# UNPACK #-} !VLoc
+ , locWithFormat_format :: Format
+ }
+
+-- | A newtype used to hang off 'Eq' and 'Ord' instances for 'Loc' which
+-- ignore the format, as used in 'GHC.CmmToAsm.Reg.Linear.JoinToTargets'.
+newtype IgnoreFormat a = IgnoreFormat a
+instance Eq (IgnoreFormat Loc) where
+ IgnoreFormat (Loc l1 _) == IgnoreFormat (Loc l2 _) = l1 == l2
+instance Ord (IgnoreFormat Loc) where
+ compare (IgnoreFormat (Loc l1 _)) (IgnoreFormat (Loc l2 _)) = compare l1 l2
+
+instance Outputable VLoc where
ppr l = text (show l)
+instance Outputable Loc where
+ ppr (Loc loc fmt) = parens (ppr loc <+> dcolon <+> ppr fmt)
+
-- | A 'RealReg', together with the specific 'Format' it is used at.
data RealRegUsage
= RealRegUsage
@@ -122,22 +146,12 @@ data RealRegUsage
instance Outputable RealRegUsage where
ppr (RealRegUsage r fmt) = ppr r <> dcolon <+> ppr fmt
--- NB: these instances only compare the underlying 'RealReg', as that is what
--- is important for register allocation.
---
--- (It would nonetheless be a good idea to remove these instances.)
-instance Eq RealRegUsage where
- (==) = (==) `on` realReg
-instance Ord RealRegUsage where
- compare = compare `on` realReg
-
-- | Get the reg numbers stored in this Loc.
-regsOfLoc :: Loc -> [RealRegUsage]
+regsOfLoc :: VLoc -> [RealReg]
regsOfLoc (InReg r) = [r]
regsOfLoc (InBoth r _) = [r]
regsOfLoc (InMem _) = []
-
-- | Reasons why instructions might be inserted by the spiller.
-- Used when generating stats for -ddrop-asm-stats.
--
=====================================
compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs
=====================================
@@ -33,12 +33,14 @@ import GHC.Utils.Outputable
import GHC.CmmToAsm.Format
import GHC.Types.Unique.Set
+import Data.Coerce (coerce)
+
-- | For a jump instruction at the end of a block, generate fixup code so its
-- vregs are in the correct regs for its destination.
--
joinToTargets
:: (FR freeRegs, Instruction instr)
- => BlockMap (UniqSet RegWithFormat) -- ^ maps the unique of the blockid to the set of vregs
+ => BlockMap Regs -- ^ maps the unique of the blockid to the set of vregs
-- that are known to be live on the entry to each block.
-> BlockId -- ^ id of the current block
@@ -62,7 +64,7 @@ joinToTargets block_live id instr
-----
joinToTargets'
:: (FR freeRegs, Instruction instr)
- => BlockMap (UniqSet RegWithFormat) -- ^ maps the unique of the blockid to the set of vregs
+ => BlockMap Regs -- ^ maps the unique of the blockid to the set of vregs
-- that are known to be live on the entry to each block.
-> [NatBasicBlock instr] -- ^ acc blocks of fixup code.
@@ -90,23 +92,23 @@ joinToTargets' block_live new_blocks block_id instr (dest:dests)
-- adjust the current assignment to remove any vregs that are not live
-- on entry to the destination block.
let live_set = expectJust $ mapLookup dest block_live
- let still_live uniq _ = uniq `elemUniqSet_Directly` live_set
+ let still_live uniq _ = uniq `elemUniqSet_Directly` getRegs live_set
let adjusted_assig = filterUFM_Directly still_live assig
-- and free up those registers which are now free.
let to_free =
- [ r | (reg, loc) <- nonDetUFMToList assig
+ [ r | (reg, Loc loc _locFmt) <- nonDetUFMToList assig
-- This is non-deterministic but we do not
-- currently support deterministic code-generation.
-- See Note [Unique Determinism and code generation]
- , not (elemUniqSet_Directly reg live_set)
+ , not (elemUniqSet_Directly reg $ getRegs live_set)
, r <- regsOfLoc loc ]
case lookupBlockAssignment dest block_assig of
Nothing
-> joinToTargets_first
block_live new_blocks block_id instr dest dests
- block_assig adjusted_assig $ map realReg to_free
+ block_assig adjusted_assig to_free
Just (_, dest_assig)
-> joinToTargets_again
@@ -116,7 +118,7 @@ joinToTargets' block_live new_blocks block_id instr (dest:dests)
-- this is the first time we jumped to this block.
joinToTargets_first :: (FR freeRegs, Instruction instr)
- => BlockMap (UniqSet RegWithFormat)
+ => BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
@@ -142,10 +144,9 @@ joinToTargets_first block_live new_blocks block_id instr dest dests
joinToTargets' block_live new_blocks block_id instr dests
-
-- we've jumped to this block before
joinToTargets_again :: (Instruction instr, FR freeRegs)
- => BlockMap (UniqSet RegWithFormat)
+ => BlockMap Regs
-> [NatBasicBlock instr]
-> BlockId
-> instr
@@ -159,7 +160,9 @@ joinToTargets_again
src_assig dest_assig
-- the assignments already match, no problem.
- | nonDetUFMToList dest_assig == nonDetUFMToList src_assig
+ | equalIgnoringFormats
+ (nonDetUFMToList dest_assig)
+ (nonDetUFMToList src_assig)
-- This is non-deterministic but we do not
-- currently support deterministic code-generation.
-- See Note [Unique Determinism and code generation]
@@ -183,7 +186,7 @@ joinToTargets_again
--
-- We need to do the R2 -> R3 move before R1 -> R2.
--
- let sccs = stronglyConnCompFromEdgedVerticesOrdR graph
+ let sccs = movementGraphSCCs graph
-- debugging
{-
@@ -267,30 +270,36 @@ makeRegMovementGraph adjusted_assig dest_assig
--
expandNode
:: a
- -> Loc -- ^ source of move
- -> Loc -- ^ destination of move
- -> [Node Loc a ]
-
-expandNode vreg loc@(InReg src) (InBoth dst mem)
- | src == dst = [DigraphNode vreg loc [InMem mem]]
- | otherwise = [DigraphNode vreg loc [InReg dst, InMem mem]]
-
-expandNode vreg loc@(InMem src) (InBoth dst mem)
- | src == mem = [DigraphNode vreg loc [InReg dst]]
- | otherwise = [DigraphNode vreg loc [InReg dst, InMem mem]]
-
-expandNode _ (InBoth _ src) (InMem dst)
- | src == dst = [] -- guaranteed to be true
-
-expandNode _ (InBoth src _) (InReg dst)
- | src == dst = []
-
-expandNode vreg (InBoth src _) dst
- = expandNode vreg (InReg src) dst
-
-expandNode vreg src dst
- | src == dst = []
- | otherwise = [DigraphNode vreg src [dst]]
+ -> Loc -- ^ source of move
+ -> Loc -- ^ destination of move
+ -> [Node Loc a]
+expandNode vreg src@(Loc srcLoc srcFmt) dst@(Loc dstLoc dstFmt) =
+ case (srcLoc, dstLoc) of
+ (InReg srcReg, InBoth dstReg dstMem)
+ | srcReg == dstReg
+ -> [DigraphNode vreg src [Loc (InMem dstMem) dstFmt]]
+ | otherwise
+ -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt
+ ,Loc (InMem dstMem) dstFmt]]
+ (InMem srcMem, InBoth dstReg dstMem)
+ | srcMem == dstMem
+ -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt]]
+ | otherwise
+ -> [DigraphNode vreg src [Loc (InReg dstReg) dstFmt
+ ,Loc (InMem dstMem) dstFmt]]
+ (InBoth _ srcMem, InMem dstMem)
+ | srcMem == dstMem
+ -> [] -- guaranteed to be true
+ (InBoth srcReg _, InReg dstReg)
+ | srcReg == dstReg
+ -> []
+ (InBoth srcReg _, _)
+ -> expandNode vreg (Loc (InReg srcReg) srcFmt) dst
+ _
+ | srcLoc == dstLoc
+ -> []
+ | otherwise
+ -> [DigraphNode vreg src [dst]]
-- | Generate fixup code for a particular component in the move graph
@@ -327,7 +336,7 @@ handleComponent delta _ (AcyclicSCC (DigraphNode vreg src dsts))
-- require a fixup.
--
handleComponent delta instr
- (CyclicSCC ((DigraphNode vreg (InReg (RealRegUsage sreg scls)) ((InReg (RealRegUsage dreg dcls): _))) : rest))
+ (CyclicSCC ((DigraphNode vreg (Loc (InReg sreg) scls) ((Loc (InReg dreg) dcls: _))) : rest))
-- dest list may have more than one element, if the reg is also InMem.
= do
-- spill the source into its slot
@@ -338,7 +347,7 @@ handleComponent delta instr
instrLoad <- loadR (RegWithFormat (RegReal dreg) dcls) slot
remainingFixUps <- mapM (handleComponent delta instr)
- (stronglyConnCompFromEdgedVerticesOrdR rest)
+ (movementGraphSCCs rest)
-- make sure to do all the reloads after all the spills,
-- so we don't end up clobbering the source values.
@@ -347,29 +356,37 @@ handleComponent delta instr
handleComponent _ _ (CyclicSCC _)
= panic "Register Allocator: handleComponent cyclic"
+-- Helper functions that use the @Ord (IgnoreFormat Loc)@ instance.
+
+equalIgnoringFormats :: [(Unique, Loc)] -> [(Unique, Loc)] -> Bool
+equalIgnoringFormats =
+ coerce $ (==) @[(Unique, IgnoreFormat Loc)]
+movementGraphSCCs :: [Node Loc Unique] -> [SCC (Node Loc Unique)]
+movementGraphSCCs =
+ coerce $ stronglyConnCompFromEdgedVerticesOrdR @(IgnoreFormat Loc) @Unique
-- | Move a vreg between these two locations.
--
makeMove
:: Instruction instr
- => Int -- ^ current C stack delta.
- -> Unique -- ^ unique of the vreg that we're moving.
- -> Loc -- ^ source location.
- -> Loc -- ^ destination location.
- -> RegM freeRegs [instr] -- ^ move instruction.
+ => Int -- ^ current C stack delta
+ -> Unique -- ^ unique of the vreg that we're moving
+ -> Loc -- ^ source location
+ -> Loc -- ^ destination location
+ -> RegM freeRegs [instr] -- ^ move instruction
-makeMove delta vreg src dst
+makeMove delta vreg (Loc src _srcFmt) (Loc dst dstFmt)
= do config <- getConfig
case (src, dst) of
- (InReg (RealRegUsage s _), InReg (RealRegUsage d fmt)) ->
+ (InReg s, InReg d) ->
do recordSpill (SpillJoinRR vreg)
- return $ [mkRegRegMoveInstr config fmt (RegReal s) (RegReal d)]
- (InMem s, InReg (RealRegUsage d cls)) ->
+ return $ [mkRegRegMoveInstr config dstFmt (RegReal s) (RegReal d)]
+ (InMem s, InReg d) ->
do recordSpill (SpillJoinRM vreg)
- return $ mkLoadInstr config (RegWithFormat (RegReal d) cls) delta s
- (InReg (RealRegUsage s cls), InMem d) ->
+ return $ mkLoadInstr config (RegWithFormat (RegReal d) dstFmt) delta s
+ (InReg s, InMem d) ->
do recordSpill (SpillJoinRM vreg)
- return $ mkSpillInstr config (RegWithFormat (RegReal s) cls) delta d
+ return $ mkSpillInstr config (RegWithFormat (RegReal s) dstFmt) delta d
_ ->
-- we don't handle memory to memory moves.
-- they shouldn't happen because we don't share
=====================================
compiler/GHC/CmmToAsm/Reg/Liveness.hs
=====================================
@@ -30,7 +30,9 @@ module GHC.CmmToAsm.Reg.Liveness (
patchRegsLiveInstr,
reverseBlocksInTops,
regLiveness,
- cmmTopLiveness
+ cmmTopLiveness,
+
+ module GHC.CmmToAsm.Reg.Regs
) where
import GHC.Prelude
@@ -41,11 +43,11 @@ import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Format
import GHC.CmmToAsm.Types
import GHC.CmmToAsm.Utils
+import GHC.CmmToAsm.Reg.Regs
import GHC.Cmm.BlockId
import GHC.Cmm.Dataflow.Label
import GHC.Cmm
-import GHC.CmmToAsm.Reg.Target
import GHC.Data.Graph.Directed
import GHC.Data.OrdList
@@ -189,9 +191,9 @@ data LiveInstr instr
data Liveness
= Liveness
- { liveBorn :: UniqSet RegWithFormat -- ^ registers born in this instruction (written to for first time).
- , liveDieRead :: UniqSet RegWithFormat -- ^ registers that died because they were read for the last time.
- , liveDieWrite :: UniqSet RegWithFormat} -- ^ registers that died because they were clobbered by something.
+ { liveBorn :: Regs -- ^ registers born in this instruction (written to for first time).
+ , liveDieRead :: Regs -- ^ registers that died because they were read for the last time.
+ , liveDieWrite :: Regs } -- ^ registers that died because they were clobbered by something.
-- | Stash regs live on entry to each basic block in the info part of the cmm code.
@@ -200,7 +202,7 @@ data LiveInfo
(LabelMap RawCmmStatics) -- cmm info table static stuff
[BlockId] -- entry points (first one is the
-- entry point for the proc).
- (BlockMap (UniqSet RegWithFormat)) -- argument locals live on entry to this block
+ (BlockMap Regs) -- argument locals live on entry to this block
(BlockMap IntSet) -- stack slots live on entry to this block
@@ -246,8 +248,8 @@ instance Outputable instr
, pprRegs (text "# w_dying: ") (liveDieWrite live) ]
$+$ space)
- where pprRegs :: SDoc -> UniqSet RegWithFormat -> SDoc
- pprRegs name regs
+ where pprRegs :: SDoc -> Regs -> SDoc
+ pprRegs name ( Regs regs )
| isEmptyUniqSet regs = empty
| otherwise = name <>
(pprUFM (getUniqSet regs) (hcat . punctuate space . map ppr))
@@ -330,7 +332,7 @@ slurpConflicts
:: Instruction instr
=> Platform
-> LiveCmmDecl statics instr
- -> (Bag (UniqSet RegWithFormat), Bag (Reg, Reg))
+ -> (Bag Regs, Bag (Reg, Reg))
slurpConflicts platform live
= slurpCmm (emptyBag, emptyBag) live
@@ -364,23 +366,22 @@ slurpConflicts platform live
= let
-- regs that die because they are read for the last time at the start of an instruction
-- are not live across it.
- rsLiveAcross = rsLiveEntry `minusUniqSet` (liveDieRead live)
+ rsLiveAcross = rsLiveEntry `minusRegs` (liveDieRead live)
-- regs live on entry to the next instruction.
-- be careful of orphans, make sure to delete dying regs _after_ unioning
-- in the ones that are born here.
- rsLiveNext = (rsLiveAcross `unionUniqSets` (liveBorn live))
- `minusUniqSet` (liveDieWrite live)
+ rsLiveNext = (rsLiveAcross `unionRegsMaxFmt` (liveBorn live))
+ `minusCoveredRegs` (liveDieWrite live)
-- orphan vregs are the ones that die in the same instruction they are born in.
-- these are likely to be results that are never used, but we still
-- need to assign a hreg to them..
- rsOrphans = intersectUniqSets
+ rsOrphans = intersectRegsMaxFmt
(liveBorn live)
- (unionUniqSets (liveDieWrite live) (liveDieRead live))
+ (unionRegsMaxFmt (liveDieWrite live) (liveDieRead live))
- --
- rsConflicts = unionUniqSets rsLiveNext rsOrphans
+ rsConflicts = unionRegsMaxFmt rsLiveNext rsOrphans
in case takeRegRegMoveInstr platform instr of
Just rr -> slurpLIs rsLiveNext
@@ -619,7 +620,7 @@ patchEraseLive platform patchF cmm
| LiveInfo static id blockMap mLiveSlots <- info
= let
-- See Note [Unique Determinism and code generation]
- blockMap' = mapMap (mapRegFormatSet patchF) blockMap
+ blockMap' = mapMap (mapRegs patchF) blockMap
info' = LiveInfo static id blockMap' mLiveSlots
in CmmProc info' label live $ map patchSCC sccs
@@ -648,8 +649,8 @@ patchEraseLive platform patchF cmm
| r1 == r2 = True
-- destination reg is never used
- | elemUniqSet_Directly (getUnique r2) (liveBorn live)
- , elemUniqSet_Directly (getUnique r2) (liveDieRead live) || elemUniqSet_Directly (getUnique r2) (liveDieWrite live)
+ | r2 `elemRegs` liveBorn live
+ , r2 `elemRegs` liveDieRead live || r2 `elemRegs` liveDieWrite live
= True
| otherwise = False
@@ -673,9 +674,9 @@ patchRegsLiveInstr platform patchF li
(patchRegsOfInstr platform instr patchF)
(Just live
{ -- WARNING: have to go via lists here because patchF changes the uniq in the Reg
- liveBorn = mapRegFormatSet patchF $ liveBorn live
- , liveDieRead = mapRegFormatSet patchF $ liveDieRead live
- , liveDieWrite = mapRegFormatSet patchF $ liveDieWrite live })
+ liveBorn = mapRegs patchF $ liveBorn live
+ , liveDieRead = mapRegs patchF $ liveDieRead live
+ , liveDieWrite = mapRegs patchF $ liveDieWrite live })
-- See Note [Unique Determinism and code generation]
--------------------------------------------------------------------------------
@@ -865,7 +866,7 @@ computeLiveness
-> [SCC (LiveBasicBlock instr)]
-> ([SCC (LiveBasicBlock instr)], -- instructions annotated with list of registers
-- which are "dead after this instruction".
- BlockMap (UniqSet RegWithFormat)) -- blocks annotated with set of live registers
+ BlockMap Regs) -- blocks annotated with set of live registers
-- on entry to the block.
computeLiveness platform sccs
@@ -880,11 +881,11 @@ computeLiveness platform sccs
livenessSCCs
:: Instruction instr
=> Platform
- -> BlockMap (UniqSet RegWithFormat)
+ -> BlockMap Regs
-> [SCC (LiveBasicBlock instr)] -- accum
-> [SCC (LiveBasicBlock instr)]
-> ( [SCC (LiveBasicBlock instr)]
- , BlockMap (UniqSet RegWithFormat))
+ , BlockMap Regs)
livenessSCCs _ blockmap done []
= (done, blockmap)
@@ -913,13 +914,14 @@ livenessSCCs platform blockmap done
linearLiveness
:: Instruction instr
- => BlockMap (UniqSet RegWithFormat) -> [LiveBasicBlock instr]
- -> (BlockMap (UniqSet RegWithFormat), [LiveBasicBlock instr])
+ => BlockMap Regs -> [LiveBasicBlock instr]
+ -> (BlockMap Regs, [LiveBasicBlock instr])
linearLiveness = mapAccumL (livenessBlock platform)
-- probably the least efficient way to compare two
-- BlockMaps for equality.
+ equalBlockMaps :: BlockMap Regs -> BlockMap Regs -> Bool
equalBlockMaps a b
= a' == b'
where a' = mapToList a
@@ -933,14 +935,14 @@ livenessSCCs platform blockmap done
livenessBlock
:: Instruction instr
=> Platform
- -> BlockMap (UniqSet RegWithFormat)
+ -> BlockMap Regs
-> LiveBasicBlock instr
- -> (BlockMap (UniqSet RegWithFormat), LiveBasicBlock instr)
+ -> (BlockMap Regs, LiveBasicBlock instr)
livenessBlock platform blockmap (BasicBlock block_id instrs)
= let
(regsLiveOnEntry, instrs1)
- = livenessBack platform emptyUniqSet blockmap [] (reverse instrs)
+ = livenessBack platform noRegs blockmap [] (reverse instrs)
blockmap' = mapInsert block_id regsLiveOnEntry blockmap
instrs2 = livenessForward platform regsLiveOnEntry instrs1
@@ -955,23 +957,26 @@ livenessBlock platform blockmap (BasicBlock block_id instrs)
livenessForward
:: Instruction instr
=> Platform
- -> UniqSet RegWithFormat -- regs live on this instr
+ -> Regs -- regs live on this instr
-> [LiveInstr instr] -> [LiveInstr instr]
livenessForward _ _ [] = []
livenessForward platform rsLiveEntry (li@(LiveInstr instr mLive) : lis)
| Just live <- mLive
= let
- RU _ written = regUsageOfInstr platform instr
+ RU _ rsWritten = regUsageOfInstr platform instr
-- Regs that are written to but weren't live on entry to this instruction
-- are recorded as being born here.
- rsBorn = mkUniqSet
- $ filter (\ r -> not $ elemUniqSet_Directly (getUnique r) rsLiveEntry)
- $ written
+ rsBorn = mkRegsMaxFmt
+ [ reg
+ | reg@( RegWithFormat r _ ) <- rsWritten
+ , not $ r `elemRegs` rsLiveEntry
+ ]
- rsLiveNext = (rsLiveEntry `unionUniqSets` rsBorn)
- `minusUniqSet` (liveDieRead live)
- `minusUniqSet` (liveDieWrite live)
+ -- See Note [Register formats in liveness analysis]
+ rsLiveNext = (rsLiveEntry `addRegsMaxFmt` rsWritten)
+ `minusRegs` (liveDieRead live) -- (FmtFwd1)
+ `minusRegs` (liveDieWrite live) -- (FmtFwd2)
in LiveInstr instr (Just live { liveBorn = rsBorn })
: livenessForward platform rsLiveNext lis
@@ -986,11 +991,11 @@ livenessForward platform rsLiveEntry (li@(LiveInstr instr mLive) : lis)
livenessBack
:: Instruction instr
=> Platform
- -> UniqSet RegWithFormat -- regs live on this instr
- -> BlockMap (UniqSet RegWithFormat) -- regs live on entry to other BBs
- -> [LiveInstr instr] -- instructions (accum)
- -> [LiveInstr instr] -- instructions
- -> (UniqSet RegWithFormat, [LiveInstr instr])
+ -> Regs -- ^ regs live on this instr
+ -> BlockMap Regs -- ^ regs live on entry to other BBs
+ -> [LiveInstr instr] -- ^ instructions (accum)
+ -> [LiveInstr instr] -- ^ instructions
+ -> (Regs, [LiveInstr instr])
livenessBack _ liveregs _ done [] = (liveregs, done)
@@ -998,15 +1003,14 @@ livenessBack platform liveregs blockmap acc (instr : instrs)
= let !(!liveregs', instr') = liveness1 platform liveregs blockmap instr
in livenessBack platform liveregs' blockmap (instr' : acc) instrs
-
-- don't bother tagging comments or deltas with liveness
liveness1
:: Instruction instr
=> Platform
- -> UniqSet RegWithFormat
- -> BlockMap (UniqSet RegWithFormat)
+ -> Regs
+ -> BlockMap Regs
-> LiveInstr instr
- -> (UniqSet RegWithFormat, LiveInstr instr)
+ -> (Regs, LiveInstr instr)
liveness1 _ liveregs _ (LiveInstr instr _)
| isMetaInstr instr
@@ -1017,14 +1021,14 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
| not_a_branch
= (liveregs1, LiveInstr instr
(Just $ Liveness
- { liveBorn = emptyUniqSet
+ { liveBorn = noRegs
, liveDieRead = r_dying
, liveDieWrite = w_dying }))
| otherwise
= (liveregs_br, LiveInstr instr
(Just $ Liveness
- { liveBorn = emptyUniqSet
+ { liveBorn = noRegs
, liveDieRead = r_dying_br
, liveDieWrite = w_dying }))
@@ -1033,21 +1037,22 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
-- registers that were written here are dead going backwards.
-- registers that were read here are live going backwards.
- liveregs1 = (liveregs `delListFromUniqSet` written)
- `addListToUniqSet` read
+ -- As for the formats, see Note [Register formats in liveness analysis]
+ liveregs1 = (liveregs `minusCoveredRegs` mkRegsMaxFmt written) -- (FmtBwd2)
+ `addRegsMaxFmt` read -- (FmtBwd1)
- -- registers that are not live beyond this point, are recorded
- -- as dying here.
- r_dying = mkUniqSet
+ -- registers that are not live beyond this point are recorded
+ -- as dying here.
+ r_dying = mkRegsMaxFmt
[ reg
| reg@(RegWithFormat r _) <- read
, not $ any (\ w -> getUnique w == getUnique r) written
- , not (elementOfUniqSet reg liveregs) ]
+ , not $ r `elemRegs` liveregs ]
- w_dying = mkUniqSet
+ w_dying = mkRegsMaxFmt
[ reg
- | reg <- written
- , not (elementOfUniqSet reg liveregs) ]
+ | reg@(RegWithFormat r _) <- written
+ , not $ r `elemRegs` liveregs ]
-- union in the live regs from all the jump destinations of this
-- instruction.
@@ -1057,14 +1062,91 @@ liveness1 platform liveregs blockmap (LiveInstr instr _)
targetLiveRegs target
= case mapLookup target blockmap of
Just ra -> ra
- Nothing -> emptyUniqSet
-
- live_from_branch = unionManyUniqSets (map targetLiveRegs targets)
-
- liveregs_br = liveregs1 `unionUniqSets` live_from_branch
+ Nothing -> noRegs
-- registers that are live only in the branch targets should
-- be listed as dying here.
- live_branch_only = live_from_branch `minusUniqSet` liveregs
- r_dying_br = (r_dying `unionUniqSets` live_branch_only)
- -- See Note [Unique Determinism and code generation]
+ live_from_branch = unionManyRegsMaxFmt (map targetLiveRegs targets)
+ liveregs_br = liveregs1 `unionRegsMaxFmt` live_from_branch
+ live_branch_only = live_from_branch `minusRegs` liveregs
+ r_dying_br = r_dying `unionRegsMaxFmt` live_branch_only
+ -- NB: we treat registers live in branches similar to any other
+ -- registers read by the instruction, so the logic here matches
+ -- the logic in the definition of 'r_dying' above.
+
+{- Note [Register formats in liveness analysis]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We keep track of which format each virtual register is live at, and make use
+of this information during liveness analysis.
+
+First, we do backwards liveness analysis:
+
+ (FmtBwd1) Take the larger format when computing registers live going backwards.
+
+ Suppose for example that we have:
+
+ <previous instructions>
+ movps %v0 %v1
+ movupd %v0 %v2
+
+ Here we read %v0 both at format F64 and F64x2, so we must consider it live
+ at format F64x2, going backwards, in the previous instructions.
+ Not doing so caused #26411.
+
+ (FmtBwd2) Only consider fully clobbered registers to be dead going backwards.
+
+ Consider for example the liveness of %v0 going backwards in the following
+ instruction block:
+
+ movlhps %v5 %v0 -- write the upper F64 of %v0
+ movupd %v1 %v2 -- some unrelated instruction
+ movsd %v3 %v0 -- write the lower F64 of %v0
+ movupd %v0 %v4 -- read %v0 at format F64x2
+
+ We must not consider %v0 to be dead going backwards from 'movsd %v3 %v0'.
+ If we do, that means we think %v0 is dead during 'movupd %v1 %v2', and thus
+ that we can assign both %v0 and %v2 to the same real register. However, this
+ would be catastrophic, as 'movupd %v1 %v2' would then clobber the data
+ written to '%v0' in 'movlhps %v5 %v0'.
+
+ Wrinkle [Don't allow scalar partial writes]
+
+ We don't allow partial writes within scalar registers, for many reasons:
+
+ - partial writes can cause partial register stalls, which can have
+ disastrous performance implications (as seen in #20405)
+ - partial writes makes register allocation more difficult, as they can
+ require preserving the contents of a register across many instructions,
+ as in:
+
+ mulw %v0 -- 32-bit write to %rax
+ <many instructions>
+ mulb %v1 -- 16-bit partial write to %rax
+
+ The current register allocator is not equipped for spilling real
+ registers (only virtual registers), which means that e.g. on i386 we
+ end up with only 2 allocatable real GP registers for <many instructions>,
+ which is insufficient for instructions that require 3 registers.
+
+ We could allow this to be customised depending on the architecture, but
+ currently we simply never allow scalar partial writes.
+
+The forwards analysis is a bit simpler:
+
+ (FmtFwd1) Remove without considering format when dead going forwards.
+
+ If a register is no longer read after an instruction, then it is dead
+ going forwards. The format doesn't matter.
+
+ (FmtFwd2) Consider all writes as making a register dead going forwards.
+
+ If we write to the lower 64 bits of a 128 bit register, we don't currently
+ have a way to say "the lower 64 bits are dead but the top 64 bits are still live".
+ We would need a notion of partial register, similar to 'VirtualRegHi' for
+ the top 32 bits of a I32x2 virtual register.
+
+ As a result, the current approach is to consider the entire register to
+ be dead. This might cause us to unnecessarily spill/reload an entire vector
+ register to avoid its lower bits getting clobbered even though later
+ instructions might only care about its upper bits.
+-}
=====================================
compiler/GHC/CmmToAsm/Reg/Regs.hs
=====================================
@@ -0,0 +1,119 @@
+{-# LANGUAGE DerivingStrategies #-}
+
+module GHC.CmmToAsm.Reg.Regs (
+ Regs(..),
+ noRegs,
+ addRegMaxFmt, addRegsMaxFmt,
+ mkRegsMaxFmt,
+ minusCoveredRegs,
+ minusRegs,
+ unionRegsMaxFmt,
+ unionManyRegsMaxFmt,
+ intersectRegsMaxFmt,
+ shrinkingRegs,
+ mapRegs,
+ elemRegs, lookupReg,
+
+ ) where
+
+import GHC.Prelude
+
+import GHC.Platform.Reg ( Reg )
+import GHC.CmmToAsm.Format ( Format, RegWithFormat(..), isVecFormat )
+
+import GHC.Utils.Outputable ( Outputable )
+import GHC.Types.Unique ( Uniquable(..) )
+import GHC.Types.Unique.Set
+
+import Data.Coerce ( coerce )
+
+-----------------------------------------------------------------------------
+
+-- | A set of registers, with their respective formats, mostly for use in
+-- register liveness analysis. See Note [Register formats in liveness analysis]
+-- in GHC.CmmToAsm.Reg.Liveness.
+newtype Regs = Regs { getRegs :: UniqSet RegWithFormat }
+ deriving newtype (Eq, Outputable)
+
+maxRegWithFormat :: RegWithFormat -> RegWithFormat -> RegWithFormat
+maxRegWithFormat r1@(RegWithFormat _ fmt1) r2@(RegWithFormat _ fmt2)
+ = if fmt1 >= fmt2
+ then r1
+ else r2
+ -- Re-using one of the arguments avoids allocating a new 'RegWithFormat',
+ -- compared with returning 'RegWithFormat r1 (max fmt1 fmt2)'.
+
+noRegs :: Regs
+noRegs = Regs emptyUniqSet
+
+addRegsMaxFmt :: Regs -> [RegWithFormat] -> Regs
+addRegsMaxFmt = foldl' addRegMaxFmt
+
+mkRegsMaxFmt :: [RegWithFormat] -> Regs
+mkRegsMaxFmt = addRegsMaxFmt noRegs
+
+addRegMaxFmt :: Regs -> RegWithFormat -> Regs
+addRegMaxFmt = coerce $ strictAddOneToUniqSet_C maxRegWithFormat
+ -- Don't build up thunks when combining with 'maxRegWithFormat'
+
+-- | Remove 2nd argument registers from the 1st argument, but only
+-- if the format in the second argument is at least as large as the format
+-- in the first argument.
+minusCoveredRegs :: Regs -> Regs -> Regs
+minusCoveredRegs = coerce $ minusUniqSet_C f
+ where
+ f :: RegWithFormat -> RegWithFormat -> Maybe RegWithFormat
+ f r1@(RegWithFormat _ fmt1) (RegWithFormat _ fmt2) =
+ if fmt2 >= fmt1
+ ||
+ not ( isVecFormat fmt1 )
+ -- See Wrinkle [Don't allow scalar partial writes]
+ -- in Note [Register formats in liveness analysis] in GHC.CmmToAsm.Reg.Liveness.
+ then Nothing
+ else Just r1
+
+-- | Remove 2nd argument registers from the 1st argument, regardless of format.
+--
+-- See also 'minusCoveredRegs', which looks at the formats.
+minusRegs :: Regs -> Regs -> Regs
+minusRegs = coerce $ minusUniqSet @RegWithFormat
+
+unionRegsMaxFmt :: Regs -> Regs -> Regs
+unionRegsMaxFmt = coerce $ strictUnionUniqSets_C maxRegWithFormat
+ -- Don't build up thunks when combining with 'maxRegWithFormat'
+
+unionManyRegsMaxFmt :: [Regs] -> Regs
+unionManyRegsMaxFmt = coerce $ strictUnionManyUniqSets_C maxRegWithFormat
+ -- Don't build up thunks when combining with 'maxRegWithFormat'
+
+intersectRegsMaxFmt :: Regs -> Regs -> Regs
+intersectRegsMaxFmt = coerce $ strictIntersectUniqSets_C maxRegWithFormat
+ -- Don't build up thunks when combining with 'maxRegWithFormat'
+
+-- | Computes the set of registers in both arguments whose size is smaller in
+-- the second argument than in the first.
+shrinkingRegs :: Regs -> Regs -> Regs
+shrinkingRegs = coerce $ minusUniqSet_C f
+ where
+ f :: RegWithFormat -> RegWithFormat -> Maybe RegWithFormat
+ f (RegWithFormat _ fmt1) r2@(RegWithFormat _ fmt2)
+ | fmt2 < fmt1
+ = Just r2
+ | otherwise
+ = Nothing
+
+-- | Map a function that may change the 'Unique' of the register,
+-- which entails going via lists.
+--
+-- See Note [UniqSet invariant] in GHC.Types.Unique.Set.
+mapRegs :: (Reg -> Reg) -> Regs -> Regs
+mapRegs f (Regs live) =
+ Regs $
+ mapUniqSet (\ (RegWithFormat r fmt) -> RegWithFormat (f r) fmt) live
+
+elemRegs :: Reg -> Regs -> Bool
+elemRegs r (Regs live) = elemUniqSet_Directly (getUnique r) live
+
+lookupReg :: Reg -> Regs -> Maybe Format
+lookupReg r (Regs live) =
+ regWithFormat_format <$> lookupUniqSet_Directly live (getUnique r)
=====================================
compiler/GHC/CmmToAsm/Reg/Target.hs
=====================================
@@ -15,7 +15,6 @@ module GHC.CmmToAsm.Reg.Target (
targetMkVirtualReg,
targetRegDotColor,
targetClassOfReg,
- mapRegFormatSet,
)
where
@@ -27,10 +26,8 @@ import GHC.Platform.Reg.Class
import GHC.CmmToAsm.Format
import GHC.Utils.Outputable
-import GHC.Utils.Misc
import GHC.Utils.Panic
import GHC.Types.Unique
-import GHC.Types.Unique.Set
import GHC.Platform
import qualified GHC.CmmToAsm.X86.Regs as X86
@@ -142,6 +139,3 @@ targetClassOfReg platform reg
= case reg of
RegVirtual vr -> classOfVirtualReg (platformArch platform) vr
RegReal rr -> targetClassOfRealReg platform rr
-
-mapRegFormatSet :: HasDebugCallStack => (Reg -> Reg) -> UniqSet RegWithFormat -> UniqSet RegWithFormat
-mapRegFormatSet f = mapUniqSet (\ ( RegWithFormat r fmt ) -> RegWithFormat ( f r ) fmt)
=====================================
compiler/GHC/CmmToAsm/X86/CodeGen.hs
=====================================
@@ -54,7 +54,9 @@ import GHC.CmmToAsm.CFG
import GHC.CmmToAsm.Format
import GHC.CmmToAsm.Config
import GHC.Platform.Reg
+import GHC.CmmToAsm.Reg.Target (targetClassOfReg)
import GHC.Platform
+import GHC.Platform.Reg.Class.Unified (RegClass(..))
-- Our intermediate code:
import GHC.Types.Basic
@@ -4697,7 +4699,14 @@ genCCall64 addr conv dest_regs args = do
-- It's not safe to omit this assignment, even if the number
-- of SSE2 regs in use is zero. If %al is larger than 8
-- on entry to a varargs function, seg faults ensue.
- nb_sse_regs_used = count (isFloatFormat . regWithFormat_format) arg_regs_used
+ is_sse_reg (RegWithFormat r _) =
+ -- NB: use 'targetClassOfRealReg' to compute whether this is an SSE
+ -- register or not, as we may have decided to e.g. store a 64-bit
+ -- integer in an xmm register.
+ case targetClassOfReg platform r of
+ RcFloatOrVector -> True
+ RcInteger -> False
+ nb_sse_regs_used = count is_sse_reg arg_regs_used
assign_eax_sse_regs
= unitOL (MOV II32 (OpImm (ImmInt nb_sse_regs_used)) (OpReg eax))
-- Note: we do this on Windows as well. It's not entirely clear why
=====================================
compiler/GHC/CmmToAsm/X86/Instr.hs
=====================================
@@ -114,9 +114,12 @@ data Instr
-- | X86 scalar move instruction.
--
- -- When used at a vector format, only moves the lower 64 bits of data;
- -- the rest of the data in the destination may either be zeroed or
- -- preserved, depending on the specific format and operands.
+ -- The format is the format the destination is written to. For an XMM
+ -- register, using a scalar format means that we don't care about the
+ -- upper bits, while using a vector format means that we care about the
+ -- upper bits, even though we are only writing to the lower bits.
+ --
+ -- See also Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear.
| MOV Format Operand Operand
-- N.B. Due to AT&T assembler quirks, when used with 'II64'
-- 'Format' immediate source and memory target operand, the source
@@ -410,18 +413,27 @@ data FMAPermutation = FMA132 | FMA213 | FMA231
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr platform instr
= case instr of
- MOV fmt src dst
+
+ -- Recall that MOV is always a scalar move instruction, but when the destination
+ -- is an XMM register, we make the distinction between:
+ --
+ -- - a scalar format, meaning that from now on we no longer care about the top bits
+ -- of the register, and
+ -- - a vector format, meaning that we still care about what's in the high bits.
+ --
+ -- See Note [Allocated register formats] in GHC.CmmToAsm.Reg.Linear.
+ MOV dst_fmt src dst
-- MOVSS/MOVSD preserve the upper half of vector registers,
-- but only for reg-2-reg moves
- | VecFormat _ sFmt <- fmt
+ | VecFormat _ sFmt <- dst_fmt
, isFloatScalarFormat sFmt
, OpReg {} <- src
, OpReg {} <- dst
- -> usageRM fmt src dst
+ -> usageRM dst_fmt src dst
-- other MOV instructions zero any remaining upper part of the destination
-- (largely to avoid partial register stalls)
| otherwise
- -> usageRW fmt src dst
+ -> usageRW dst_fmt src dst
MOVD fmt1 fmt2 src dst ->
-- NB: MOVD and MOVQ always zero any remaining upper part of destination,
-- so the destination is "written" not "modified".
@@ -437,7 +449,7 @@ regUsageOfInstr platform instr
IMUL fmt src dst -> usageRM fmt src dst
-- Result of IMULB will be in just in %ax
- IMUL2 II8 src -> mkRU (mk II8 eax:use_R II8 src []) [mk II8 eax]
+ IMUL2 II8 src -> mkRU (mk II8 eax:use_R II8 src []) [mk II16 eax]
-- Result of IMUL for wider values, will be split between %dx/%edx/%rdx and
-- %ax/%eax/%rax.
IMUL2 fmt src -> mkRU (mk fmt eax:use_R fmt src []) [mk fmt eax,mk fmt edx]
=====================================
compiler/GHC/Types/Unique/FM.hs
=====================================
@@ -38,6 +38,7 @@ module GHC.Types.Unique.FM (
listToUFM_C,
listToIdentityUFM,
addToUFM,addToUFM_C,addToUFM_Acc,addToUFM_L,
+ strictAddToUFM_C,
addListToUFM,addListToUFM_C,
addToUFM_Directly,
addListToUFM_Directly,
@@ -62,6 +63,7 @@ module GHC.Types.Unique.FM (
minusUFM_C,
intersectUFM,
intersectUFM_C,
+ strictIntersectUFM_C,
disjointUFM,
equalKeysUFM,
diffUFM,
@@ -178,6 +180,16 @@ addToUFM_C
addToUFM_C f (UFM m) k v =
UFM (M.insertWith (flip f) (getKey $ getUnique k) v m)
+strictAddToUFM_C
+ :: Uniquable key
+ => (elt -> elt -> elt) -- ^ old -> new -> result
+ -> UniqFM key elt -- ^ old
+ -> key -> elt -- ^ new
+ -> UniqFM key elt -- ^ result
+-- Arguments of combining function of MS.insertWith and strictAddToUFM_C are flipped.
+strictAddToUFM_C f (UFM m) k v =
+ UFM (MS.insertWith (flip f) (getKey $ getUnique k) v m)
+
addToUFM_Acc
:: Uniquable key
=> (elt -> elts -> elts) -- Add to existing
@@ -391,6 +403,13 @@ intersectUFM_C
-> UniqFM key elt3
intersectUFM_C f (UFM x) (UFM y) = UFM (M.intersectionWith f x y)
+strictIntersectUFM_C
+ :: (elt1 -> elt2 -> elt3)
+ -> UniqFM key elt1
+ -> UniqFM key elt2
+ -> UniqFM key elt3
+strictIntersectUFM_C f (UFM x) (UFM y) = UFM (MS.intersectionWith f x y)
+
disjointUFM :: UniqFM key elt1 -> UniqFM key elt2 -> Bool
disjointUFM (UFM x) (UFM y) = M.disjoint x y
=====================================
compiler/GHC/Types/Unique/Set.hs
=====================================
@@ -19,12 +19,14 @@ module GHC.Types.Unique.Set (
emptyUniqSet,
unitUniqSet,
mkUniqSet,
- addOneToUniqSet, addListToUniqSet,
+ addOneToUniqSet, addListToUniqSet, strictAddOneToUniqSet_C,
delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet,
delListFromUniqSet_Directly,
unionUniqSets, unionManyUniqSets,
- minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM,
- intersectUniqSets,
+ strictUnionUniqSets_C, strictUnionManyUniqSets_C,
+ minusUniqSet, minusUniqSet_C,
+ uniqSetMinusUFM, uniqSetMinusUDFM,
+ intersectUniqSets, strictIntersectUniqSets_C,
disjointUniqSets,
restrictUniqSetToUFM,
uniqSetAny, uniqSetAll,
@@ -109,6 +111,10 @@ addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet = foldl' addOneToUniqSet
{-# INLINEABLE addListToUniqSet #-}
+strictAddOneToUniqSet_C :: Uniquable a => (a -> a -> a) -> UniqSet a -> a -> UniqSet a
+strictAddOneToUniqSet_C f (UniqSet set) x =
+ UniqSet (strictAddToUFM_C f set x x)
+
delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
delOneFromUniqSet (UniqSet s) a = UniqSet (delFromUFM s a)
@@ -127,15 +133,29 @@ delListFromUniqSet_Directly (UniqSet s) l =
unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
unionUniqSets (UniqSet s) (UniqSet t) = UniqSet (plusUFM s t)
+strictUnionUniqSets_C :: (a -> a -> a) -> UniqSet a -> UniqSet a -> UniqSet a
+strictUnionUniqSets_C f (UniqSet s) (UniqSet t) =
+ UniqSet (strictPlusUFM_C f s t)
+
unionManyUniqSets :: [UniqSet a] -> UniqSet a
unionManyUniqSets = foldl' (flip unionUniqSets) emptyUniqSet
+strictUnionManyUniqSets_C :: (a -> a -> a) -> [UniqSet a] -> UniqSet a
+strictUnionManyUniqSets_C f = foldl' (flip (strictUnionUniqSets_C f)) emptyUniqSet
+
minusUniqSet :: UniqSet a -> UniqSet a -> UniqSet a
minusUniqSet (UniqSet s) (UniqSet t) = UniqSet (minusUFM s t)
+minusUniqSet_C :: (a -> a -> Maybe a) -> UniqSet a -> UniqSet a -> UniqSet a
+minusUniqSet_C f (UniqSet s) (UniqSet t) = UniqSet (minusUFM_C f s t)
+
intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
intersectUniqSets (UniqSet s) (UniqSet t) = UniqSet (intersectUFM s t)
+strictIntersectUniqSets_C :: (a -> a -> a) -> UniqSet a -> UniqSet a -> UniqSet a
+strictIntersectUniqSets_C f (UniqSet s) (UniqSet t) =
+ UniqSet (strictIntersectUFM_C f s t)
+
disjointUniqSets :: UniqSet a -> UniqSet a -> Bool
disjointUniqSets (UniqSet s) (UniqSet t) = disjointUFM s t
=====================================
compiler/ghc.cabal.in
=====================================
@@ -310,6 +310,7 @@ Library
GHC.CmmToAsm.Reg.Linear.X86
GHC.CmmToAsm.Reg.Linear.X86_64
GHC.CmmToAsm.Reg.Liveness
+ GHC.CmmToAsm.Reg.Regs
GHC.CmmToAsm.Reg.Target
GHC.CmmToAsm.Reg.Utils
GHC.CmmToAsm.RV64
=====================================
testsuite/tests/simd/should_run/T26411.hs
=====================================
@@ -0,0 +1,57 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module Main where
+
+import GHC.Exts
+
+data DoubleX32 = DoubleX32
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+
+doubleX32ToList :: DoubleX32 -> [Double]
+doubleX32ToList (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = a v0 . a v1 . a v2 . a v3 . a v4 . a v5 . a v6 . a v7 . a v8 . a v9 . a v10 . a v11 . a v12 . a v13 . a v14 . a v15 $ []
+ where
+ a v xs = case unpackDoubleX2# v of
+ (# x0, x1 #) -> D# x0 : D# x1 : xs
+
+doubleX32FromList :: [Double] -> DoubleX32
+doubleX32FromList [D# x0, D# x1, D# x2, D# x3, D# x4, D# x5, D# x6, D# x7, D# x8, D# x9, D# x10, D# x11, D# x12, D# x13, D# x14, D# x15, D# x16, D# x17, D# x18, D# x19, D# x20, D# x21, D# x22, D# x23, D# x24, D# x25, D# x26, D# x27, D# x28, D# x29, D# x30, D# x31]
+ = DoubleX32
+ (packDoubleX2# (# x0, x1 #)) (packDoubleX2# (# x2, x3 #)) (packDoubleX2# (# x4, x5 #)) (packDoubleX2# (# x6, x7 #))
+ (packDoubleX2# (# x8, x9 #)) (packDoubleX2# (# x10, x11 #)) (packDoubleX2# (# x12, x13 #)) (packDoubleX2# (# x14, x15 #))
+ (packDoubleX2# (# x16, x17 #)) (packDoubleX2# (# x18, x19 #)) (packDoubleX2# (# x20, x21 #)) (packDoubleX2# (# x22, x23 #))
+ (packDoubleX2# (# x24, x25 #)) (packDoubleX2# (# x26, x27 #)) (packDoubleX2# (# x28, x29 #)) (packDoubleX2# (# x30, x31 #))
+
+negateDoubleX32 :: DoubleX32 -> DoubleX32
+negateDoubleX32 (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = DoubleX32
+ (negateDoubleX2# v0) (negateDoubleX2# v1) (negateDoubleX2# v2) (negateDoubleX2# v3)
+ (negateDoubleX2# v4) (negateDoubleX2# v5) (negateDoubleX2# v6) (negateDoubleX2# v7)
+ (negateDoubleX2# v8) (negateDoubleX2# v9) (negateDoubleX2# v10) (negateDoubleX2# v11)
+ (negateDoubleX2# v12) (negateDoubleX2# v13) (negateDoubleX2# v14) (negateDoubleX2# v15)
+
+recipDoubleX2# :: DoubleX2# -> DoubleX2#
+recipDoubleX2# v = divideDoubleX2# (broadcastDoubleX2# 1.0##) v
+{-# INLINE recipDoubleX2# #-}
+
+recipDoubleX32 :: DoubleX32 -> DoubleX32
+recipDoubleX32 (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = DoubleX32
+ (recipDoubleX2# v0) (recipDoubleX2# v1) (recipDoubleX2# v2) (recipDoubleX2# v3)
+ (recipDoubleX2# v4) (recipDoubleX2# v5) (recipDoubleX2# v6) (recipDoubleX2# v7)
+ (recipDoubleX2# v8) (recipDoubleX2# v9) (recipDoubleX2# v10) (recipDoubleX2# v11)
+ (recipDoubleX2# v12) (recipDoubleX2# v13) (recipDoubleX2# v14) (recipDoubleX2# v15)
+
+main :: IO ()
+main = do
+ let a = doubleX32FromList [0..31]
+ b = negateDoubleX32 a
+ c = recipDoubleX32 a
+ print $ doubleX32ToList b
+ putStrLn $ if doubleX32ToList b == map negate [0..31] then "OK" else "Wrong"
+ print $ doubleX32ToList c
+ putStrLn $ if doubleX32ToList c == map recip [0..31] then "OK" else "Wrong"
=====================================
testsuite/tests/simd/should_run/T26411.stdout
=====================================
@@ -0,0 +1,4 @@
+[-0.0,-1.0,-2.0,-3.0,-4.0,-5.0,-6.0,-7.0,-8.0,-9.0,-10.0,-11.0,-12.0,-13.0,-14.0,-15.0,-16.0,-17.0,-18.0,-19.0,-20.0,-21.0,-22.0,-23.0,-24.0,-25.0,-26.0,-27.0,-28.0,-29.0,-30.0,-31.0]
+OK
+[Infinity,1.0,0.5,0.3333333333333333,0.25,0.2,0.16666666666666666,0.14285714285714285,0.125,0.1111111111111111,0.1,9.090909090909091e-2,8.333333333333333e-2,7.692307692307693e-2,7.142857142857142e-2,6.666666666666667e-2,6.25e-2,5.8823529411764705e-2,5.555555555555555e-2,5.263157894736842e-2,5.0e-2,4.7619047619047616e-2,4.5454545454545456e-2,4.3478260869565216e-2,4.1666666666666664e-2,4.0e-2,3.8461538461538464e-2,3.7037037037037035e-2,3.571428571428571e-2,3.4482758620689655e-2,3.333333333333333e-2,3.225806451612903e-2]
+OK
=====================================
testsuite/tests/simd/should_run/T26411b.hs
=====================================
@@ -0,0 +1,73 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module Main (main) where
+
+import GHC.Exts
+
+data DoubleX32 = DoubleX32
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+ DoubleX2# DoubleX2# DoubleX2# DoubleX2#
+
+doubleX32ToList :: DoubleX32 -> [Double]
+doubleX32ToList (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = a v0 . a v1 . a v2 . a v3 . a v4 . a v5 . a v6 . a v7 . a v8 . a v9 . a v10 . a v11 . a v12 . a v13 . a v14 . a v15 $ []
+ where
+ a v xs = case unpackDoubleX2# v of
+ (# x0, x1 #) -> D# x0 : D# x1 : xs
+{-# INLINE doubleX32ToList #-}
+
+doubleX32FromList :: [Double] -> DoubleX32
+doubleX32FromList [D# x0, D# x1, D# x2, D# x3, D# x4, D# x5, D# x6, D# x7, D# x8, D# x9, D# x10, D# x11, D# x12, D# x13, D# x14, D# x15, D# x16, D# x17, D# x18, D# x19, D# x20, D# x21, D# x22, D# x23, D# x24, D# x25, D# x26, D# x27, D# x28, D# x29, D# x30, D# x31]
+ = DoubleX32
+ (packDoubleX2# (# x0, x1 #)) (packDoubleX2# (# x2, x3 #)) (packDoubleX2# (# x4, x5 #)) (packDoubleX2# (# x6, x7 #))
+ (packDoubleX2# (# x8, x9 #)) (packDoubleX2# (# x10, x11 #)) (packDoubleX2# (# x12, x13 #)) (packDoubleX2# (# x14, x15 #))
+ (packDoubleX2# (# x16, x17 #)) (packDoubleX2# (# x18, x19 #)) (packDoubleX2# (# x20, x21 #)) (packDoubleX2# (# x22, x23 #))
+ (packDoubleX2# (# x24, x25 #)) (packDoubleX2# (# x26, x27 #)) (packDoubleX2# (# x28, x29 #)) (packDoubleX2# (# x30, x31 #))
+{-# NOINLINE doubleX32FromList #-}
+
+broadcastDoubleX32 :: Double -> DoubleX32
+broadcastDoubleX32 (D# x)
+ = let !v = broadcastDoubleX2# x
+ in DoubleX32 v v v v v v v v v v v v v v v v
+{-# INLINE broadcastDoubleX32 #-}
+
+negateDoubleX32 :: DoubleX32 -> DoubleX32
+negateDoubleX32 (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = DoubleX32
+ (negateDoubleX2# v0) (negateDoubleX2# v1) (negateDoubleX2# v2) (negateDoubleX2# v3)
+ (negateDoubleX2# v4) (negateDoubleX2# v5) (negateDoubleX2# v6) (negateDoubleX2# v7)
+ (negateDoubleX2# v8) (negateDoubleX2# v9) (negateDoubleX2# v10) (negateDoubleX2# v11)
+ (negateDoubleX2# v12) (negateDoubleX2# v13) (negateDoubleX2# v14) (negateDoubleX2# v15)
+{-# NOINLINE negateDoubleX32 #-}
+
+recipDoubleX2# :: DoubleX2# -> DoubleX2#
+recipDoubleX2# v = divideDoubleX2# (broadcastDoubleX2# 1.0##) v
+{-# NOINLINE recipDoubleX2# #-}
+
+recipDoubleX32 :: DoubleX32 -> DoubleX32
+recipDoubleX32 (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = DoubleX32
+ (recipDoubleX2# v0) (recipDoubleX2# v1) (recipDoubleX2# v2) (recipDoubleX2# v3)
+ (recipDoubleX2# v4) (recipDoubleX2# v5) (recipDoubleX2# v6) (recipDoubleX2# v7)
+ (recipDoubleX2# v8) (recipDoubleX2# v9) (recipDoubleX2# v10) (recipDoubleX2# v11)
+ (recipDoubleX2# v12) (recipDoubleX2# v13) (recipDoubleX2# v14) (recipDoubleX2# v15)
+{-# NOINLINE recipDoubleX32 #-}
+
+divideDoubleX32 :: DoubleX32 -> DoubleX32 -> DoubleX32
+divideDoubleX32 (DoubleX32 u0 u1 u2 u3 u4 u5 u6 u7 u8 u9 u10 u11 u12 u13 u14 u15) (DoubleX32 v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)
+ = DoubleX32
+ (divideDoubleX2# u0 v0) (divideDoubleX2# u1 v1) (divideDoubleX2# u2 v2) (divideDoubleX2# u3 v3)
+ (divideDoubleX2# u4 v4) (divideDoubleX2# u5 v5) (divideDoubleX2# u6 v6) (divideDoubleX2# u7 v7)
+ (divideDoubleX2# u8 v8) (divideDoubleX2# u9 v9) (divideDoubleX2# u10 v10) (divideDoubleX2# u11 v11)
+ (divideDoubleX2# u12 v12) (divideDoubleX2# u13 v13) (divideDoubleX2# u14 v14) (divideDoubleX2# u15 v15)
+{-# INLINE divideDoubleX32 #-}
+
+main :: IO ()
+main = do
+ let a = doubleX32FromList [0..31]
+ b = divideDoubleX32 (broadcastDoubleX32 1.0) a
+ print $ doubleX32ToList b
+ putStrLn $ if doubleX32ToList b == map recip [0..31] then "OK" else "Wrong"
=====================================
testsuite/tests/simd/should_run/T26411b.stdout
=====================================
@@ -0,0 +1,2 @@
+[Infinity,1.0,0.5,0.3333333333333333,0.25,0.2,0.16666666666666666,0.14285714285714285,0.125,0.1111111111111111,0.1,9.090909090909091e-2,8.333333333333333e-2,7.692307692307693e-2,7.142857142857142e-2,6.666666666666667e-2,6.25e-2,5.8823529411764705e-2,5.555555555555555e-2,5.263157894736842e-2,5.0e-2,4.7619047619047616e-2,4.5454545454545456e-2,4.3478260869565216e-2,4.1666666666666664e-2,4.0e-2,3.8461538461538464e-2,3.7037037037037035e-2,3.571428571428571e-2,3.4482758620689655e-2,3.333333333333333e-2,3.225806451612903e-2]
+OK
=====================================
testsuite/tests/simd/should_run/all.T
=====================================
@@ -89,6 +89,7 @@ test('simd012', [], compile_and_run, [''])
test('simd013',
[ req_c
, unless(arch('x86_64'), skip) # because the C file uses Intel intrinsics
+ , extra_ways(["optasm"]) # #26526 demonstrated a bug in the optasm way
],
compile_and_run, ['simd013C.c'])
test('simd014',
@@ -145,6 +146,8 @@ test('T22187_run', [],compile_and_run,[''])
test('T25062_V16', [], compile_and_run, [''])
test('T25561', [], compile_and_run, [''])
test('T26542', [], compile_and_run, [''])
+test('T26411', [], compile_and_run, [''])
+test('T26411b', [], compile_and_run, ['-O'])
# Even if the CPU we run on doesn't support *executing* those tests we should try to
# compile them.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a2b43e3395902e88ec371c98cdb4a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a2b43e3395902e88ec371c98cdb4a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
18 Dec '25
Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC
Commits:
a2e35bf3 by Simon Peyton Jones at 2025-12-18T17:42:44+00:00
More wibbles
- - - - -
14 changed files:
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Types/Constraint.hs
- testsuite/tests/pmcheck/should_compile/T15753c.hs
- + testsuite/tests/pmcheck/should_compile/T15753c.stderr
- testsuite/tests/pmcheck/should_compile/T15753d.hs
- + testsuite/tests/pmcheck/should_compile/T15753d.stderr
- + testsuite/tests/pmcheck/should_compile/T22652a.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T5236.stderr
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
compiler/GHC/Tc/Errors.hs
=====================================
@@ -1509,11 +1509,12 @@ coercion.
mkIrredErr :: SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM SolverReport
mkIrredErr ctxt items
= do { (ctxt, binds, item1) <- relevantBindings True ctxt item1
- ; couldNotDeduceErr <- mkCouldNotDeduceErr (getUserGivens ctxt) (item1 :| others) Nothing
+ ; couldNotDeduceErr <- mkCouldNotDeduceErr useful_givens (item1 :| others) Nothing
; let msg = important ctxt $ mkPlainMismatchMsg couldNotDeduceErr
; return $ add_relevant_bindings binds msg }
where
item1:|others = tryFilter (not . ei_suppress) items
+ useful_givens = getUsefulGivens ctxt item1
{- Note [Constructing Hole Errors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1694,8 +1695,8 @@ validHoleFits ctxt@(CEC { cec_encl = implics
givenConstraints :: SolverReportErrCtxt -> [(Type, RealSrcSpan)]
-- Returned outermost first
-- See Note [Constraints include ...]
-givenConstraints ctxt
- = do { implic@Implic{ ic_given = given } <- getUserGivens ctxt
+givenConstraints (CEC { cec_encl = implics })
+ = do { implic@Implic{ ic_given = given } <- getGivensFromImplics implics
; constraint <- given
; return (varType constraint, getCtLocEnvLoc (ic_env implic)) }
@@ -2105,6 +2106,7 @@ eqInfoMsgs ty1 ty2
misMatchOrCND :: SolverReportErrCtxt -> ErrorItem
-> TcType -> TcType -> TcM MismatchMsg
+-- Make a message for a failed equality constraint (t1 ~ t2)
-- If oriented then ty1 is actual, ty2 is expected
misMatchOrCND ctxt item ty1 ty2
| ei_insoluble item -- See Note [Insoluble mis-match]
@@ -2120,7 +2122,8 @@ misMatchOrCND ctxt item ty1 ty2
where
level = ctLocTypeOrKind_maybe (errorItemCtLoc item) `orElse` TypeLevel
- givens = [ given | given <- getUserGivens ctxt, ic_given_eqs given /= NoGivenEqs ]
+ givens = [ given | given <- getUsefulGivens ctxt item
+ , ic_given_eqs given /= NoGivenEqs ]
-- Keep only UserGivens that have some equalities.
-- See Note [Suppress redundant givens during error reporting]
@@ -2302,7 +2305,8 @@ mkQCErr :: HasDebugCallStack => SolverReportErrCtxt -> NonEmpty ErrorItem -> TcM
mkQCErr ctxt items
| item1 :| _ <- tryFilter (not . ei_suppress) items
-- Ignore multiple qc-errors on the same line
- = do { couldNotDeduceErr <- mkCouldNotDeduceErr (getUserGivens ctxt) (item1 :| []) Nothing
+ = do { couldNotDeduceErr <- mkCouldNotDeduceErr (getUsefulGivens ctxt item1)
+ (item1 :| []) Nothing
; return $ important ctxt $ mkPlainMismatchMsg couldNotDeduceErr }
@@ -2332,7 +2336,8 @@ mkDictErr ctxt orig_items@(item1 :| others)
where
items = tryFilter (not . ei_suppress) orig_items
- no_givens = null (getUserGivens ctxt)
+ useful_givens = getUsefulGivens ctxt item1
+ no_givens = null useful_givens
is_no_inst (item, (matches, unifiers, _))
= no_givens
@@ -2471,9 +2476,9 @@ mkCouldNotDeduceErr
-> NonEmpty ErrorItem
-> Maybe CND_ExpectedActual
-> TcM MismatchMsg
-mkCouldNotDeduceErr user_givens items@(item :| _) mb_ea
+mkCouldNotDeduceErr useful_givens items@(item :| _) mb_ea
= do { mb_noBuiltinInst_info <- getNoBuiltinInstMsg item
- ; return $ CouldNotDeduce user_givens items mb_ea mb_noBuiltinInst_info }
+ ; return $ CouldNotDeduce useful_givens items mb_ea mb_noBuiltinInst_info }
getNoBuiltinInstMsg :: ErrorItem -> TcM (Maybe NoBuiltinInstanceMsg)
getNoBuiltinInstMsg item =
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -4178,7 +4178,7 @@ pprTcSolverReportMsg _ (ExpectingMoreArguments n thing) =
| n == 1 = text "more argument to"
| otherwise = text "more arguments to" -- n > 1
pprTcSolverReportMsg ctxt (UnboundImplicitParams (item :| items)) =
- let givens = getUserGivens ctxt
+ let givens = getUsefulGivens ctxt item
in if null givens
then addArising (errorItemCtLoc item) $
sep [ text "Unbound implicit parameter" <> plural preds
@@ -4233,7 +4233,7 @@ pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
(ambig_kvs, ambig_tvs) = ambigTkvsOfTy pred
ambigs = ambig_kvs ++ ambig_tvs
has_ambigs = not (null ambigs)
- useful_givens = discardProvCtxtGivens orig (getUserGivensFromImplics implics)
+ useful_givens = getUsefulGivens ctxt item
-- useful_givens are the enclosing implications with non-empty givens,
-- modulo the horrid discardProvCtxtGivens
lead_with_ambig = not (null ambigs)
@@ -4298,7 +4298,7 @@ pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
= empty
----------- Possible fixes ----------------
- ctxt_fixes = ctxtFixes has_ambigs pred implics
+ ctxt_fixes = ctxtFixes ctxt has_ambigs pred
drv_fixes = case orig of
DerivOrigin standalone -> [drv_fix standalone]
@@ -4332,7 +4332,7 @@ pprTcSolverReportMsg ctxt@(CEC {cec_encl = implics})
Just (_, tys) -> not (all isTyVarTy tys)
Nothing -> False
-pprTcSolverReportMsg (CEC {cec_encl = implics}) (OverlappingInstances item matches unifiers) =
+pprTcSolverReportMsg ctxt (OverlappingInstances item matches unifiers) =
vcat
[ addArising ct_loc $
(text "Overlapping instances for"
@@ -4375,7 +4375,7 @@ pprTcSolverReportMsg (CEC {cec_encl = implics}) (OverlappingInstances item match
(clas, tys) = getClassPredTys pred
tyCoVars = tyCoVarsOfTypesList tys
famTyCons = filter isFamilyTyCon $ concatMap (nonDetEltsUniqSet . tyConsOfType) tys
- useful_givens = discardProvCtxtGivens orig (getUserGivensFromImplics implics)
+ useful_givens = getUsefulGivens ctxt item
matching_givens = mapMaybe matchable useful_givens
matchable implic@(Implic { ic_given = evvars, ic_info = skol_info })
= case ev_vars_matching of
@@ -4707,10 +4707,13 @@ pprMismatchMsg ctxt
| otherwise = vcat ( addArising ct_loc no_deduce_msg
: pp_from_givens useful_givens)
- ea_supplementary = case mb_ea of
- Nothing -> empty
- Just (CND_ExpectedActual level ty1 ty2) ->
- mk_supplementary_ea_msg ctxt level ty1 ty2 orig
+ ea_supplementary
+ | Just (CND_ExpectedActual level ty1 ty2) <- mb_ea
+ = mk_supplementary_ea_msg ctxt level ty1 ty2 orig
+ | Just InsolubleFunDepReason <- ei_m_reason item
+ = text "The functional dependencies arising from this constraint are insoluble"
+ | otherwise
+ = empty
ct_loc = errorItemCtLoc item
orig = ctLocOrigin ct_loc
@@ -5583,8 +5586,8 @@ show_fixes [] = empty
show_fixes (f:fs) = sep [ text "Possible fix:"
, nest 2 (vcat (f : map (text "or" <+>) fs))]
-ctxtFixes :: Bool -> PredType -> [Implication] -> [SDoc]
-ctxtFixes has_ambig_tvs pred implics
+ctxtFixes :: SolverReportErrCtxt -> Bool -> PredType -> [SDoc]
+ctxtFixes (CEC {cec_encl = implics}) has_ambig_tvs pred
| not has_ambig_tvs
, isTyVarClassPred pred -- Don't suggest adding (Eq T) to the context, say
, (skol:skols) <- usefulContext implics pred
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -62,7 +62,7 @@ module GHC.Tc.Errors.Types (
, SolverReport(..), SupplementaryInfo(..)
, SolverReportWithCtxt(..)
, SolverReportErrCtxt(..)
- , getUserGivens, discardProvCtxtGivens
+ , getUsefulGivens
, TcSolverReportMsg(..)
, CannotUnifyVariableReason(..)
, MismatchMsg(..)
@@ -5409,10 +5409,6 @@ data SolverReportErrCtxt
-- See Note [Suppressing error messages]
}
-getUserGivens :: SolverReportErrCtxt -> [UserGiven]
--- One item for each enclosing implication
-getUserGivens (CEC {cec_encl = implics}) = getUserGivensFromImplics implics
-
----------------------------------------------------------------------------
--
-- ErrorItem
@@ -5438,7 +5434,7 @@ data ErrorItem
, ei_loc :: CtLoc
, ei_m_reason :: Maybe CtIrredReason -- If this ErrorItem was made from a
-- CtIrred, this stores the reason
- , ei_insoluble :: Bool -- True if the constraint is defdinitely insoluble
+ , ei_insoluble :: Bool -- True if the constraint is definitely insoluble
-- Cache of `insolubleCt`
, ei_suppress :: Bool -- Suppress because of
@@ -5513,6 +5509,19 @@ message (showing both problems):
-}
+getUsefulGivens :: SolverReportErrCtxt -> ErrorItem -> [UserGiven]
+-- One item for each enclosing implication
+getUsefulGivens (CEC {cec_encl = implics}) item
+ | ei_insoluble item
+ = [] -- If the constraint is insoluble anyway, we won't try to solve it
+ -- from the inert Givens, so it's positively confusing to list them.
+ -- Otherwise we get "Can't deduce X from X".
+ | otherwise
+ = discardProvCtxtGivens orig $
+ getGivensFromImplics implics
+ where
+ orig = errorItemOrigin item
+
discardProvCtxtGivens :: CtOrigin -> [UserGiven] -> [UserGiven]
discardProvCtxtGivens orig givens -- See Note [discardProvCtxtGivens]
| ProvCtxtOrigin (PSB {psb_id = L _ name}) <- orig
=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -738,14 +738,15 @@ tcCheckGivens inerts given_ids
; mb_res <- tryM $ -- try_to_solve may throw an exception;
-- e.g. reduction stack overflow
- discardErrs $ -- An exception id not an error;
+ discardErrs $ -- An exception is not an error;
-- just means "not definitely unsat"
runTcSInerts inerts $
try_to_solve given_cts
-- If mb_res = Left err, solving threw an exception, e.g. reduction stack
-- overflow. So return the original incoming inerts to say "not definitely
- -- unsatisfiable".
+ -- unsatisfiable". See (CF3) in Note [Exploiting closed type families], and
+ -- test T15753c.
; let res = case mb_res of
Right res -> res
Left {} -> Just inerts
=====================================
compiler/GHC/Tc/Solver/FunDeps.hs
=====================================
@@ -523,7 +523,7 @@ tryEqFunDeps :: EqCt -> SolverStage ()
tryEqFunDeps work_item@(EqCt { eq_lhs = work_lhs
, eq_rhs = work_rhs
, eq_eq_rel = eq_rel })
- | NomEq <- eq_rel
+ | NomEq <- eq_rel -- Functional dependencies only work for nominal equalities
, TyFamLHS fam_tc work_args <- work_lhs -- We have F args ~N# rhs
= do { eqs_for_me <- simpleStage $ getInertFamEqsFor fam_tc work_args work_rhs
; simpleStage $ traceTcS "tryEqFunDeps" (ppr work_item $$ ppr eqs_for_me)
@@ -1071,7 +1071,12 @@ Key point: equations that are not relevant do not need to be considered for fund
And now we are back where we started -- loop.
We solve this by bumping the `ctLocDepth` in `solveFunDeps`, and imposing
- a depth bound. See the call to `bumpReductionDepth`.
+ a depth bound. See the call to `bumpReductionDepth`. If the depth limit
+ is exceeded we add an error message and fail in the monad.
+
+ Take care: when we are solving-for-unsatisfiability, in the pattern match
+ checker, we must carefully catch this failure: see the use of `tryM` in
+ `tcCheckGivens`.
(CF4) If one of the fundeps generated by interacting with the local equalities is
definitely insoluble (e.g. Int~Bool) then there is no point in continuing to
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -66,7 +66,7 @@ module GHC.Tc.Types.Constraint (
Implication(..), implicationPrototype, checkTelescopeSkol,
ImplicStatus(..), isInsolubleStatus, isSolvedStatus,
- UserGiven, getUserGivensFromImplics,
+ UserGiven, getGivensFromImplics,
HasGivenEqs(..), checkImplicationInvariants,
EvNeedSet(..), emptyEvNeedSet, unionEvNeedSet, extendEvNeedSet, delGivensFromEvNeedSet,
@@ -1637,10 +1637,10 @@ data HasGivenEqs -- See Note [HasGivenEqs]
type UserGiven = Implication
-getUserGivensFromImplics :: [Implication] -> [UserGiven]
+getGivensFromImplics :: [Implication] -> [UserGiven]
-- The argument [Implication] is innermost first;
-- the returned [UserGiven] is outermost first
-getUserGivensFromImplics implics
+getGivensFromImplics implics
= get [] implics
where
get :: [UserGiven] -> [Implication] -> [UserGiven]
=====================================
testsuite/tests/pmcheck/should_compile/T15753c.hs
=====================================
@@ -5,6 +5,11 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wincomplete-patterns #-}
+
+-- NB: After fixing #22652 this program right produces warnings
+-- because (F u1 u1 ~ Char) is unsatisfiable
+-- But it produces too many warnings: #26685
+
module Bug where
import Data.Kind (Type)
@@ -34,22 +39,6 @@ type family F (u1 :: ()) (u2 :: ()) :: Type where
type family Case (u :: ()) :: Type where
Case '() = Int
----------------------------------------
--- The checker can (now, Dec 25) see that (F u1 u2 ~ Char) is
--- unsatisfiable, so the empty pattern match is fine
-g1a :: F u1 u2 :~: Char -> SUnit u1 -> SUnit u2 -> Void
-g1a r _ _ = case r of {}
-
-{- Why [G] F u1 u2 ~ Char is unsatisfiable
-
-[G] F u1 u2 ~ Char =>rewrite [G] If (IsUnit u1) (Case u2) Int ~ Char
- =>(fundep) [W] IsUnit u1 ~ True
- [W] Case u2 ~ Char <<-- insoluble: no relevant eqns
--}
-
----------------------------------------
--- This older test matches on Refl (which is unsatisfiable)
--- but we now get complaints from inside
g1 :: F u1 u2 :~: Char
-> SUnit u1 -> SUnit u2
-> Void
@@ -57,8 +46,6 @@ g1 Refl su1 su2
| STrue <- sIsUnit su1
= case su2 of {}
-
-
g2 :: F u1 u2 :~: Char
-> SUnit u1 -> SUnit u2
-> Void
=====================================
testsuite/tests/pmcheck/should_compile/T15753c.stderr
=====================================
@@ -0,0 +1,19 @@
+T15753c.hs:46:5: warning: [GHC-94210] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match has inaccessible right hand side
+ In an equation for ‘g1’:
+ g1 Refl su1 su2 | STrue <- sIsUnit su1 = ...
+
+T15753c.hs:47:5: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
+ Pattern match(es) are non-exhaustive
+ In a case alternative:
+ Patterns of type ‘SUnit u2’ not matched: SUnit
+
+T15753c.hs:52:1: warning: [GHC-94210] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match has inaccessible right hand side
+ In an equation for ‘g2’: g2 Refl su1 su2 = ...
+
+T15753c.hs:55:9: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
+ Pattern match(es) are non-exhaustive
+ In a case alternative:
+ Patterns of type ‘SUnit u2’ not matched: SUnit
+
=====================================
testsuite/tests/pmcheck/should_compile/T15753d.hs
=====================================
@@ -8,7 +8,11 @@
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall -Wno-unticked-promoted-constructors #-}
-module Bug where
+
+-- NB: After fixing #22652 this program right produces warnings
+-- But it produces too many warnings: #26685
+
+module T15753d where
import Data.Kind
import Data.Type.Bool
=====================================
testsuite/tests/pmcheck/should_compile/T15753d.stderr
=====================================
@@ -0,0 +1,40 @@
+T15753d.hs:83:5: warning: [GHC-94210] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match has inaccessible right hand side
+ In an equation for ‘mapInsertWithNonEmpty1’:
+ mapInsertWithNonEmpty1 sf
+ snew_k
+ snew_v
+ (SMkMap sm)
+ Refl
+ Refl | STuple2 sold_k _ `SCons` sold_kvs <- sm,
+ SFalse <- sold_k %== snew_k = ...
+
+T15753d.hs:85:5: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
+ Pattern match(es) are non-exhaustive
+ In a case alternative:
+ Patterns of type ‘Sing
+ (MapInsertWith f new_k new_v (MkMap xs))’ not matched:
+ SMkMap _
+
+T15753d.hs:95:5: warning: [GHC-94210] [-Woverlapping-patterns (in -Wdefault)]
+ Pattern match has inaccessible right hand side
+ In an equation for ‘mapInsertWithNonEmpty2’:
+ mapInsertWithNonEmpty2 sf
+ snew_k
+ snew_v
+ (SMkMap sm)
+ Refl
+ Refl | STuple2 sold_k _ `SCons` sold_kvs <- sm = ...
+
+T15753d.hs:96:5: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
+ Pattern match(es) are non-exhaustive
+ In a case alternative:
+ Patterns of type ‘Sing (x == new_k)’ not matched: STrue
+
+T15753d.hs:98:9: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
+ Pattern match(es) are non-exhaustive
+ In a case alternative:
+ Patterns of type ‘Sing
+ (MapInsertWith f new_k new_v (MkMap xs))’ not matched:
+ SMkMap _
+
=====================================
testsuite/tests/pmcheck/should_compile/T22652a.hs
=====================================
@@ -0,0 +1,49 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE EmptyCase #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -Wincomplete-patterns #-}
+
+-- This test is a spin-off from the test T15753c
+
+module T22652a where
+
+import Data.Kind (Type)
+import Data.Type.Equality ((:~:)(..))
+import Data.Void (Void)
+
+data SBool :: Bool -> Type where
+ SFalse :: SBool False
+ STrue :: SBool True
+
+data SUnit :: () -> Type where
+ SUnit :: SUnit '()
+
+type family IsUnit (u :: ()) :: Bool where
+ IsUnit '() = True
+
+type family If (c :: Bool) (t :: Type) (f :: Type) :: Type where
+ If True t _ = t
+ If False _ f = f
+
+type family F (u1 :: ()) (u2 :: ()) :: Type where
+ F u1 u2 =
+ If (IsUnit u1) (Case u2) Int
+
+type family Case (u :: ()) :: Type where
+ Case '() = Int
+
+---------------------------------------
+-- The checker can (now, Dec 25) see that (F u1 u2 ~ Char) is
+-- unsatisfiable, so the empty pattern match is fine
+g1a :: F u1 u2 :~: Char -> SUnit u1 -> SUnit u2 -> Void
+g1a r _ _ = case r of {}
+
+{- Why [G] F u1 u2 ~ Char is unsatisfiable
+
+[G] F u1 u2 ~ Char =>rewrite [G] If (IsUnit u1) (Case u2) Int ~ Char
+ =>(fundep) [W] IsUnit u1 ~ True
+ [W] Case u2 ~ Char <<-- insoluble: no relevant eqns
+-}
=====================================
testsuite/tests/pmcheck/should_compile/all.T
=====================================
@@ -180,3 +180,4 @@ test('T24891', normal, compile, ['-Wincomplete-record-selectors'])
test('T25257', normal, compile, [overlapping_incomplete])
test('T24845', [], compile, [overlapping_incomplete])
test('T22652', [], compile, [overlapping_incomplete])
+test('T22652a', [], compile, [overlapping_incomplete])
=====================================
testsuite/tests/typecheck/should_fail/T5236.stderr
=====================================
@@ -0,0 +1,7 @@
+T5236.hs:16:9: error: [GHC-39999]
+ • No instance for ‘Id A B’
+ The functional dependencies arising from this constraint are insoluble
+ • In the ambiguity check for ‘loop’
+ To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
+ In the type signature: loop :: Id A B => Bool
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -250,7 +250,7 @@ test('SilentParametersOverlapping', normal, compile, [''])
test('FailDueToGivenOverlapping', normal, compile_fail, [''])
test('LongWayOverlapping', normal, compile_fail, [''])
test('T5051', normal, compile, [''])
-test('T5236',normal,compile,[''])
+test('T5236',normal,compile_fail,[''])
test('T5246',normal,compile_fail,[''])
test('T5300',normal,compile_fail,[''])
test('T5095',normalise_fun(normalise_errmsg),compile_fail,[''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a2e35bf3cc33177353e2f7a244877e8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a2e35bf3cc33177353e2f7a244877e8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/mp/iface-patches-9.10] 23 commits: compiler: implement --show-iface-abi-hash major mode
by Matthew Pickering (@mpickering) 18 Dec '25
by Matthew Pickering (@mpickering) 18 Dec '25
18 Dec '25
Matthew Pickering pushed to branch wip/mp/iface-patches-9.10 at Glasgow Haskell Compiler / GHC
Commits:
012af357 by Cheng Shao at 2024-12-09T09:46:45-08:00
compiler: implement --show-iface-abi-hash major mode
- - - - -
0f665588 by Cheng Shao at 2024-12-09T09:46:45-08:00
Oneshot bytecode linking
- - - - -
a54376cf by Torsten Schmits at 2024-12-09T09:46:45-08:00
Package deps bytecode linking
- - - - -
44c8c978 by Ian-Woo Kim at 2024-12-09T09:46:45-08:00
set extra_decls = Nothing in interpreter after interface generation
- - - - -
d695ed07 by Ian-Woo Kim at 2024-12-09T09:46:45-08:00
No in-memory resident mi_extra_decls in compilation.
They are transiently loaded and removed after byte-code generation.
- - - - -
27a4a8bc by Ben Gamari at 2024-12-09T10:20:35-08:00
rts: Tighten up invariants of PACK
- - - - -
0756f0b5 by Ben Gamari at 2024-12-09T10:20:40-08:00
StgToByteCode: Don't assume that data con workers are nullary
Previously StgToByteCode assumed that all data-con workers were of a
nullary representation. This is not a valid assumption, as seen
in #23210, where an unsaturated application of a unary data
constructor's worker resulted in invalid bytecode. Sadly, I have not yet
been able to reduce a minimal testcase for this.
Fixes #23210.
- - - - -
b335f856 by Cheng Shao at 2024-12-10T10:52:14-08:00
driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code
This commit fixes an undefined symbol error in RTS linker when
attempting to compile home modules with -fhpc and
-fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for
detailed description and analysis of the bug.
Also adds T25510/T25510c regression tests to test make mode/oneshot
mode of the bug.
backported to GHC 9.10.
- - - - -
2261e59e by Rebecca Turner at 2024-12-10T13:55:31-08:00
ghc-internal: No trailing whitespace in exceptions
This is a backport of the *behavior* in
https://gitlab.haskell.org/ghc/ghc/-/commit/bfe600f5bb3ecd2c8fa71c536c63d3c…
The commit upstream depends on a bunch of other changes to the exception
reporting infrastructure, so I've chosen to recreate its behavior here
rather than pulling in all the dependent patches.
This fixes a regression where GHC 9.10.1 adds a trailing newline to the
`displayException` implementation for `SomeException`. This has been
reverted in `master` but 9.10.2 isn't out yet and there's various
changes the upstream commit depends on, so this is a simple one-line
fix.
See: https://gitlab.haskell.org/ghc/ghc/-/issues/25052
- - - - -
68f4225c by Ian-Woo Kim at 2024-12-11T14:49:55-08:00
disabled stub dynamic object generation for one-shot byte-code linking.
- - - - -
97da9d9e by Torsten Schmits at 2024-12-25T08:52:35-08:00
refactor quadratic search in warnMissingHomeModules
- - - - -
ba330bbd by Rodrigo Mesquita at 2024-12-25T09:49:02-08:00
Improve reachability queries on ModuleGraph
Introduces `ReachabilityIndex`, an index constructed from a
`GHC.Data.Graph.Directed` `Graph` that supports fast reachability
queries (in $O(1)$). This abstract data structure is exposed from
`GHC.Data.Graph.Directed.Reachability`.
This index is constructed from the module graph nodes and cached in
`ModuleGraph`, enabling efficient reachability queries on the module
graph. Previously, we'd construct a Map of Set of ModuleGraph nodes
which used a lot of memory (`O(n^2)` in the number of nodes) and cache
that in the `ModuleGraph`. By using the reachability index we get rid of
this space leak in the module graph -- even though the index is still
quadratic in the number of modules, it is much, much more space
efficient due to its representation using an IntMap of IntSet as opposed
to the transitive closure we previously cached.
In a memory profile of MultiLayerModules with 100x100 modules, memory
usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB
are caused by a second space leak related to ModuleGraph. On the same
program, it brings compile time from 7.5s to 5.5s.
Note how we simplify `checkHomeUnitsClosed` in terms of
`isReachableMany` and by avoiding constructing a second graph with the
full transitive closure -- it suffices to answer the reachability query
on the full graph without collapsing the transitive closure completely
into nodes.
Unfortunately, solving this leak means we have to do a little bit more
work since we can no longer cache the result of turning vertex indices
into nodes. This results in a slight regression in MultiLayerModulesTH_Make,
but results in large performance and memory wins when compiling large
amounts of modules.
-------------------------
Metric Decrease:
mhu-perf
Metric Increase:
MultiLayerModulesTH_Make
-------------------------
- - - - -
53ecc06c by Ian-Woo Kim at 2024-12-25T16:45:39-08:00
dummy flag -fpackage-db-byte-code
- - - - -
3573c6fe by Ian-Woo Kim at 2025-01-08T06:58:32-08:00
similarize the parallel downsweep to GHC HEAD version.
- - - - -
9da11f8f by Matthew Pickering at 2025-01-08T08:29:47-08:00
Use deterministic names for temporary files
When there are multiple threads they can race to create a temporary
file, in some situations the thread will create ghc_1.c and in some it
will create ghc_2.c. This filename ends up in the debug info for object
files after compiling a C file, therefore contributes to object
nondeterminism.
In order to fix this we store a prefix in `TmpFs` which serves to
namespace temporary files. The prefix is populated from the counter in
TmpFs when the TmpFs is forked. Therefore the TmpFs must be forked
outside the thread which consumes it, in a deterministic order, so each
thread always receives a TmpFs with the same prefix.
This assumes that after the initial TmpFs is created, all other TmpFs
are created from forking the original TmpFs. Which should have been try
anyway as otherwise there would be file collisions and non-determinism.
Fixes #25224
- - - - -
3a484a7b by Ian-Woo Kim at 2025-01-08T14:47:34-08:00
monotonic FinderCache. missed part from parallel downsweep latest GHC HEAD patch
- - - - -
2c4d9f61 by Andreas Klebinger at 2025-02-28T15:04:43-08:00
SpecConstr: Introduce a separate argument limit for forced specs.
We used to put no limit at all on specializations forced via the SPEC
argument. This isn't always reasonable so we introduce a very high limit
that applies to forced specializations, a flag to control it, and we now
emit a warning if we fail a specialization because we exceed the
warning.
Fixes #25197
- - - - -
1c80ba27 by Torsten Schmits at 2025-10-30T17:58:26+01:00
Load TH deps from home unit states of the modules that import them
- - - - -
4d6ffa22 by Torsten Schmits at 2025-11-06T16:10:01+01:00
remove redundant core bindings typecheck in initWholeCoreBindings
- - - - -
75206a24 by Georgios Karachalias at 2025-11-19T13:58:58+01:00
Use OsPath in PkgDbRef and UnitDatabase, not FilePath
- - - - -
ad1d03ec by Matthew Pickering at 2025-12-11T19:44:01+01:00
Various downsweep perf tweaks
- - - - -
f20cef54 by Torsten Schmits at 2025-12-11T19:44:01+01:00
Abstract out parts of mkUnitState into a handler type
- - - - -
3ecb31bc by Fendor at 2025-12-18T17:28:42+00:00
Refactor the Binary serialisation interface
The goal is simplifiy adding deduplication tables to `ModIface`
interface serialisation.
We identify two main points of interest that make this difficult:
1. UserData hardcodes what `Binary` instances can have deduplication
tables. Moreover, it heavily uses partial functions.
2. GHC.Iface.Binary hardcodes the deduplication tables for 'Name' and
'FastString', making it difficult to add more deduplication.
Instead of having a single `UserData` record with fields for all the
types that can have deduplication tables, we allow to provide custom
serialisers for any `Typeable`.
These are wrapped in existentials and stored in a `Map` indexed by their
respective `TypeRep`.
The `Binary` instance of the type to deduplicate still needs to
explicitly look up the decoder via `findUserDataReader` and
`findUserDataWriter`, which is no worse than the status-quo.
`Map` was chosen as microbenchmarks indicate it is the fastest for a
small number of keys (< 10).
To generalise the deduplication table serialisation mechanism, we
introduce the types `ReaderTable` and `WriterTable` which provide a
simple interface that is sufficient to implement a general purpose
deduplication mechanism for `writeBinIface` and `readBinIface`.
This allows us to provide a list of deduplication tables for
serialisation that can be extended more easily, for example for
`IfaceTyCon`, see the issue https://gitlab.haskell.org/ghc/ghc/-/issues/24540
for more motivation.
In addition to this refactoring, we split `UserData` into `ReaderUserData`
and `WriterUserData`, to avoid partial functions and reduce overall
memory usage, as we need fewer mutable variables.
Bump haddock submodule to accomodate for `UserData` split.
-------------------------
Metric Increase:
MultiLayerModulesTH_Make
MultiLayerModulesRecomp
T21839c
-------------------------
Split `BinHandle` into `ReadBinHandle` and `WriteBinHandle`
A `BinHandle` contains too much information for reading data.
For example, it needs to keep a `FastMutInt` and a `IORef BinData`,
when the non-mutable variants would suffice.
Additionally, this change has the benefit that anyone can immediately
tell whether the `BinHandle` is used for reading or writing.
Bump haddock submodule BinHandle split.
Add Eq and Ord instance to `IfaceType`
We add an `Ord` instance so that we can store `IfaceType` in a
`Data.Map` container.
This is required to deduplicate `IfaceType` while writing `.hi` files to
disk. Deduplication has many beneficial consequences to both file size
and memory usage, as the deduplication enables implicit sharing of
values.
See issue #24540 for more motivation.
The `Ord` instance would be unnecessary if we used a `TrieMap` instead
of `Data.Map` for the deduplication process. While in theory this is
clerarly the better option, experiments on the agda code base showed
that a `TrieMap` implementation has worse run-time performance
characteristics.
To the change itself, we mostly derive `Eq` and `Ord`. This requires us
to change occurrences of `FastString` with `LexicalFastString`, since
`FastString` has no `Ord` instance.
We change the definition of `IfLclName` to a newtype of
`LexicalFastString`, to make such changes in the future easier.
Bump haddock submodule for IfLclName changes
Move out LiteralMap to avoid cyclic module dependencies
Add deduplication table for `IfaceType`
The type `IfaceType` is a highly redundant, tree-like data structure.
While benchmarking, we realised that the high redundancy of `IfaceType`
causes high memory consumption in GHCi sessions when byte code is
embedded into the `.hi` file via `-fwrite-if-simplified-core` or
`-fbyte-code-and-object-code`.
Loading such `.hi` files from disk introduces many duplicates of
memory expensive values in `IfaceType`, such as `IfaceTyCon`,
`IfaceTyConApp`, `IA_Arg` and many more.
We improve the memory behaviour of GHCi by adding an additional
deduplication table for `IfaceType` to the serialisation of `ModIface`,
similar to how we deduplicate `Name`s and `FastString`s.
When reading the interface file back, the table allows us to automatically
share identical values of `IfaceType`.
To provide some numbers, we evaluated this patch on the agda code base.
We loaded the full library from the `.hi` files, which contained the
embedded core expressions (`-fwrite-if-simplified-core`).
Before this patch:
* Load time: 11.7 s, 2.5 GB maximum residency.
After this patch:
* Load time: 7.3 s, 1.7 GB maximum residency.
This deduplication has the beneficial side effect to additionally reduce
the size of the on-disk interface files tremendously.
For example, on agda, we reduce the size of `.hi` files (with
`-fwrite-if-simplified-core`):
* Before: 101 MB on disk
* Now: 24 MB on disk
This has even a beneficial side effect on the cabal store. We reduce the
size of the store on disk:
* Before: 341 MB on disk
* Now: 310 MB on disk
Note, none of the dependencies have been compiled with
`-fwrite-if-simplified-core`, but `IfaceType` occurs in multiple
locations in a `ModIface`.
We also add IfaceType deduplication table to .hie serialisation and
refactor .hie file serialisation to use the same infrastrucutre as
`putWithTables`.
Bump haddock submodule to accomodate for changes to the deduplication
table layout and binary interface.
Add run-time configurability of `.hi` file compression
Introduce the flag `-fwrite-if-compression=<n>` which allows to
configure the compression level of writing .hi files.
The motivation is that some deduplication operations are too expensive
for the average use case. Hence, we introduce multiple compression
levels with variable impact on performance, but still reduce the
memory residency and `.hi` file size on disk considerably.
We introduce three compression levels:
* `1`: `Normal` mode. This is the least amount of compression.
It deduplicates only `Name` and `FastString`s, and is naturally the
fastest compression mode.
* `2`: `Safe` mode. It has a noticeable impact on .hi file size and is
marginally slower than `Normal` mode. In general, it should be safe to
always use `Safe` mode.
* `3`: `Full` deduplication mode. Deduplicate as much as we can,
resulting in minimal .hi files, but at the cost of additional
compilation time.
Reading .hi files doesn't need to know the initial compression level,
and can always deserialise a `ModIface`, as we write out a byte that
indicates the next value has been deduplicated.
This allows users to experiment with different compression levels for
packages, without recompilation of dependencies.
Note, the deduplication also has an additional side effect of reduced
memory consumption to implicit sharing of deduplicated elements.
See https://gitlab.haskell.org/ghc/ghc/-/issues/24540 for example where
that matters.
-------------------------
Metric Decrease:
MultiLayerModulesDefsGhciWithCore
T16875
T21839c
T24471
hard_hole_fits
libdir
-------------------------
Improve sharing of duplicated values in `ModIface`, fixes #24723
As a `ModIface` often contains duplicated values that are not
necessarily shared, we improve sharing by serialising the `ModIface`
to an in-memory byte array. Serialisation uses deduplication tables, and
deserialisation implicitly shares duplicated values.
This helps reducing the peak memory usage while compiling in
`--make` mode. The peak memory usage is especially smaller when
generating interface files with core expressions
(`-fwrite-if-simplified-core`).
On agda, this reduces the peak memory usage:
* `2.2 GB` to `1.9 GB` for a ghci session.
On `lib:Cabal`, we report:
* `570 MB` to `500 MB` for a ghci session
* `790 MB` to `667 MB` for compiling `lib:Cabal` with ghc
There is a small impact on execution time, around 2% on the agda code
base.
Avoid unneccessarily re-serialising the `ModIface`
To reduce memory usage of `ModIface`, we serialise `ModIface` to an
in-memory byte array, which implicitly shares duplicated values.
This serialised byte array can be reused to avoid work when we actually
write the `ModIface` to disk.
We introduce a new field to `ModIface` which allows us to save the byte
array, and write it direclty to disk if the `ModIface` wasn't changed
after the initial serialisation.
This requires us to change absolute offsets, for example to jump to the
deduplication table for `Name` or `FastString` with relative offsets, as
the deduplication byte array doesn't contain header information, such as
fingerprints.
To allow us to dump the binary blob to disk, we need to replace all
absolute offsets with relative ones.
We introduce additional helpers for `ModIface` binary serialisation, which
construct relocatable binary blobs. We say the binary blob is relocatable,
if the binary representation can be moved and does not contain any
absolute offsets.
Further, we introduce new primitives for `Binary` that allow to create
relocatable binaries, such as `forwardGetRel` and `forwardPutRel`.
-------------------------
Metric Decrease:
MultiLayerModulesDefsGhcWithCore
Metric Increase:
MultiComponentModules
MultiLayerModules
T10421
T12150
T12234
T12425
T13035
T13253-spj
T13701
T13719
T14697
T15703
T16875
T18698b
T18140
T18304
T18698a
T18730
T18923
T20049
T24582
T5837
T6048
T9198
T9961
mhu-perf
-------------------------
These metric increases may look bad, but they are all completely benign,
we simply allocate 1 MB per module for `shareIface`. As this allocation
is quite quick, it has a negligible impact on run-time performance.
In fact, the performance difference wasn't measurable on my local
machine. Reducing the size of the pre-allocated 1 MB buffer avoids these
test failures, but also requires us to reallocate the buffer if the
interface file is too big. These reallocations *did* have an impact on
performance, which is why I have opted to accept all these metric
increases, as the number of allocated bytes is merely a guidance.
This 1MB allocation increase causes a lot of tests to fail that
generally have a low allocation number. E.g., increasing from 40MB to
41MB is a 2.5% increase.
In particular, the tests T12150, T13253-spj, T18140, T18304, T18698a,
T18923, T20049, T24582, T5837, T6048, and T9961 only fail on i386-darwin
job, where the number of allocated bytes seems to be lower than in other
jobs.
The tests T16875 and T18698b fail on i386-linux for the same reason.
WIP: Lazy loading of IfaceDecl
- - - - -
114 changed files:
- compiler/GHC.hs
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Data/Graph/Directed.hs
- + compiler/GHC/Data/Graph/Directed/Internal.hs
- + compiler/GHC/Data/Graph/Directed/Reachability.hs
- + compiler/GHC/Data/OsPath.hs
- compiler/GHC/Data/TrieMap.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/Main.hs
- + compiler/GHC/Driver/Main.hs-boot
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Coverage.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Env.hs
- compiler/GHC/Iface/Ext/Binary.hs
- compiler/GHC/Iface/Ext/Fields.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Binary.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/IfaceToCore.hs-boot
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Runtime/Context.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/GHC/Stg/CSE.hs
- compiler/GHC/Stg/Utils.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Hpc.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/Tc/Errors/Hole.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/FieldLabel.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/Name/Ppr.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModGuts.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Binary/Typeable.hs
- compiler/GHC/Utils/TmpFs.hs
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/Language/Haskell/Syntax/Type.hs-boot
- compiler/cbits/genSym.c
- compiler/ghc.cabal.in
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/phases.rst
- docs/users_guide/using-optimisation.rst
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Monad.hs
- ghc/Main.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- rts/Interpreter.c
- rts/include/rts/storage/InfoTables.h
- + testsuite/tests/bytecode/T24634/T24634.stdout
- + testsuite/tests/bytecode/T25510/Makefile
- + testsuite/tests/bytecode/T25510/T25510A.hs
- + testsuite/tests/bytecode/T25510/T25510B.hs
- + testsuite/tests/bytecode/T25510/all.T
- testsuite/tests/plugins/simple-plugin/Simple/RemovePlugin.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/th/cross-package/Cross.hs
- + testsuite/tests/th/cross-package/CrossDep.hs
- + testsuite/tests/th/cross-package/CrossDepApi.hs
- + testsuite/tests/th/cross-package/CrossLocal.hs
- + testsuite/tests/th/cross-package/CrossNum.hs
- + testsuite/tests/th/cross-package/CrossNum.hs-boot
- + testsuite/tests/th/cross-package/CrossObj.hs
- + testsuite/tests/th/cross-package/CrossPackage.stdout
- + testsuite/tests/th/cross-package/Makefile
- + testsuite/tests/th/cross-package/all.T
- + testsuite/tests/th/cross-package/dep.conf
- + testsuite/tests/th/cross-package/obj.conf
- + testsuite/tests/th/cross-package/prep.bash
- + testsuite/tests/th/cross-package/run.bash
- + testsuite/tests/th/cross-package/unit1
- + testsuite/tests/th/cross-package/unit2
- testsuite/tests/wasm/should_run/control-flow/LoadCmmGroup.hs
- utils/haddock
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a3a509dd5259f5a5b87d7138225b7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7a3a509dd5259f5a5b87d7138225b7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/mp/iface-patches-9.10
by Matthew Pickering (@mpickering) 18 Dec '25
by Matthew Pickering (@mpickering) 18 Dec '25
18 Dec '25
Matthew Pickering pushed new branch wip/mp/iface-patches-9.10 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mp/iface-patches-9.10
You're receiving this email because of your account on gitlab.haskell.org.
1
0
18 Dec '25
Rodrigo Mesquita pushed new branch wip/romes/25636 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/25636
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/querying-newline-modes] 205 commits: compiler/ghci: replace the LoadDLL message with LoadDLLs
by Wolfgang Jeltsch (@jeltsch) 18 Dec '25
by Wolfgang Jeltsch (@jeltsch) 18 Dec '25
18 Dec '25
Wolfgang Jeltsch pushed to branch wip/jeltsch/querying-newline-modes at Glasgow Haskell Compiler / GHC
Commits:
a4d664c7 by Cheng Shao at 2025-09-29T17:29:22+02:00
compiler/ghci: replace the LoadDLL message with LoadDLLs
As a part of #25407, this commit changes the LoadDLL message to
LoadDLLs, which takes a list of DLL paths to load and returns the list
of remote pointer handles. The wasm dyld is refactored to take
advantage of LoadDLLs and harvest background parallelism. On other
platforms, LoadDLLs is based on a fallback codepath that does
sequential loading.
The driver is not actually emitting singular LoadDLLs message with
multiple DLLs yet, this is left in subsequent commits.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7fc4bae by Cheng Shao at 2025-09-29T17:29:22+02:00
driver: separate downsweep/upsweep phase in loadPackages'
This commit refactors GHC.Linker.Loader.loadPackages' to be separated
into downsweep/upsweep phases:
- The downsweep phase performs dependency analysis and generates a
list of topologically sorted packages to load
- The upsweep phase sequentially loads these packages by calling
loadPackage
This is a necessary refactoring to make it possible to make loading of
DLLs concurrent.
- - - - -
ab180104 by Cheng Shao at 2025-09-29T17:57:19+02:00
driver: emit single LoadDLLs message to load multiple DLLs
This commit refactors the driver so that it emits a single LoadDLLs
message to load multiple DLLs in GHC.Linker.Loader.loadPackages'.
Closes #25407.
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
TcPlugin_RewritePerf
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
9c304ec0 by Sean D. Gillespie at 2025-09-29T19:57:07-04:00
Fix SIZED_BIN_OP_TY_INT casts in RTS interpreter
Correct `SIZED_BIN_OP_TY_INT` cast to integer. Previously, it cast
its second operand as its parameter `ty`. This does not currently
cause any issues, since we are only using it for bit shifts.
Fixes #26287
- - - - -
a1de535f by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: Fix lost wakeups in threadPaused for threads blocked on black holes
The lazy blackholing code in threadPaused could overwrite closures
that were already eagerly blackholed, and as such wouldn't have a
marked update frame. If the black hole was overwritten by its
original owner, this would lead to an undetected collision, and
the contents of any existing blocking queue being lost.
This adds a check for eagerly blackholed closures and avoids
overwriting their contents.
Fixes #26324
- - - - -
b7e21e49 by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: push the correct update frame in stg_AP_STACK
The frame contains an eager black hole (__stg_EAGER_BLACKHOLE_info) so
we should push an stg_bh_upd_frame_info instead of an stg_upd_frame_info.
- - - - -
02a7c18a by Cheng Shao at 2025-09-30T18:41:27-04:00
ghci: fix lookupSymbolInDLL behavior on wasm
This patch fixes lookupSymbolInDLL behavior on wasm to return Nothing
instead of throwing. On wasm, we only have lookupSymbol, and the
driver would attempt to call lookupSymbolInDLL first before falling
back to lookupSymbol, so lookupSymbolInDLL needs to return Nothing
gracefully for the fallback behavior to work.
- - - - -
aa0ca5e3 by Cheng Shao at 2025-09-30T18:41:27-04:00
hadrian/compiler: enable internal-interpreter for ghc library in wasm stage1
This commit enables the internal-interpreter flag for ghc library in
wasm stage1, as well as other minor adjustments to make it actually
possible to launch a ghc api session that makes use of the internal
interpreter. Closes #26431 #25400.
- - - - -
69503668 by Cheng Shao at 2025-09-30T18:41:27-04:00
testsuite: add T26431 test case
This commit adds T26431 to testsuite/tests/ghci-wasm which goes
through the complete bytecode compilation/linking/running pipeline in
wasm, so to witness that the ghc shared library in wasm have full
support for internal-interpreter.
- - - - -
e9445c01 by Matthew Pickering at 2025-09-30T18:42:23-04:00
driver: Load bytecode static pointer entries during linking
Previously the entries were loaded too eagerly, during upsweep, but we
should delay loading them until we know that the relevant bytecode
object is demanded.
Towards #25230
- - - - -
b8307eab by Cheng Shao at 2025-09-30T18:43:14-04:00
autoconf/ghc-toolchain: remove obsolete C99 check
This patch removes obsolete c99 check from autoconf/ghc-toolchain. For
all toolchain & platform combination we support, gnu11 or above is
already supported without any -std flag required, and our RTS already
required C11 quite a few years ago, so the C99 check is completely
pointless.
- - - - -
9c293544 by Simon Peyton Jones at 2025-10-01T09:36:10+01:00
Fix buglet in GHC.Core.Unify.uVarOrFam
We were failing to match two totally-equal types!
This led to #26457.
- - - - -
554487a7 by Rodrigo Mesquita at 2025-10-01T23:04:43-04:00
cleanup: Drop obsolete comment about HsConDetails
HsConDetails used to have an argument representing the type of the
tyargs in a list:
data HsConDetails tyarg arg rec
= PrefixCon [tyarg] [arg]
This datatype was shared across 3 synonyms: HsConPatDetails,
HsConDeclH98Details, HsPatSynDetails. In the latter two cases, `tyarg`
was instanced to `Void` meaning the list was always empty for these
cases.
In 7b84c58867edca57a45945a20a9391724db6d9e4, this was refactored such
that HsConDetails no longer needs a type of tyargs by construction. The
first case now represents the type arguments in the args type itself,
with something like:
ConPat "MkE" [InvisP tp1, InvisP tp2, p1, p2]
So the deleted comment really is just obsolete.
Fixes #26461
- - - - -
6992ac09 by Cheng Shao at 2025-10-02T07:27:55-04:00
testsuite: remove unused expected output files
This patch removes unused expected output files in the testsuites on
platforms that we no longer support.
- - - - -
39eaaaba by Ben Gamari at 2025-10-02T07:28:45-04:00
rts: Dynamically initialize built-in closures
To resolve #26166 we need to eliminate references to undefined symbols
in the runtime system. One such source of these is the runtime's
static references to `I#` and `C#` due the `stg_INTLIKE` and
`stg_CHARLIKE` arrays.
To avoid this we make these dynamic, initializing them during RTS
start-up.
- - - - -
c254c54b by Cheng Shao at 2025-10-02T07:29:33-04:00
compiler: only invoke keepCAFsForGHCi if internal-interpreter is enabled
This patch makes the ghc library only invoke keepCAFsForGHCi if
internal-interpreter is enabled. For cases when it's not (e.g. the
host build of a cross ghc), this avoids unnecessarily retaining all
CAFs in the heap. Also fixes the type signature of c_keepCAFsForGHCi
to match the C ABI.
- - - - -
c9ec4d43 by Simon Hengel at 2025-10-02T18:42:20-04:00
Update copyright in documentation
- - - - -
da9633a9 by Matthew Pickering at 2025-10-02T18:43:04-04:00
loader: Unify loadDecls and loadModuleLinkables functions
These two functions nearly did the same thing. I have refactored them so
that `loadDecls` now calls `loadModuleLinkables`.
Fixes #26459
- - - - -
5db98d80 by Simon Hengel at 2025-10-02T18:43:53-04:00
Fix typo
- - - - -
1275d360 by Matthew Pickering at 2025-10-03T06:05:56-04:00
testsuite: Use ghci_ways to set ways in PackedDataCon/UnboxedTuples/UnliftedDataTypeInterp tests
These tests reimplemented the logic from `valid_way` in order to
determine what ways to run. It's easier to use this combination of
`only_ways` and `extra_ways` to only run in GHCi ways and always run in
GHCi ways.
- - - - -
c06b534b by Matthew Pickering at 2025-10-03T06:06:40-04:00
Rename interpreterBackend to bytecodeBackend
This is preparation for creating bytecode files.
The "interpreter" is one way in which we can run bytecode objects. It is
more accurate to describe that the backend produces bytecode, rather
than the means by which the code will eventually run.
The "interpreterBackend" binding is left as a deprecated alias.
- - - - -
41bdb16f by Andreas Klebinger at 2025-10-06T18:04:34-04:00
Add a perf test for #26425
- - - - -
1da0c700 by Andreas Klebinger at 2025-10-06T18:05:14-04:00
Testsuite: Silence warnings about Wx-partial in concprog001
- - - - -
7471eb6a by sheaf at 2025-10-07T21:39:43-04:00
Improve how we detect user type errors in types
This commit cleans up all the code responsible for detecting whether a
type contains "TypeError msg" applications nested inside it. All the
logic is now in 'userTypeError_maybe', which is always deep. Whether
it looks inside type family applications is determined by the passed-in
boolean flag:
- When deciding whether a constraint is definitely insoluble, don't
look inside type family applications, as they may still reduce -- in
which case the TypeError could disappear.
- When reporting unsolved constraints, look inside type family
applications: they had the chance to reduce but didn't, and the
custom type error might contain valuable information.
All the details are explained in Note [Custom type errors in constraints]
in GHC.Tc.Types.Constraint.
Another benefit of this change is that it allows us to get rid of the
deeply dodgy 'getUserTypeErrorMsg' function.
This commit also improves the detection of custom type errors, for
example in equality constraints:
TypeError blah ~# rhs
It used to be the case that we didn't detect the TypeError on the LHS,
because we never considered that equality constraints could be insoluble
due to the presence of custom type errors. Addressing this oversight
improves detection of redundant pattern match warnings, fixing #26400.
- - - - -
29955267 by Rodrigo Mesquita at 2025-10-07T21:40:25-04:00
cleanup: Drop obsolete settings from config.mk.in
These values used to be spliced into the bindist's `config.mk` s.t. when
`make` was run, the values were read and written into the bindist installation `settings` file.
However, we now carry these values to the bindist directly in the
default.target toolchain file, and `make` writes almost nothing to
`settings` now (see #26227)
The entries deleted in this MR were already unused.
Fixes #26478
- - - - -
f7adfed2 by ARATA Mizuki at 2025-10-08T08:37:24-04:00
T22033 is only relevant if the word size is 64-bit
Fixes #25497
- - - - -
ff1650c9 by Ben Gamari at 2025-10-08T08:38:07-04:00
rts/posix: Enforce iteration limit on heap reservation logic
Previously we could loop indefinitely when attempting to get an address
space reservation for our heap. Limit the logic to 8 iterations to
ensure we instead issue a reasonable error message.
Addresses #26151.
- - - - -
01844557 by Ben Gamari at 2025-10-08T08:38:07-04:00
rts/posix: Hold on to low reservations when reserving heap
Previously when the OS gave us an address space reservation in low
memory we would immediately release it and try again. However, on some
platforms this meant that we would get the same allocation again in the
next iteration (since mmap's `hint` argument is just that, a hint).
Instead we now hold on to low reservations until we have found a
suitable heap reservation.
Fixes #26151.
- - - - -
b2c8d052 by Sven Tennie at 2025-10-08T08:38:47-04:00
Build terminfo only in upper stages in cross-builds (#26288)
Currently, there's no way to provide library paths for [n]curses for
both - build and target - in cross-builds. As stage0 is only used to
build upper stages, it should be fine to build terminfo only for them.
This re-enables building cross-compilers with terminfo.
- - - - -
c58f9a61 by Julian Ospald at 2025-10-08T08:39:36-04:00
ghc-toolchain: Drop `ld.gold` from merge object command
It's deprecated.
Also see #25716
- - - - -
2b8baada by sheaf at 2025-10-08T18:23:37-04:00
Improvements to 'mayLookIdentical'
This commit makes significant improvements to the machinery that decides
when we should pretty-print the "invisible bits" of a type, such as:
- kind applications, e.g. '@k' in 'Proxy @k ty'
- RuntimeReps, e.g. 'TYPE r'
- multiplicities and linear arrows 'a %1 -> b'
To do this, this commit refactors 'mayLookIdentical' to return **which**
of the invisible bits don't match up, e.g. in
(a %1 -> b) ~ (a %Many -> b)
we find that the invisible bit that doesn't match up is a multiplicity,
so we should set 'sdocLinearTypes = True' when pretty-printing, and with
e.g.
Proxy @k1 ~ Proxy @k2
we find that the invisible bit that doesn't match up is an invisible
TyCon argument, so we set 'sdocPrintExplicitKinds = True'.
We leverage these changes to remove the ad-hoc treatment of linearity
of data constructors with 'dataConDisplayType' and 'dataConNonLinearType'.
This is now handled by the machinery of 'pprWithInvisibleBits'.
Fixes #26335 #26340
- - - - -
129ce32d by sheaf at 2025-10-08T18:23:37-04:00
Store SDoc context in SourceError
This commits modifies the SourceError datatype which is used for
throwing and then reporting exceptions by storing all the info we need
to be able to print the SDoc, including whether we should print with
explicit kinds, explicit runtime-reps, etc.
This is done using the new datatype:
data SourceErrorContext
= SEC
!DiagOpts
!(DiagnosticOpts GhcMessage)
Now, when we come to report an error (by handling the exception), we
have access to the full context we need.
Fixes #26387
- - - - -
f9790ca8 by Ben Gamari at 2025-10-08T18:24:19-04:00
gitlab-ci: Make RELEASE_JOB an input
Rather than an undocumented variable.
- - - - -
14281a22 by Ben Gamari at 2025-10-11T14:06:47-04:00
rts/nonmoving: Fix comment spelling
- - - - -
bedd38b0 by Ben Gamari at 2025-10-11T14:06:47-04:00
rts/nonmoving: Use atomic operations to update bd->flags
- - - - -
215d6841 by Ben Gamari at 2025-10-11T14:06:47-04:00
nonmoving: Use get_itbl instead of explicit loads
This is cleaner and also fixes unnecessary (and unsound) use of
`volatile`.
- - - - -
2c94aa3a by Ben Gamari at 2025-10-11T14:06:47-04:00
rts/Scav: Handle WHITEHOLEs in scavenge_one
`scavenge_one`, used to scavenge mutable list entries, may encounter
`WHITEHOLE`s when the non-moving GC is in use via two paths:
1. when an MVAR is being marked concurrently
2. when the object belongs to a chain of selectors being short-cutted.
Fixes #26204.
- - - - -
6bd8155c by Matthew Pickering at 2025-10-11T14:07:29-04:00
Add support for generating bytecode objects
This commit adds the `-fwrite-byte-code` option which makes GHC emit a
`.gbc` file which contains a serialised representation of bytecode.
The bytecode can be loaded by the compiler to avoid having to
reinterpret a module when using the bytecode interpreter (for example,
in GHCi).
There are also the new options:
* -gbcdir=<DIR>: Specify the directory to place the gbc files
* -gbcsuf=<suffix>: Specify the suffix for gbc files
The option `-fbyte-code-and-object-code` now implies
`-fwrite-byte-code`.
These performance tests fail due to https://github.com/haskell/directory/issues/204
-------------------------
Metric Increase:
MultiComponentModules
MultiLayerModules
MultiComponentModulesRecomp
MultiLayerModulesRecomp
MultiLayerModulesTH_Make
MultiLayerModulesTH_OneShot
T13701
-------------------------
The bytecode serialisation part was implemented by Cheng Shao
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
- - - - -
dc8f9599 by Matthew Pickering at 2025-10-11T14:07:30-04:00
Revert "Add a perf test for #26425"
This test has a large memory spike currently, which makes the test
sensitive, since if you allocate a little more or less, the precise
location where GC happens shifts and you observe a different part of the
spike.
Andreas told me to revert the patch for now, and he will add it back
when he fixes the memory spike.
This reverts commit 41bdb16fd083110a06507248f648c507a2feb4af.
- - - - -
e10dcd65 by Sven Tennie at 2025-10-12T10:24:56+00:00
T22859: Increase threadDelay for small machines
The previously used thread delay led to failures on my RISC-V test
setups.
- - - - -
d59ef6b6 by Hai / @BestYeen at 2025-10-14T21:51:14-04:00
Change Alex and Happy m4 scripts to display which version was found in the system, adapt small formatting details in Happy script to be more like the Alex script again.
- - - - -
c98abb6a by Hai / @BestYeen at 2025-10-14T21:52:08-04:00
Update occurrences of return to pure and add a sample for redefining :m to mean :main
- - - - -
70ee825a by Cheng Shao at 2025-10-14T21:52:50-04:00
testsuite: fix T3586 for non-SSE3 platforms
`T3586.hs` contains `-fvia-C -optc-msse3` which I think is a
best-effort basis to harvest the C compiler's auto vectorization
optimizations via the C backend back when the test was added. The
`-fvia-C` part is now a deprecated no-op because GHC can't fall back
to the C backend on a non-unregisterised build, and `-optc-msse3`
might actually cause the test to fail on non x86/x64 platforms, e.g.
recent builds of wasi-sdk would report `wasm32-wasi-clang: error:
unsupported option '-msse3' for target 'wasm32-unknown-wasi'`.
So this patch cleans up this historical cruft. `-fvia-C` is removed,
and `-optc-msse3` is only passed when cpuid contains `pni` (which
indicates support of SSE3).
- - - - -
4be32153 by Teo Camarasu at 2025-10-15T08:06:09-04:00
Add submodules for template-haskell-lift and template-haskell-quasiquoter
These two new boot libraries expose stable subsets of the
template-haskell interface.
This is an implemenation of the GHC proposal https://github.com/ghc-proposals/ghc-proposals/pull/696
Work towards #25262
- - - - -
0c00c9c3 by Ben Gamari at 2025-10-15T08:06:51-04:00
rts: Eliminate uses of implicit constant arrays
Folding of `const`-sized variable-length arrays to a constant-length
array is a gnu extension which clang complains about.
Closes #26502.
- - - - -
bf902a1d by Fendor at 2025-10-15T16:00:59-04:00
Refactor distinct constructor tables map construction
Adds `GHC.Types.Unique.FM.alterUFM_L`, `GHC.Types.Unique.DFM.alterUDFM_L`
`GHC.Data.Word64Map.alterLookup` to support fusion of distinct
constructor data insertion and lookup during the construction of the `DataCon`
map in `GHC.Stg.Debug.numberDataCon`.
Co-authored-by: Fendor <fendor(a)posteo.de>
Co-authored-by: Finley McIlwaine <finleymcilwaine(a)gmail.com>
- - - - -
b3585ba1 by Fendor at 2025-10-15T16:00:59-04:00
Allow per constructor refinement of distinct-constructor-tables
Introduce `-fno-distinct-constructor-tables`. A distinct constructor table
configuration is built from the combination of flags given, in order. For
example, to only generate distinct constructor tables for a few specific
constructors and no others, just pass
`-fdistinct-constructor-tables-only=C1,...,CN`.
This flag can be supplied multiple times to extend the set of
constructors to generate a distinct info table for.
You can disable generation of distinct constructor tables for all
configurations by passing `-fno-distinct-constructor-tables`.
The various configurations of these flags is included in the `DynFlags`
fingerprints, which should result in the expected recompilation logic.
Adds a test that checks for distinct tables for various given or omitted
constructors.
Updates CountDepsAst and CountDepsParser tests to account for new dependencies.
Fixes #23703
Co-authored-by: Fendor <fendor(a)posteo.de>
Co-authored-by: Finley McIlwaine <finleymcilwaine(a)gmail.com>
- - - - -
e17dc695 by fendor at 2025-10-15T16:01:41-04:00
Fix typos in haddock documentation for stack annotation API
- - - - -
f85058d3 by Zubin Duggal at 2025-10-17T13:50:52+05:30
compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
Fixes #26264
Metric Decrease:
T9233
- - - - -
c85c845d by sheaf at 2025-10-17T22:35:32-04:00
Don't prematurely final-zonk PatSyn declarations
This commit makes GHC hold off on the final zonk for pattern synonym
declarations, in 'GHC.Tc.TyCl.PatSyn.tc_patsyn_finish'.
This accommodates the fact that pattern synonym declarations without a
type signature can contain unfilled metavariables, e.g. if the RHS of
the pattern synonym involves view-patterns whose type mentions promoted
(level 0) metavariables. Just like we do for ordinary function bindings,
we should allow these metavariables to be settled later, instead of
eagerly performing a final zonk-to-type.
Now, the final zonking-to-type for pattern synonyms is performed in
GHC.Tc.Module.zonkTcGblEnv.
Fixes #26465
- - - - -
ba3e5bdd by Rodrigo Mesquita at 2025-10-18T16:57:18-04:00
Move code-gen aux symbols from ghc-internal to rts
These symbols were all previously defined in ghc-internal and made the
dependency structure awkward, where the rts may refer to some of these
symbols and had to work around that circular dependency the way
described in #26166.
Moreover, the code generator will produce code that uses these symbols!
Therefore, they should be available in the rts:
PRINCIPLE: If the code generator may produce code which uses this
symbol, then it should be defined in the rts rather than, say,
ghc-internal.
That said, the main motivation is towards fixing #26166.
Towards #26166. Pre-requisite of !14892
- - - - -
f31de2a9 by Ben Gamari at 2025-10-18T16:57:18-04:00
rts: Avoid static symbol references to ghc-internal
This resolves #26166, a bug due to new constraints placed by Apple's
linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
Fixes #26166
Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita(a)gmail.com>
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
- - - - -
43fdfddc by Ben Gamari at 2025-10-18T16:57:18-04:00
compiler: Rename isMathFun -> isLibcFun
This set includes more than just math functions.
- - - - -
4ed5138f by Ben Gamari at 2025-10-18T16:57:18-04:00
compiler: Add libc allocator functions to libc_funs
Prototypes for these are now visible from `Prim.h`, resulting in
multiple-declaration warnings in the unregisterised job.
- - - - -
9a0a076b by Ben Gamari at 2025-10-18T16:57:18-04:00
rts: Minimize header dependencies of Prim.h
Otherwise we will end up with redundant and incompatible declarations
resulting in warnings during the unregisterised build.
- - - - -
26b8a414 by Diego Antonio Rosario Palomino at 2025-10-18T16:58:10-04:00
Cmm Parser: Fix incorrect example in comment
The Parser.y file contains a comment with an incorrect example of textual
Cmm (used in .cmm files). This commit updates the comment to ensure it
reflects valid textual Cmm syntax.
Fixes #26313
- - - - -
d4a9d6d6 by ARATA Mizuki at 2025-10-19T18:43:47+09:00
Handle implications between x86 feature flags
This includes:
* Multiple -msse* options can be specified
* -mavx implies -msse4.2
* -mavx2 implies -mavx
* -mfma implies -mavx
* -mavx512f implies -mavx2 and -mfma
* -mavx512{cd,er,pf} imply -mavx512f
Closes #24989
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
c9b8465c by Cheng Shao at 2025-10-20T10:16:00-04:00
wasm: workaround WebKit bug in dyld
This patch works around a WebKit bug and allows dyld to run on WebKit
based platforms as well. See added note for detailed explanation.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
91b6be10 by Julian Ospald at 2025-10-20T18:21:03-04:00
Improve error handling in 'getPackageArchives'
When the library dirs in the package conf files are not set up correctly,
the JS linker will happily ignore such packages and not link against them,
although they're part of the link plan.
Fixes #26383
- - - - -
6c5269da by Sven Tennie at 2025-10-20T18:21:44-04:00
Align coding style
Improve readability by using the same style for all constructor calls in
this function.
- - - - -
3d305889 by Sven Tennie at 2025-10-20T18:21:44-04:00
Reduce complexity by removing joins with mempty
ldArgs, cArgs and cppArgs are all `mempty`. Thus concatenating them adds
nothing but some complexity while reading the code.
- - - - -
38d65187 by Matthew Pickering at 2025-10-21T13:12:20+01:00
Fix stack decoding when using profiled runtime
There are three fixes in this commit.
* We need to replicate the `InfoTable` and `InfoTableProf`
approach for the other stack constants (see the new Stack.ConstantsProf
file).
* Then we need to appropiately import the profiled or non-profiled
versions.
* Finally, there was an incorrect addition in `stackFrameSize`. We need
to cast after performing addition on words.
Fixes #26507
- - - - -
17231bfb by fendor at 2025-10-21T13:12:20+01:00
Add regression test for #26507
- - - - -
4f5bf93b by Simon Peyton Jones at 2025-10-25T04:05:34-04:00
Postscript to fix for #26255
This MR has comments only
- - - - -
6ef22fa0 by IC Rainbow at 2025-10-26T18:23:01-04:00
Add SIMD primops for bitwise logical operations
This adds 128-bit wide and/or/xor instructions for X86 NCG,
with both SSE and AVX encodings.
```
andFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -- andps / vandps
andDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -- andpd / vandpd
andInt8X16# :: Int8X16# -> Int8X16# -> Int8X16# -- pand / vpand
```
The new primops are available on ARM when using LLVM backend.
Tests added:
- simd015 (floats and doubles)
- simd016 (integers)
- simd017 (words)
Fixes #26417
- - - - -
fbdc623a by sheaf at 2025-10-26T18:23:52-04:00
Add hints for unsolved HasField constraints
This commit adds hints and explanations for unsolved 'HasField'
constraints.
GHC will now provide additional explanations for an unsolved constraint
of the form 'HasField fld_name rec_ty fld_ty'; the details are laid out in
Note [Error messages for unsolved HasField constraints], but briefly:
1. Provide similar name suggestions (e.g. mis-spelled field name)
and import suggestions (record field not in scope).
These result in actionable 'GhcHints', which is helpful to provide
code actions in HLS.
2. Explain why GHC did not solve the constraint, e.g.:
- 'fld_name' is not a string literal (e.g. a type variable)
- 'rec_ty' is a TyCon without any fields, e.g. 'Int' or 'Bool'.
- 'fld_ty' contains existentials variables or foralls.
- The record field is a pattern synonym field (GHC does not generate
HasField instances for those).
- 'HasField' is a custom 'TyCon', not actually the built-in
'HasField' typeclass from 'GHC.Records'.
On the way, we slightly refactor the mechanisms for import suggestions
in GHC.Rename.Unbound. This is to account for the fact that, for
'HasField', we don't care whether the field is imported qualified or
unqualified. 'importSuggestions' was refactored, we now have
'sameQualImportSuggestions' and 'anyQualImportSuggestions'.
Fixes #18776 #22382 #26480
- - - - -
99d5707f by sheaf at 2025-10-26T18:23:52-04:00
Rename PatSyn MatchContext to PatSynCtx to avoid punning
- - - - -
5dc2e9ea by Julian Ospald at 2025-10-27T18:17:23-04:00
Skip uniques test if sources are not available
- - - - -
544b9ec9 by Vladislav Zavialov at 2025-10-27T18:18:06-04:00
Re-export GHC.Hs.Basic from GHC.Hs
Clean up some import sections in GHC by re-exporting GHC.Hs.Basic
from GHC.Hs.
- - - - -
643ce801 by Julian Ospald at 2025-10-28T18:18:55-04:00
rts: remove unneccesary cabal flags
We perform those checks via proper autoconf macros
instead that do the right thing and then add those
libs to the rts buildinfo.
- - - - -
d69ea8fe by Vladislav Zavialov at 2025-10-28T18:19:37-04:00
Test case for #17705
Starting with GHC 9.12 (the first release to include 5745dbd3),
all examples in this ticket are handled as expected.
- - - - -
4038a28b by Andreas Klebinger at 2025-10-30T12:38:52-04:00
Add a perf test for #26425
- - - - -
f997618e by Andreas Klebinger at 2025-10-30T12:38:52-04:00
OccAnal: Be stricter for better compiler perf.
In particular we are now stricter:
* When combining usageDetails.
* When computing binder info.
In combineUsageDetails when combining the underlying adds we compute a
new `LocalOcc` for each entry by combining the two existing ones.
Rather than wait for those entries to be forced down the road we now
force them immediately. Speeding up T26425 by about 10% with little
effect on the common case.
We also force binders we put into the Core AST everywhere now.
Failure to do so risks leaking the occ env used to set the binders
OccInfo.
For T26425 compiler residency went down by a factor of ~10x.
Compile time also improved by a factor of ~1.6.
-------------------------
Metric Decrease:
T18698a
T26425
T9233
-------------------------
- - - - -
5618645b by Vladislav Zavialov at 2025-10-30T12:39:33-04:00
Fix namespace specifiers in subordinate exports (#12488)
This patch fixes an oversight in the `lookupChildrenExport` function that
caused explicit namespace specifiers of subordinate export items to be
ignored:
module M (T (type A)) where -- should be rejected
data T = A
Based on the `IEWrappedName` data type, there are 5 cases to consider:
1. Unadorned name: P(X)
2. Named default: P(default X)
3. Pattern synonym: P(pattern X)
4. Type name: P(type X)
5. Data name: P(data X)
Case 1 is already handled correctly; cases 2 and 3 are parse errors; and
it is cases 4 and 5 that we are concerned with in this patch.
Following the precedent established in `LookupExactName`, we introduce
a boolean flag in `LookupChildren` to control whether to look up in all
namespaces or in a specific one. If an export item is accompanied by an
explicit namespace specifier `type` or `data`, we restrict the lookup in
`lookupGRE` to a specific namespace.
The newly introduced diagnostic `TcRnExportedSubordinateNotFound`
provides error messages and suggestions more tailored to this context
than the previously used `reportUnboundName`.
- - - - -
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
f6961b02 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: reformat dyld source code
This commit reformats dyld source code with prettier, to avoid
introducing unnecessary diffs in subsequent patches when they're
formatted before committing.
- - - - -
0c9032a0 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: simplify _initialize logic in dyld
This commit simplifies how we _initialize a wasm shared library in
dyld and removes special treatment for libc.so, see added comment for
detailed explanation.
- - - - -
ec1b40bd by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: support running dyld fully client side in the browser
This commit refactors the wasm dyld script so that it can be used to
load and run wasm shared libraries fully client-side in the browser
without needing a wasm32-wasi-ghci backend:
- A new `DyLDBrowserHost` class is exported, which runs in the browser
and uses the in-memory vfs without any RPC calls. This meant to be
used to create a `rpc` object for the fully client side use cases.
- The exported `main` function now can be used to load user-specified
shared libraries, and the user can use the returned `DyLD` instance
to run their own exported Haskell functions.
- The in-browser wasi implementation is switched to
https://github.com/haskell-wasm/browser_wasi_shim for bugfixes and
major performance improvements not landed upstream yet.
- When being run by deno, it now correctly switches to non-nodejs code
paths, so it's more convenient to test dyld logic with deno.
See added comments for details, as well as the added `playground001`
test case for an example of using it to build an in-browser Haskell
playground.
- - - - -
8f3e481f by Cheng Shao at 2025-11-01T00:08:01+01:00
testsuite: add playground001 to test haskell playground
This commit adds the playground001 test case to test the haskell
playground in browser, see comments for details.
- - - - -
af40606a by Cheng Shao at 2025-11-01T00:08:04+01:00
Revert "testsuite: add T26431 test case"
This reverts commit 695036686f8c6d78611edf3ed627608d94def6b7. T26431
is now retired, wasm ghc internal-interpreter logic is tested by
playground001.
- - - - -
86c82745 by Vladislav Zavialov at 2025-11-01T07:24:29-04:00
Supplant TcRnExportHiddenComponents with TcRnDodgyExports (#26534)
Remove a bogus special case in lookup_ie_kids_all,
making TcRnExportHiddenComponents obsolete.
- - - - -
fcf6331e by Richard Eisenberg at 2025-11-03T08:33:05+00:00
Refactor fundep solving
This commit is a large-scale refactor of the increasingly-messy code that
handles functional dependencies. It has virtually no effect on what compiles
but improves error messages a bit. And it does the groundwork for #23162.
The big picture is described in
Note [Overview of functional dependencies in type inference]
in GHC.Tc.Solver.FunDeps
* New module GHC.Tc.Solver.FunDeps contains all the fundep-handling
code for the constraint solver.
* Fundep-equalities are solved in a nested scope; they may generate
unifications but otherwise have no other effect.
See GHC.Tc.Solver.FunDeps.solveFunDeps
The nested needs to start from the Givens in the inert set, but
not the Wanteds; hence a new function `resetInertCans`, used in
`nestFunDepsTcS`.
* That in turn means that fundep equalities never show up in error
messages, so the complicated FunDepOrigin tracking can all disappear.
* We need to be careful about tracking unifications, so we kick out
constraints from the inert set after doing unifications. Unification
tracking has been majorly reformed: see Note [WhatUnifications] in
GHC.Tc.Utils.Unify.
A good consequence is that the hard-to-grok `resetUnificationFlag`
has been replaced with a simpler use of
`reportCoarseGrainUnifications`
Smaller things:
* Rename `FunDepEqn` to `FunDepEqns` since it contains multiple
type equalities.
Some compile time improvement
Metrics: compile_time/bytes allocated
Baseline
Test value New value Change
---------------------- --------------------------------------
T5030(normal) 173,839,232 148,115,248 -14.8% GOOD
hard_hole_fits(normal) 286,768,048 284,015,416 -1.0%
geo. mean -0.2%
minimum -14.8%
maximum +0.3%
Metric Decrease:
T5030
- - - - -
231adc30 by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
QuickLook's tcInstFun should make instantiation variables directly
tcInstFun must make "instantiation variables", not regular
unification variables, when instantiating function types. That was
previously implemented by a hack: set the /ambient/ level to QLInstTyVar.
But the hack finally bit me, when I was refactoring WhatUnifications.
And it was always wrong: see the now-expunged (TCAPP2) note.
This commit does it right, by making tcInstFun call its own
instantiation functions. That entails a small bit of duplication,
but the result is much, much cleaner.
- - - - -
39d4a24b by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Build implication for constraints from (static e)
This commit addresses #26466, by buiding an implication for the
constraints arising from a (static e) form. The implication has
a special ic_info field of StaticFormSkol, which tells the constraint
solver to use an empty set of Givens.
See (SF3) in Note [Grand plan for static forms]
in GHC.Iface.Tidy.StaticPtrTable
This commit also reinstates an `assert` in GHC.Tc.Solver.Equality.
The test `StaticPtrTypeFamily` was failing with an assertion failure,
but it now works.
- - - - -
2e2aec1e by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Comments about defaulting representation equalities
- - - - -
52a4d1da by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Improve tracking of rewriter-sets
This refactor substantially improves the treatment of so-called
"rewriter-sets" in the constraint solver.
The story is described in the rewritten
Note [Wanteds rewrite Wanteds: rewriter-sets]
in GHC.Tc.Types.Constraint
Some highlights
* Trace the free coercion holes of a filled CoercionHole,
in CoercionPlusHoles. See Note [Coercion holes] (COH5)
This avoids taking having to take the free coercion variables
of a coercion when zonking a rewrriter-set
* Many knock on changes
* Make fillCoercionHole take CoercionPlusHoles as its argument
rather than to separate arguments.
* Similarly setEqIfWanted, setWantedE, wrapUnifierAndEmit.
* Be more careful about passing the correct CoHoleSet to
`rewriteEqEvidence` and friends
* Make kickOurAfterFillingCoercionHole more clever. See
new Note [Kick out after filling a coercion hole]
Smaller matters
* Rename RewriterSet to CoHoleSet
* Add special-case helper `rewriteEqEvidenceSwapOnly`
- - - - -
3e78e1ba by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Tidy up constraint solving for foralls
* In `can_eq_nc_forall` make sure to track Givens that are used
in the nested solve step.
* Tiny missing-swap bug-fix in `lookup_eq_in_qcis`
* Fix some leftover mess from
commit 14123ee646f2b9738a917b7cec30f9d3941c13de
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Wed Aug 20 00:35:48 2025 +0100
Solve forall-constraints via an implication, again
Specifically, trySolveImplication is now dead.
- - - - -
973f2c25 by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Do not treat CoercionHoles as free variables in coercions
This fixes a long-standing wart in the free-variable finder;
now CoercionHoles are no longer treated as a "free variable"
of a coercion.
I got big and unexpected performance regressions when making
this change. Turned out that CallArity didn't discover that
the free variable finder could be eta-expanded, which gave very
poor code.
So I re-used Note [The one-shot state monad trick] for Endo,
resulting in GHC.Utils.EndoOS. Very simple, big win.
- - - - -
c2b8a0f9 by Simon Peyton Jones at 2025-11-03T08:33:05+00:00
Update debug-tracing in CallArity
No effect on behaviour, and commented out anyway
- - - - -
9aa5ee99 by Simon Peyton Jones at 2025-11-03T08:33:28+00:00
Comments only -- remove dangling Note references
- - - - -
6683f183 by Simon Peyton Jones at 2025-11-03T08:33:28+00:00
Accept error message wibbles
- - - - -
3ba3d9f9 by Luite Stegeman at 2025-11-04T00:59:41-05:00
rts: fix eager black holes: record mutated closure and fix assertion
This fixes two problems with handling eager black holes, introduced
by a1de535f762bc23d4cf23a5b1853591dda12cdc9.
- the closure mutation must be recorded even for eager black holes,
since the mutator has mutated it before calling threadPaused
- The assertion that an unmarked eager black hole must be owned by
the TSO calling threadPaused is incorrect, since multiple threads
can race to claim the black hole.
fixes #26495
- - - - -
b5508f2c by Rodrigo Mesquita at 2025-11-04T14:10:56+00:00
build: Relax ghc/ghc-boot Cabal bound to 3.16
Fixes #26202
- - - - -
c5b3541f by Rodrigo Mesquita at 2025-11-04T14:10:56+00:00
cabal-reinstall: Use haddock-api +in-tree-ghc
Fixes #26202
- - - - -
c6d4b945 by Rodrigo Mesquita at 2025-11-04T14:10:56+00:00
cabal-reinstall: Pass --strict to Happy
This is necessary to make the generated Parser build successfully
This mimics Hadrian, which always passes --strict to happy.
Fixes #26202
- - - - -
79df1e0e by Rodrigo Mesquita at 2025-11-04T14:10:56+00:00
genprimopcode: Require higher happy version
I've bumped the happy version to forbid deprecated Happy versions which
don't successfully compile.
- - - - -
fa5d33de by Simon Peyton Jones at 2025-11-05T08:35:40-05:00
Add a HsWrapper optimiser
This MR addresses #26349, by introduceing optSubTypeHsWrapper.
There is a long
Note [Deep subsumption and WpSubType]
in GHC.Tc.Types.Evidence that explains what is going on.
- - - - -
ea58cae5 by Simon Peyton Jones at 2025-11-05T08:35:40-05:00
Improve mkWpFun_FRR
This commit ensures that `mkWpFun_FRR` directly produces a `FunCo` in
the cases where it can.
(Previously called `mkWpFun` which in turn optimised to a `FunCo`, but
that made the smarts in `mkWpFun` /essential/ rather than (as they
should be) optional.
- - - - -
5cdcfaed by Ben Gamari at 2025-11-06T09:01:36-05:00
compiler: Exclude units with no exposed modules from unused package check
Such packages cannot be "used" in the Haskell sense of the word yet
are nevertheless necessary as they may provide, e.g., C object code or
link flags.
Fixes #24120.
- - - - -
74b8397a by Brandon Chinn at 2025-11-06T09:02:19-05:00
Replace deprecated argparse.FileType
- - - - -
36ddf988 by Ben Gamari at 2025-11-06T09:03:01-05:00
Bump unix submodule to 2.8.8.0
Closes #26474.
- - - - -
c32b3a29 by fendor at 2025-11-06T09:03:43-05:00
Fix assertion in `postStringLen` to account for \0 byte
We fix the assertion to handle trailing \0 bytes in `postStringLen`.
Before this change, the assertion looked like this:
ASSERT(eb->begin + eb->size > eb->pos + len + 1);
Let's assume some values to see why this is actually off by one:
eb->begin = 0
eb->size = 1
eb->pos = 0
len = 1
then the assertion would trigger correctly:
0 + 1 > 0 + 1 + 1 => 1 > 2 => false
as there is not enough space for the \0 byte (which is the trailing +1).
However, if we change `eb->size = 2`, then we do have enough space for a
string of length 1, but the assertion still fails:
0 + 2 > 0 + 1 + 1 => 2 > 2 => false
Which causes the assertion to fail if there is exactly enough space for
the string with a trailing \0 byte.
Clearly, the assertion should be `>=`!
If we switch around the operand, it should become more obvious that `<=`
is the correct comparison:
ASSERT(eb->pos + len + 1 <= eb->begin + eb->size);
This is expresses more naturally that the current position plus the
length of the string (and the null byte) must be smaller or equal to the
overall size of the buffer.
This change also is in line with the implementation in
`hasRoomForEvent` and `hasRoomForVariableEvent`:
```
StgBool hasRoomForEvent(EventsBuf *eb, EventTypeNum eNum)
{
uint32_t size = ...;
if (eb->pos + size > eb->begin + eb->size)
...
```
the check `eb->pos + size > eb->begin + eb->size` is identical to
`eb->pos + size <= eb->begin + eb->size` plus a negation.
- - - - -
3034a6f2 by Ben Gamari at 2025-11-06T09:04:24-05:00
Bump os-string submodule to 2.0.8
- - - - -
39567e85 by Cheng Shao at 2025-11-06T09:05:06-05:00
rts: use computed goto for instruction dispatch in the bytecode interpreter
This patch uses computed goto for instruction dispatch in the bytecode
interpreter. Previously instruction dispatch is done by a classic
switch loop, so executing the next instruction requires two jumps: one
to the start of the switch loop and another to the case block based on
the instruction tag. By using computed goto, we can build a jump table
consisted of code addresses indexed by the instruction tags
themselves, so executing the next instruction requires only one jump,
to the destination directly fetched from the jump table.
Closes #12953.
- - - - -
93fc7265 by sheaf at 2025-11-06T21:33:24-05:00
Correct hasFixedRuntimeRep in matchExpectedFunTys
This commit fixes a bug in the representation-polymormorphism check in
GHC.Tc.Utils.Unify.matchExpectedFunTys. The problem was that we put
the coercion resulting from hasFixedRuntimeRep in the wrong place,
leading to the Core Lint error reported in #26528.
The change is that we have to be careful when using 'mkWpFun': it
expects **both** the expected and actual argument types to have a
syntactically fixed RuntimeRep, as explained in Note [WpFun-FRR-INVARIANT]
in GHC.Tc.Types.Evidence.
On the way, this patch improves some of the commentary relating to
other usages of 'mkWpFun' in the compiler, in particular in the view
pattern case of 'tc_pat'. No functional changes, but some stylistic
changes to make the code more readable, and make it easier to understand
how we are upholding the WpFun-FRR-INVARIANT.
Fixes #26528
- - - - -
c052c724 by Simon Peyton Jones at 2025-11-06T21:34:06-05:00
Fix a horrible shadowing bug in implicit parameters
Fixes #26451. The change is in GHC.Tc.Solver.Monad.updInertDicts
where we now do /not/ delete /Wanted/ implicit-parameeter constraints.
This bug has been in GHC since 9.8! But it's quite hard to provoke;
I contructed a tests in T26451, but it was hard to do so.
- - - - -
b253013e by Georgios Karachalias at 2025-11-07T17:21:57-05:00
Remove the `CoreBindings` constructor from `LinkablePart`
Adjust HscRecompStatus to disallow unhydrated WholeCoreBindings
from being passed as input to getLinkDeps (which would previously
panic in this case).
Fixes #26497
- - - - -
ac7b737e by Sylvain Henry at 2025-11-07T17:22:51-05:00
Testsuite: pass ext-interp test way (#26552)
Note that some tests are still marked as broken with the ext-interp way
(see #26552 and #14335)
- - - - -
3c2f4bb4 by sheaf at 2025-11-11T11:47:28-05:00
Preserve user-written kinds in data declarations
This commit ensures that we preserve the user-written kind for data
declarations, e.g. in
type T2T = Type -> Type
type D :: T2T
data D a where { .. }
that we preserve the user-written kind of D as 'T2T', instead of
expanding the type synonym 'T2T' during kind checking.
We do this by storing 'tyConKind' separately from 'tyConResKind'. This
means that 'tyConKind' is not necessarily equal to
'mkTyConKind binders res_kind', as e.g. in the above example the former
is 'T2T' while the latter is 'Type -> Type'.
This is explained in Note [Preserve user-written TyCon kind] in GHC.Core.TyCon.
This is particularly important for Haddock, as the kinds stored in
interface files affect the generated documentation, and we want to
preserve the user-written types as much as possible.
- - - - -
19859584 by sheaf at 2025-11-11T11:47:28-05:00
Store user-written datacon tvs in interface files
This commit ensures we store the user-written quantified type variables
of data constructors in interface files, e.g. in
data D a where
MkD1 :: forall x. x -> D x
MkD2 :: forall u v. u -> v -> D v
The previous behaviour was to rename the universal variables to match
the universal variables of the data constructor. This was undesirable
because the names that end up in interface files end up mattering for
generated Haddock documentation; it's better to preserve the user-written
type variables.
Moreover, the universal variables may not have been user-written at all,
e.g. in an example such as:
type T2T = Type -> Type
data G :: T2T where
MkG :: forall x. D x
Here GHC will invent the type variable name 'a' for the first binder of
the TyCon G. We really don't want to then rename the user-written 'x'
into the generated 'a'.
- - - - -
034b2056 by sheaf at 2025-11-11T11:47:28-05:00
DataCon univ_tvs names: pick TyCon over inferred
This commit changes how we compute the names of universal type variables
in GADT data constructors. This augments the existing logic that chose
which type variable name to use, in GHC.Tc.TyCl.mkGADTVars. We continue
to prefer DataCon tv names for user-written binders, but we now prefer
TyCon tv names for inferred (non-user-written) DataCon binders.
This makes a difference in examples such as:
type (:~~:) :: k1 -> k2 -> Type
data a :~~: b where
HRefl :: a :~~: a
Before this patch, we ended up giving HRefl the type:
forall {k2}. forall (a :: k2). a :~~: a
whereas we now give it the type:
forall {k1}. forall (a :: k1). a :~~: a
The important part isn't really 'k1' or 'k2', but more that the inferred
type variable names of the DataCon can be arbitrary/unpredictable (as
they are chosen by GHC and depend on how unification proceeds), so it's
much better to use the more predictable TyCon type variable names.
- - - - -
95078d00 by sheaf at 2025-11-11T11:47:28-05:00
Backpack Rename: use explicit record construction
This commit updates the Backpack boilerplate in GHC.Iface.Rename to
use explicit record construction rather than record update. This makes
sure that the code stays up to date when the underlying constructors
change (e.g. new fields are added). The rationale is further explained
in Note [Prefer explicit record construction].
- - - - -
2bf36263 by sheaf at 2025-11-11T11:47:28-05:00
Store # eta binders in TyCon and use for Haddock
This commit stores the number of TyCon binders that were introduced by
eta-expansion (by the function GHC.Tc.Gen.HsType.splitTyConKind).
This is then used to pretty-print the TyCon as the user wrote it, e.g.
for
type Effect :: (Type -> Type) -> Type -> Type
data State s :: Effect where {..} -- arity 3
GHC will eta-expand the data declaration to
data State s a b where {..}
but also store in the 'TyCon' that the number of binders introduced by
this eta expansion is 2. This allows us, in
'Haddock.Convert.synifyTyConKindSig', to recover the original user-written
syntax, preserving the user's intent in Haddock documentation.
See Note [Inline kind signatures with GADTSyntax] in Haddock.Convert.
- - - - -
6c91582f by Matthew Pickering at 2025-11-11T11:48:12-05:00
driver: Properly handle errors during LinkNode steps
Previously we were not properly catching errors during the LinkNode step
(see T9930fail test).
This is fixed by wrapping the `LinkNode` action in `wrapAction`, the
same handler which is used for module compilation.
Fixes #26496
- - - - -
e1e1eb32 by Matthew Pickering at 2025-11-11T11:48:54-05:00
driver: Remove unecessary call to hscInsertHPT
This call was left-over from e9445c013fbccf9318739ca3d095a3e0a2e1be8a
If you follow the functions which call `upsweep_mod`, they immediately
add the interface to the HomePackageTable when `upsweep_mod` returns.
- - - - -
b22777d4 by ARATA Mizuki at 2025-11-11T11:49:44-05:00
LLVM backend: Pass the +evex512 attribute to LLVM 18+ if -mavx512f is set
The newer LLVM requires the +evex512 attribute to enable use of ZMM registers.
LLVM exhibits a backward-compatible behavior if the cpu is `x86-64`, but not if `penryn`.
Therefore, on macOS, where the cpu is set to `penryn`, we need to explicitly pass +evex512.
Fixes #26410
- - - - -
6ead7d06 by Vladislav Zavialov at 2025-11-11T11:50:26-05:00
Comments only in GHC.Parser.PostProcess.Haddock
Remove outdated Note [Register keyword location], as the issue it describes
was addressed by commit 05eb50dff2fcc78d025e77b9418ddb369db49b9f.
- - - - -
43fa8be8 by sheaf at 2025-11-11T11:51:18-05:00
localRegistersConflict: account for assignment LHS
This commit fixes a serious oversight in GHC.Cmm.Sink.conflicts,
specifically the code that computes which local registers conflict
between an assignment and a Cmm statement.
If we have:
assignment: <local_reg> = <expr>
node: <local_reg> = <other_expr>
then clearly the two conflict, because we cannot move one statement past
the other, as they assign two different values to the same local
register. (Recall that 'conflicts (local_reg,expr) node' is False if and
only if the assignment 'local_reg = expr' can be safely commuted past
the statement 'node'.)
The fix is to update 'GHC.Cmm.Sink.localRegistersConflict' to take into
account the following two situations:
(1) 'node' defines the LHS local register of the assignment,
(2) 'node' defines a local register used in the RHS of the assignment.
The bug is precisely that we were previously missing condition (1).
Fixes #26550
- - - - -
79dfcfe0 by sheaf at 2025-11-11T11:51:18-05:00
Update assigned register format when spilling
When we come to spilling a register to put new data into it, in
GHC.CmmToAsm.Reg.Linear.allocRegsAndSpill_spill, we need to:
1. Spill the data currently in the register. That is, do a spill
with a format that matches what's currently in the register.
2. Update the register assignment, allocating a virtual register to
this real register, but crucially **updating the format** of this
assignment.
Due to shadowing in the Haskell code for allocRegsAndSpill_spill, we
were mistakenly re-using the old format. This could lead to a situation
where:
a. We were using xmm6 to store a Double#.
b. We want to store a DoubleX2# into xmm6, so we spill the current
content of xmm6 to the stack using a scalar move (correct).
c. We update the register assignment, but we fail to update the format
of the assignment, so we continue to think that xmm6 stores a
Double# and not a DoubleX2#.
d. Later on, we need to spill xmm6 because it is getting clobbered by
another instruction. We then decide to only spill the lower 64 bits
of the register, because we still think that xmm6 only stores a
Double# and not a DoubleX2#.
Fixes #26542
- - - - -
aada5db9 by ARATA Mizuki at 2025-11-11T11:52:07-05:00
Fix the order of spill/reload instructions
The AArch64 NCG could emit multiple instructions for a single spill/reload,
but their order was not consistent between the definition and a use.
Fixes #26537
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
64ec82ff by Andreas Klebinger at 2025-11-11T11:52:48-05:00
Add hpc to release script
- - - - -
741da00c by Ben Gamari at 2025-11-12T03:38:20-05:00
template-haskell: Better describe getQ semantics
Clarify that the state is a type-indexed map, as suggested by #26484.
- - - - -
8b080e04 by ARATA Mizuki at 2025-11-12T03:39:11-05:00
Fix incorrect markups in the User's Guide
* Correct markup for C--: "C-\-" in reST
* Fix internal links
* Fix code highlighting
* Fix inline code: Use ``code`` rather than `code`
* Remove extra backslashes
Fixes #16812
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
a00840ea by Simon Peyton Jones at 2025-11-14T15:23:56+00:00
Make TYPE and CONSTRAINT apart again
This patch finally fixes #24279.
* The story started with #11715
* Then #21623 articulated a plan, which made Type and Constraint
not-apart; a horrible hack but it worked. The main patch was
commit 778c6adca2c995cd8a1b84394d4d5ca26b915dac
Author: Simon Peyton Jones <simonpj(a)microsoft.com>
Date: Wed Nov 9 10:33:22 2022 +0000
Type vs Constraint: finally nailed
* #24279 reported a bug in the above big commit; this small patch fixes it
commit af6932d6c068361c6ae300d52e72fbe13f8e1f18
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jan 8 10:49:49 2024 +0000
Make TYPE and CONSTRAINT not-apart
Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty
which is supposed to make TYPE and CONSTRAINT be not-apart.
* Then !10479 implemented "unary classes".
* That change in turn allows us to make Type and Constraint apart again,
cleaning up the compiler and allowing a little bit more expressiveness.
It fixes the original hope in #24279, namely that `Type` and `Constraint`
should be distinct throughout.
- - - - -
c0a1e574 by Georgios Karachalias at 2025-11-15T05:14:31-05:00
Report all missing modules with -M
We now report all missing modules at once in GHC.Driver.Makefile.processDeps,
as opposed to only reporting a single missing module. Fixes #26551.
- - - - -
c9fa3449 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: fix array index for registers
We used to store R32 in h$regs[-1]. While it's correct in JavaScript,
fix this to store R32 in h$regs[0] instead.
- - - - -
9e469909 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: support more than 128 registers (#26558)
The JS backend only supported 128 registers (JS variables/array slots
used to pass function arguments). It failed in T26537 when 129
registers were required.
This commit adds support for more than 128 registers: it is now limited to
maxBound :: Int (compiler's Int). If we ever go above this threshold the
compiler now panics with a more descriptive message.
A few built-in JS functions were assuming 128 registers and have been
rewritten to use loops. Note that loops are only used for "high"
registers that are stored in an array: the 31 "low" registers are still
handled with JS global variables and with explicit switch-cases to
maintain good performance in the most common cases (i.e. few registers
used). Adjusting the number of low registers is now easy: just one
constant to adjust (GHC.StgToJS.Regs.lowRegsCount).
No new test added: T26537 is used as a regression test instead.
- - - - -
0a64a78b by Sven Tennie at 2025-11-15T20:31:10-05:00
AArch64: Simplify CmmAssign and CmmStore
The special handling for floats was fake: The general case is always
used. So, the additional code path isn't needed (and only adds
complexity for the reader.)
- - - - -
15b311be by sheaf at 2025-11-15T20:32:02-05:00
SimpleOpt: refactor & push coercions into lambdas
This commit improves the simple optimiser (in GHC.Core.SimpleOpt)
in a couple of ways:
- The logic to push coercion lambdas is shored up.
The function 'pushCoercionIntoLambda' used to be called in 'finish_app',
but this meant we could not continue to optimise the program after
performing this transformation.
Now, we call 'pushCoercionIntoLambda' as part of 'simple_app'.
Doing so can be important when dealing with unlifted newtypes,
as explained in Note [Desugaring unlifted newtypes].
- The code is re-structured to avoid duplication and out-of-sync
code paths.
Now, 'simple_opt_expr' defers to 'simple_app' for the 'App', 'Var',
'Cast' and 'Lam' cases. This means all the logic for those is
centralised in a single place (e.g. the 'go_lam' helper function).
To do this, the general structure is brought a bit closer to the
full-blown simplifier, with a notion of 'continuation'
(see 'SimpleContItem').
This commit also modifies GHC.Core.Opt.Arity.pushCoercionIntoLambda to
apply a substitution (a slight generalisation of its existing implementation).
- - - - -
b33284c7 by sheaf at 2025-11-15T20:32:02-05:00
Improve typechecking of data constructors
This commit changes the way in which we perform typecheck data
constructors, in particular how we make multiplicities line up.
Now, impedance matching occurs as part of the existing subsumption
machinery. See the revamped Note [Typechecking data constructors] in
GHC.Tc.Gen.App, as well as Note [Polymorphisation of linear fields]
in GHC.Core.Multiplicity.
This allows us to get rid of a fair amount of hacky code that was
added with the introduction of LinearTypes; in particular the logic of
GHC.Tc.Gen.Head.tcInferDataCon.
-------------------------
Metric Decrease:
T10421
T14766
T15164
T15703
T19695
T5642
T9630
WWRec
-------------------------
- - - - -
b6faf5d0 by sheaf at 2025-11-15T20:32:02-05:00
Handle unsaturated rep-poly newtypes
This commit allows GHC to handle unsaturated occurrences of unlifted
newtype constructors. The plan is detailed in
Note [Eta-expanding rep-poly unlifted newtypes]
in GHC.Tc.Utils.Concrete: for unsaturated unlifted newtypes, we perform
the appropriate representation-polymorphism check in tcInstFun.
- - - - -
682bf979 by Mike Pilgrem at 2025-11-16T16:44:14+00:00
Fix #26293 Valid stack.yaml for hadrian
- - - - -
acc70c3a by Simon Peyton Jones at 2025-11-18T16:21:20-05:00
Fix a bug in defaulting
Addresses #26582
Defaulting was doing some unification but then failing to
iterate. Silly.
I discovered that the main solver was unnecessarily iterating even
if there was a unification for an /outer/ unification variable, so
I fixed that too.
- - - - -
c12fa73e by Simon Peyton Jones at 2025-11-19T02:55:01-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
41b84f40 by sheaf at 2025-11-19T02:55:52-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
1faa758a by sheaf at 2025-11-19T02:55:52-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
55eab80d by Sylvain Henry at 2025-11-20T17:33:13-05:00
Build external interpreter program on demand (#24731)
This patch teaches GHC how to build the external interpreter program
when it is missing. As long as we have the `ghci` library, doing this is
trivial so most of this patch is refactoring for doing it sanely.
- - - - -
08bbc028 by Rodrigo Mesquita at 2025-11-20T17:33:54-05:00
Add tests for #23973 and #26565
These were fixed by 4af4f0f070f83f948e49ad5d7835fd91b8d3f0e6 in !10417
- - - - -
6b42232c by sheaf at 2025-11-20T17:34:35-05:00
Mark T26410_ffi as fragile on Windows
As seen in #26595, this test intermittently fails on Windows.
This commit marks it as fragile, until we get around to fixing it.
- - - - -
b7b7c049 by Andrew Lelechenko at 2025-11-21T21:04:01+00:00
Add nubOrd / nubOrdBy to Data.List and Data.List.NonEmpty
As per https://github.com/haskell/core-libraries-committee/issues/336
- - - - -
352d5462 by Marc Scholten at 2025-11-22T10:33:03-05:00
Fix haddock test runner to handle UTF-8 output
xhtml 3000.4.0.0 now produces UTF-8 output instead of escaping non-ASCII characters.
When using --test-accept it previously wrote files in the wrong encoding
because they have not been decoded properly when reading the files.
- - - - -
48a3ed57 by Simon Peyton Jones at 2025-11-25T15:33:54+00:00
Add a fast-path for args=[] to occAnalApp
In the common case of having not arguments, occAnalApp
was doing redundant work.
- - - - -
951e5ed9 by Simon Peyton Jones at 2025-11-25T15:33:54+00:00
Fix a performance hole in the occurrence analyser
As #26425 showed, the clever stuff in
Note [Occurrence analysis for join points]
does a lot of duplication of usage details. This patch
improved matters with a little fancy footwork. It is
described in the new (W4) of the same Note.
Compile-time allocations go down slightly. Here are the changes
of +/- 0.5% or more:
T13253(normal) 329,369,244 326,395,544 -0.9%
T13253-spj(normal) 66,410,496 66,095,864 -0.5%
T15630(normal) 129,797,200 128,663,136 -0.9%
T15630a(normal) 129,212,408 128,027,560 -0.9%
T16577(normal) 6,756,706,896 6,723,028,512 -0.5%
T18282(normal) 128,462,070 125,808,584 -2.1% GOOD
T18698a(normal) 208,418,305 202,037,336 -3.1% GOOD
T18730(optasm) 136,981,756 136,208,136 -0.6%
T18923(normal) 58,103,088 57,745,840 -0.6%
T19695(normal) 1,386,306,272 1,365,609,416 -1.5%
T26425(normal) 3,344,402,957 2,457,811,664 -26.5% GOOD
T6048(optasm) 79,763,816 79,212,760 -0.7%
T9020(optasm) 225,278,408 223,682,440 -0.7%
T9961(normal) 303,810,717 300,729,168 -1.0% GOOD
geo. mean -0.5%
minimum -26.5%
maximum +0.4%
Metric Decrease:
T18282
T18698a
T26425
T9961
- - - - -
f1959dfc by Simon Peyton Jones at 2025-11-26T11:58:07+00:00
Remove a quadratic-cost assertion check in mkCoreApp
See the new Note [Assertion checking in mkCoreApp]
- - - - -
98fa0d36 by Simon Hengel at 2025-11-27T17:54:57-05:00
Fix typo in docs/users_guide/exts/type_families.rst
- - - - -
5b97e5ce by Simon Hengel at 2025-11-27T17:55:37-05:00
Fix broken RankNTypes example in user's guide
- - - - -
fa2aaa00 by Simon Peyton Jones at 2025-11-27T17:56:18-05:00
Switch off specialisation in ExactPrint
In !15057 (where we re-introduced -fpolymoprhic-specialisation) we found
that ExactPrint's compile time blew up by a factor of 5. It turned out
to be caused by bazillions of specialisations of `markAnnotated`.
Since ExactPrint isn't perf-critical, it does not seem worth taking
the performance hit, so this patch switches off specialisation in
this one module.
- - - - -
1fd25987 by Simon Peyton Jones at 2025-11-27T17:56:18-05:00
Switch -fpolymorphic-specialisation on by default
This patch addresses #23559.
Now that !10479 has landed and #26329 is fixed, we can switch on
polymorphic specialisation by default, addressing a bunch of other
tickets listed in #23559.
Metric changes:
* CoOpt_Singleton: +4% compiler allocations: we just get more
specialisations
* info_table_map_perf: -20% decrease in compiler allocations.
This is caused by using -fno-specialise in ExactPrint.hs
Without that change we get a 4x blow-up in compile time;
see !15058 for details
Metric Decrease:
info_table_map_perf
Metric Increase:
CoOpt_Singletons
- - - - -
b7fe7445 by Matthew Pickering at 2025-11-27T17:56:59-05:00
rts: Fix a deadlock with eventlog flush interval and RTS shutdown
The ghc_ticker thread attempts to flush at the eventlog tick interval, this requires
waiting to take all capabilities.
At the same time, the main thread is shutting down, the schedule is
stopped and then we wait for the ticker thread to finish.
Therefore we are deadlocked.
The solution is to use `newBoundTask/exitMyTask`, so that flushing can
cooperate with the scheduler shutdown.
Fixes #26573
- - - - -
1d4a1229 by sheaf at 2025-11-27T17:58:02-05:00
SimpleOpt: don't subst in pushCoercionIntoLambda
It was noticed in #26589 that the change in 15b311be was incorrect:
the simple optimiser carries two different substitution-like pieces of
information: 'soe_subst' (from InVar to OutExpr) and 'soe_inl'
(from InId to InExpr). It is thus incorrect to have 'pushCoercionIntoLambda'
apply the substitution from 'soe_subst' while discarding 'soe_inl'
entirely, which is what was done in 15b311be.
Instead, we change back pushCoercionIntoLambda to take an InScopeSet,
and optimise the lambda before calling 'pushCoercionIntoLambda' to avoid
mixing InExpr with OutExpr, or mixing two InExpr with different
environments. We can then call 'soeZapSubst' without problems.
Fixes #26588 #26589
- - - - -
84a087d5 by Sylvain Henry at 2025-11-28T17:35:28-05:00
Fix PIC jump tables on Windows (#24016)
Avoid overflows in jump tables by using a base label closer to the jump
targets. See added Note [Jump tables]
- - - - -
82db7042 by Zubin Duggal at 2025-11-28T17:36:10-05:00
rts/linker/PEi386: Copy strings before they are inserted into LoadedDllCache. The original strings are temporary and might be freed at an arbitrary point.
Fixes #26613
- - - - -
ff3f0d09 by Ben Gamari at 2025-11-29T18:34:28-05:00
gitlab-ci: Run ghcup-metadata jobs on OpenCape runners
This significantly reduces our egress traffic
and makes the jobs significantly faster.
- - - - -
ef0dc33b by Matthew Pickering at 2025-11-29T18:35:10-05:00
Use 'OsPath' in getModificationTimeIfExists
This part of the compiler is quite hot during recompilation checking in
particular since the filepaths will be translated to a string. It is
better to use the 'OsPath' native function, which turns out to be easy
to do.
- - - - -
fa3bd0a6 by Georgios Karachalias at 2025-11-29T18:36:05-05:00
Use OsPath in PkgDbRef and UnitDatabase, not FilePath
- - - - -
0d7c05ec by Ben Gamari at 2025-12-01T03:13:46-05:00
hadrian: Place user options after package arguments
This makes it easier for the user to override the default package
arguments with `UserSettings.hs`.
Fixes #25821.
-------------------------
Metric Decrease:
T14697
-------------------------
- - - - -
3b2c4598 by Vladislav Zavialov at 2025-12-01T03:14:29-05:00
Namespace-specified wildcards in import/export lists (#25901)
This change adds support for top-level namespace-specified wildcards
`type ..` and `data ..` to import and export lists.
Examples:
import M (type ..) -- imports all type and class constructors from M
import M (data ..) -- imports all data constructors and terms from M
module M (type .., f) where
-- exports all type and class constructors defined in M,
-- plus the function 'f'
The primary intended usage of this feature is in combination with module
aliases, allowing namespace disambiguation:
import Data.Proxy as T (type ..) -- T.Proxy is unambiguously the type constructor
import Data.Proxy as D (data ..) -- D.Proxy is unambiguously the data constructor
The patch accounts for the interactions of wildcards with:
* Imports with `hiding` clauses
* Import warnings -Wunused-imports, -Wdodgy-imports
* Export warnings -Wduplicate-exports, -Wdodgy-exports
Summary of the changes:
1. Move the NamespaceSpecifier type from GHC.Hs.Binds to GHC.Hs.Basic,
making it possible to use it in more places in the AST.
2. Extend the AST (type: IE) with a representation of `..`, `type ..`,
and `data ..` (constructor: IEWholeNamespace). Per the proposal, the
plain `..` is always rejected with a dedicated error message.
3. Extend the grammar in Parser.y with productions for `..`, `type ..`,
and `data ..` in both import and export lists.
4. Implement wildcard imports by updating the `filterImports` function
in GHC.Rename.Names; the logic for IEWholeNamespace is roughly
modeled after the Nothing (no explicit import list) case.
5. Implement wildcard exports by updating the `exports_from_avail`
function in GHC.Tc.Gen.Export; the logic for IEWholeNamespace is
closely modeled after the IEModuleContents case.
6. Refactor and extend diagnostics to report the new warnings and
errors. See PsErrPlainWildcardImport, DodgyImportsWildcard,
PsErrPlainWildcardExport, DodgyExportsWildcard,
TcRnDupeWildcardExport.
Note that this patch is specifically about top-level import/export
items. Subordinate import/export items are left unchanged.
- - - - -
c71faa76 by Luite Stegeman at 2025-12-01T03:16:05-05:00
rts: Handle overflow of ELF section header string table
If the section header string table is stored in a section greater
than or equal to SHN_LORESERVE (0xff00), the 16-bit field e_shstrndx
in the ELF header does not contain the section number, but rather
an overflow value SHN_XINDEX (0xffff) indicating that we need to look
elsewhere.
This fixes the linker by not using e_shstrndx directly but calling
elf_shstrndx, which correctly handles the SHN_XINDEX value.
Fixes #26603
- - - - -
ab20eb54 by Mike Pilgrem at 2025-12-01T22:46:55+00:00
Re CLC issue 292 Warn GHC.Internal.List.{init,last} are partial
Also corrects the warning for `tail` to refer to `Data.List.uncons` (like the existing warning for `head`).
In module `Settings.Warnings`, applies `-Wno-x-partial` to the `filepath`, and `parsec` packages (outside GHC's repository).
Also bumps submodules.
- - - - -
fc1d7f79 by Jade Lovelace at 2025-12-02T11:04:09-05:00
docs: fix StandaloneKindSignatures in DataKinds docs
These should be `type` as otherwise GHC reports a duplicate definition
error.
- - - - -
beae879b by Rodrigo Mesquita at 2025-12-03T15:42:37+01:00
task: Substitute some datatypes for newtypes
* Substitutes some data type declarations for newtype declarations
* Adds comment to `LlvmConfigCache`, which must decidedly not be a
newtype.
Fixes #23555
- - - - -
3bd7dd44 by mangoiv at 2025-12-04T04:36:45-05:00
Renamer: reinstate the template haskell level check in notFound
Out-of-scope names might be caused by a staging error, as is explained by
Note [Out of scope might be a staging error] in GHC.Tc.Utils.Env.hs.
This logic was assumed to be dead code after 217caad1 and has thus been
removed. This commit reintroduces it and thus fixes issue #26099.
- - - - -
0318010b by Zubin Duggal at 2025-12-04T04:37:27-05:00
testlib: Optionally include the way name in the expected output file
This allows us to have different outputs for different ways.
- - - - -
6d945fdd by Zubin Duggal at 2025-12-04T04:37:27-05:00
testsuite: Accept output of tests failing in ext-interp way due to differing compilation requirements
Fixes #26552
- - - - -
0ffc5243 by Cheng Shao at 2025-12-04T04:38:09-05:00
devx: minor fixes for compile_flags.txt
This patch includes minor fixes for compile_flags.txt to improve
developer experience when using clangd as language server to hack on
RTS C sources:
- Ensure `-fPIC` is passed and `__PIC__` is defined, to be coherent
with `-DDYNAMIC` and ensure the `__PIC__` guarded code paths are
indexed
- Add the missing `-DRtsWay` definition, otherwise a few source files
like `RtsUtils.c` and `Trace.c` would produce clangd errors
- - - - -
e36a5fcb by Matthew Pickering at 2025-12-05T16:25:57-05:00
Add support for building bytecode libraries
A bytecode library is a collection of bytecode files (.gbc) and a
library which combines together additional object files.
A bytecode library is created by invoking GHC with the `-bytecodelib`
flag.
A library can be created from in-memory `ModuleByteCode` linkables or
by passing `.gbc` files as arguments on the command line.
Fixes #26298
- - - - -
8f9ae339 by Matthew Pickering at 2025-12-05T16:25:57-05:00
Load bytecode libraries to satisfy package dependencies
This commit allows you to use a bytecode library to satisfy a package
dependency when using the interpreter.
If a user enables `-fprefer-byte-code`, then if a package provides a
bytecode library, that will be loaded and used to satisfy the
dependency.
The main change is to separate the relevant parts of the `LoaderState`
into external and home package byte code. Bytecode is loaded into either
the home package or external part (similar to HPT/EPS split), HPT
bytecode can be unloaded. External bytecode is never unloaded.
The unload function has also only been called with an empty list of
"stable linkables" for a long time. It has been modified to directly
implement a complete unloading of the home package bytecode linkables.
At the moment, the bytecode libraries are found in the "library-dirs"
field from the package description. In the future when `Cabal`
implements support for "bytecode-library-dirs" field, we can read the
bytecode libraries from there. No changes to the Cabal submodule are
necessary at the moment.
Four new tests are added in testsuite/tests/cabal, which generate fake
package descriptions and test loading the libraries into GHCi.
Fixes #26298
- - - - -
54458ce4 by mangoiv at 2025-12-05T16:26:50-05:00
ExplicitLevelImports: improve documentation of the code
- more explicit names for variable names like `flg` or `topLevel`
- don't pass the same value twice to functions
- some explanations of interesting but undocumented code paths
- adjust comment to not mention non-existent error message
- - - - -
c7061392 by mangoiv at 2025-12-05T16:27:42-05:00
driver: don't expect nodes to exist when checking paths between them
In `mgQueryZero`, previously node lookups were expected to never fail,
i.e. it was expected that when calculating the path between two nodes in
a zero level import graph, both nodes would always exist. This is not
the case, e.g. in some situations involving exact names (see the
test-case). The fix is to first check whether the node is present in the
graph at all, instead of panicking, just to report that there is no
path.
Closes #26568
- - - - -
d6cf8463 by Peng Fan at 2025-12-06T11:06:28-05:00
NCG/LA64: Simplify genCCall into two parts
genCCall is too long, so it's been simplified into two parts:
genPrim and genLibCCall.
Suggested by Andreas Klebinger
- - - - -
9d371d23 by Matthew Pickering at 2025-12-06T11:07:09-05:00
hadrian: Use a response file to invoke GHC for dep gathering.
In some cases we construct an argument list too long for GHC to
handle directly on windows. This happens when we generate
the dependency file because the command line will contain
references to a large number of .hs files.
To avoid this we now invoke GHC using a response file when
generating dependencies to sidestep length limitations.
Note that we only pass the actual file names in the dependency
file. Why? Because this side-steps #26560
- - - - -
0043bfb0 by Marc Scholten at 2025-12-06T11:08:03-05:00
update xhtml to 3000.4.0.0
haddock-api: bump xhtml bounds
haddock-api: use lazy text instead of string to support xhtml 3000.4.0.0
Bumping submodule xhtml to 3000.4.0.0
add xhtml to stage0Packages
remove unused import of writeUtf8File
Remove redundant import
Update haddock golden files for xhtml 3000.4.0.0
Metric Decrease:
haddock.Cabal
haddock.base
- - - - -
fc958fc9 by Julian Ospald at 2025-12-06T11:08:53-05:00
rts: Fix object file format detection in loadArchive
Commit 76d1041dfa4b96108cfdd22b07f2b3feb424dcbe seems to
have introduced this bug, ultimately leading to failure of
test T11788. I can only theorize that this test isn't run
in upstream's CI, because they don't build a static GHC.
The culprit is that we go through the thin archive, trying
to follow the members on the filesystem, but don't
re-identify the new object format of the member. This pins
`object_fmt` to `NotObject` from the thin archive.
Thanks to @angerman for spotting this.
- - - - -
0f297f6e by mangoiv at 2025-12-06T11:09:44-05:00
users' guide: don't use f strings in the python script to ensure compatibility with python 3.5
- - - - -
3bfe7aa2 by Matthew Pickering at 2025-12-07T12:18:57-05:00
ci: Try using multi repl in ghc-in-ghci test
This should be quite a bit faster than the ./hadrian/ghci command as it
doesn't properly build all the dependencies.
- - - - -
2ef1601a by Rodrigo Mesquita at 2025-12-07T12:19:38-05:00
Stack.Decode: Don't error on bitmap size 0
A RET_BCO may have a bitmap with no payload.
In that case, the bitmap = 0.
One can observe this by using -ddump-bcos and interpreting
```
main = pure ()
```
Observe, for instance, that the BCO for this main function has size 0:
```
ProtoBCO Main.main#0:
\u []
break<main:Main,0>() GHC.Internal.Base.pure
GHC.Internal.Base.$fApplicativeIO GHC.Internal.Tuple.()
bitmap: 0 []
BRK_FUN <breakarray> main:Main 0 <cc>
PACK () 0
PUSH_G GHC.Internal.Base.$fApplicativeIO
PUSH_APPLY_PP
PUSH_G GHC.Internal.Base.pure
ENTER
```
Perhaps we never tried to decode a stack in which a BCO like this was
present. However, for the debugger, we want to decode stacks of threads
stopped at breakpoints, and these kind of BCOs do get on a stack under
e.g. `stg_apply_interp_info` frames.
See the accompanying test in the next commit for an example to trigger
the bug this commit fixes.
Fixes #26640
- - - - -
747153d2 by Rodrigo Mesquita at 2025-12-07T12:19:38-05:00
Add test for #26640
- - - - -
d4b1e353 by Simon Hengel at 2025-12-10T00:00:02-05:00
Fix syntax error in gadt_syntax.rst
- - - - -
91cc8be6 by Cheng Shao at 2025-12-10T00:00:43-05:00
ci: fix "ci.sh clean" to address frequent out of space error on windows runners
This patch fixes the `ci.sh clean` logic to address frequent out of
space error on windows runners; previously it didn't clean up the
inplace mingw blobs, which is the largest source of space leak on
windows runners. See added comment for detailed explanation.
- - - - -
fe2b79f4 by Recursion Ninja at 2025-12-10T08:34:18-05:00
Narrow before optimising MUL/DIV/REM into shifts
The MUL/DIV/REM operations can be optimised into shifts when one of the
operands is a constant power of 2. However, as literals in Cmm are
stored as 'Integer', for this to be correct we first need to narrow the
literal to the appropriate width before checking whether the literal is
a power of 2.
Fixes #25664
- - - - -
06c2349c by Recursion Ninja at 2025-12-10T08:34:58-05:00
Decouple 'Language.Haskell.Syntax.Type' from 'GHC.Utils.Panic'
- Remove the *original* defintion of 'hsQTvExplicit' defined within 'Language.Haskell.Syntax.Type'
- Redefine 'hsQTvExplicit' as 'hsq_explicit' specialized to 'GhcPass' exported by 'GHC.Utils.Panic'
- Define 'hsQTvExplicitBinders' as 'hsq_explicit' specialized to 'DocNameI' exported by 'Haddock.GhcUtils'.
- Replace all call sites of the original 'hsQTvExplicit' definition with either:
1. 'hsQTvExplicit' updated definition
2. 'hsQTvExplicitBinders'
All call sites never entered the 'XLHsQTyVars' constructor branch, but a call to 'panic' existed on this code path because the type system was not strong enought to guarantee that the 'XLHsQTyVars' construction was impossible.
These two specialized functions provide the type system with enough information to make that guarantee, and hence the dependancy on 'panic' can be removed.
- - - - -
ac0815d5 by sheaf at 2025-12-10T23:39:57-05:00
Quantify arg before mult in function arrows
As noted in #23764, we expect quantification order to be left-to-right,
so that in a type such as
a %m -> b
the inferred quantification order should be [a, m, b] and not [m, a, b].
This was addressed in commit d31fbf6c, but that commit failed to update
some other functions such as GHC.Core.TyCo.FVs.tyCoFVsOfType.
This affects Haddock, as whether we print an explicit forall or not
depends on whether the inferred quantification order matches the actual
quantification order.
- - - - -
2caf796e by sheaf at 2025-12-10T23:39:57-05:00
Haddock: improvements to ty-var quantification
This commit makes several improvements to how Haddock deals with the
quantification of type variables:
1. In pattern synonyms, Haddock used to jumble up universal and
existential quantification. That is now fixed, fixing #26252.
Tested in the 'PatternSyns2' haddock-html test.
2. The logic for computing whether to use an explicit kind annotation
for a type variable quantified in a forall was not even wrong.
This commit improves the heuristic, but it will always remain an
imperfect heuristic (lest we actually run kind inference again).
In the future (#26271), we hope to avoid reliance on this heuristic.
- - - - -
b14bdd59 by Teo Camarasu at 2025-12-10T23:40:38-05:00
Add explicit export list to GHC.Num
Let's make clear what this module exports to allow us to easily deprecate and remove some of these in the future. Resolves https://gitlab.haskell.org/ghc/ghc/-/issues/26625
- - - - -
d99f8326 by Cheng Shao at 2025-12-11T19:14:18-05:00
compiler: remove unused CPP code in foreign stub
This patch removes unused CPP code in the generated foreign stub:
- `#define IN_STG_CODE 0` is not needed, since `Rts.h` already
includes this definition
- The `if defined(__cplusplus)` code paths are not needed in the `.c`
file, since we don't generate C++ stubs and don't include C++
headers in our stubs. But it still needs to be present in the `.h`
header since it might be later included into C++ source files.
- - - - -
46c9746f by Cheng Shao at 2025-12-11T19:14:57-05:00
configure: bump LlvmMaxVersion to 22
This commit bumps LlvmMaxVersion to 22; 21.x releases have been
available since Aug 26th, 2025 and there's no regressions with 21.x so
far. This bump is also required for updating fedora image to 43.
- - - - -
96fce8d0 by Cheng Shao at 2025-12-12T01:17:51+01:00
hadrian: add support for building with UndefinedBehaviorSanitizer
This patch adds a +ubsan flavour transformer to hadrian to build all
stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is
particularly useful to catch potential undefined behavior in the RTS
codebase.
- - - - -
f7a06d8c by Cheng Shao at 2025-12-12T01:17:51+01:00
ci: update alpine/fedora & add ubsan job
This patch updates alpine image to 3.23, fedora image to 43, and adds
a `x86_64-linux-fedora43-validate+debug_info+ubsan` job that's run in
validate/nightly pipelines to catch undefined behavior in the RTS
codebase.
- - - - -
2ccd11ca by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix zero-length VLA undefined behavior in interpretBCO
This commit fixes a zero-length VLA undefined behavior in interpretBCO, caught by UBSan:
```
+rts/Interpreter.c:3133:19: runtime variable length array bound evaluates to non-positive value 0
```
- - - - -
4156ed19 by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix unaligned ReadSpB in interpretBCO
This commit fixes unaligned ReadSpB in interpretBCO, caught by UBSan:
```
+rts/Interpreter.c:2174:64: runtime load of misaligned address 0x004202059dd1 for type 'StgWord', which requires 8 byte alignment
```
To perform proper unaligned read, we define StgUnalignedWord as a type
alias of StgWord with aligned(1) attribute, and load StgUnalignedWord
instead of StgWord in ReadSpB, so the C compiler is aware that we're
not loading with natural alignment.
- - - - -
fef89fb9 by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix signed integer overflow in subword arithmetic in interpretBCO
This commit fixes signed integer overflow in subword arithmetic in
interpretBCO, see added note for detailed explanation.
- - - - -
3c001377 by Cheng Shao at 2025-12-13T05:03:15-05:00
ci: use treeless fetch for perf notes
This patch improves the ci logic for fetching perf notes by using
treeless fetch
(https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-…)
to avoid downloading all blobs of the perf notes repo at once, and
only fetch the actually required blobs on-demand when needed. This
makes the initial `test-metrics.sh pull` operation much faster, and
also more robust, since we are seeing an increasing rate of 504 errors
in CI when fetching all perf notes at once, which is a major source of
CI flakiness at this point.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
123a8d77 by Peter Trommler at 2025-12-13T05:03:57-05:00
Cmm: remove restriction in MachOp folding
- - - - -
0b54b5fd by Andreas Klebinger at 2025-12-13T05:04:38-05:00
Remove explicit Typeable deriviations.
- - - - -
08b13f7b by Cheng Shao at 2025-12-13T05:05:18-05:00
ci: set gc.auto=0 during setup stage
This patch sets `gc.auto=0` during `setup` stage of CI, see added
comment for detailed explanation.
- - - - -
3b5aecb5 by Ben Gamari at 2025-12-13T23:43:10+01:00
Bump exceptions submodule to 0.10.11
- - - - -
c32de3b0 by Johan Förberg at 2025-12-15T02:36:03-05:00
base: Define Semigroup and Monoid instances for lazy ST
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/374
Fixes #26581
- - - - -
4f8b660c by mangoiv at 2025-12-15T02:37:05-05:00
ci: do not require nightly cabal-reinstall job to succeed
- - - - -
2c2a3ef3 by Cheng Shao at 2025-12-15T11:51:53-05:00
docs: drop obsolete warning about -fexternal-interpreter on windows
This patch drops an obsolete warning about -fexternal-interpreter not
supported on windows; it is supported since a long time ago, including
the profiled way.
- - - - -
68573aa5 by Marc Scholten at 2025-12-15T11:53:00-05:00
haddock: Drop Haddock.Backends.HaddockDB as it's unused
- - - - -
b230d549 by mangoiv at 2025-12-16T15:17:45-05:00
base: generalize delete{Firsts,}By
When we delete{Firsts,}By we should not require the
lists to be the same type. This is an especially useful
generalisation in the case of deleteFirstsBy because we
can skip an invocation of the map function.
This change was discussed on the core-libraries-committee's bug
tracker at https://github.com/haskell/core-libraries-committee/issues/372.
- - - - -
6a2b43e3 by Cheng Shao at 2025-12-16T15:18:30-05:00
compiler: clean up redundant LANGUAGE pragmas
This patch bumps `default-language` of `ghc`/`ghc-bin` from `GHC2021`
to `GHC2024` (which is supported in ghc 9.10, current boot ghc lower
version bound), and also cleans up redundant `LANGUAGE` pragmas (as
well as `default-extensions`/`other-extensions`) that are already
implied by `GHC2024`.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
81596377 by Wolfgang Jeltsch at 2025-12-18T18:05:20+02:00
Add an operation `System.IO.hGetNewlineMode`
This commit also contains some small code and documentation changes for
related operations, for the sake of consistency.
- - - - -
1255 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- .gitlab/rel_eng/upload_ghc_libs.py
- .gitlab/test-metrics.sh
- .gitmodules
- cabal.project-reinstall
- compile_flags.txt
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Types/Literals.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/InfoTable.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- + compiler/GHC/ByteCode/Serialize.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/BlockId.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Config.hs
- compiler/GHC/Cmm/ContFlowOpt.hs
- compiler/GHC/Cmm/Dataflow.hs
- compiler/GHC/Cmm/Dataflow/Block.hs
- compiler/GHC/Cmm/Dataflow/Graph.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Cmm/DebugBlock.hs
- compiler/GHC/Cmm/Dominators.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Graph.hs
- compiler/GHC/Cmm/Info.hs
- compiler/GHC/Cmm/Info/Build.hs
- compiler/GHC/Cmm/LRegSet.hs
- compiler/GHC/Cmm/LayoutStack.hs
- compiler/GHC/Cmm/Lint.hs
- compiler/GHC/Cmm/Liveness.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/Cmm/Opt.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Pipeline.hs
- compiler/GHC/Cmm/ProcPoint.hs
- compiler/GHC/Cmm/Reducibility.hs
- compiler/GHC/Cmm/Reg.hs
- compiler/GHC/Cmm/Sink.hs
- compiler/GHC/Cmm/Switch.hs
- compiler/GHC/Cmm/Switch/Implement.hs
- compiler/GHC/Cmm/ThreadSanitizer.hs
- compiler/GHC/Cmm/UniqueRenamer.hs
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/RegInfo.hs
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/CmmToAsm/CPrim.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/Dwarf/Types.hs
- compiler/GHC/CmmToAsm/Format.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/Monad.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/PPC/RegInfo.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Graph.hs
- compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs
- compiler/GHC/CmmToAsm/Reg/Graph/SpillCost.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Linear/State.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- compiler/GHC/CmmToAsm/Wasm.hs
- compiler/GHC/CmmToAsm/Wasm/Asm.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/Wasm/Types.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/Base.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion.hs-boot
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/ConLike.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/LateCC/OverloadedCalls.hs
- compiler/GHC/Core/LateCC/TopLevelBinds.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Lint/Interactive.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Multiplicity.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/Opt/CallerCC.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/PatSyn.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/TyCon/Env.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/CoreToStg/Prep.hs
- compiler/GHC/Data/Bag.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Data/FlatBag.hs
- compiler/GHC/Data/Graph/Collapse.hs
- compiler/GHC/Data/Graph/Color.hs
- compiler/GHC/Data/Graph/Directed.hs
- compiler/GHC/Data/List/Infinite.hs
- compiler/GHC/Data/List/NonEmpty.hs
- compiler/GHC/Data/Maybe.hs
- compiler/GHC/Data/OsPath.hs
- compiler/GHC/Data/Pair.hs
- compiler/GHC/Data/SmallArray.hs
- compiler/GHC/Data/Stream.hs
- compiler/GHC/Data/Strict.hs
- compiler/GHC/Data/StringBuffer.hs
- compiler/GHC/Data/TrieMap.hs
- compiler/GHC/Data/Word64Map.hs
- compiler/GHC/Data/Word64Map/Internal.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backend/Internal.hs
- compiler/GHC/Driver/Backpack.hs
- + compiler/GHC/Driver/ByteCode.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Config/Finder.hs
- + compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/Config/Linker.hs
- compiler/GHC/Driver/Config/Stg/Debug.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Config/Tidy.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/KnotVars.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/GenerateCgIPEStub.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/LlvmConfigCache.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Messager.hs
- compiler/GHC/Driver/Monad.hs
- compiler/GHC/Driver/Phases.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Driver/Pipeline/Monad.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Inspect.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Basic.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Doc.hs
- compiler/GHC/Hs/Doc.hs-boot
- compiler/GHC/Hs/DocString.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Expr.hs-boot
- compiler/GHC/Hs/Extension.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Pat.hs-boot
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Arrows.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/Decl.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/ListComp.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Check.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Pmc/Types.hs
- compiler/GHC/HsToCore/Pmc/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Env.hs
- compiler/GHC/Iface/Errors.hs
- compiler/GHC/Iface/Errors/Ppr.hs
- compiler/GHC/Iface/Errors/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Debug.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Flags.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/JS/Ident.hs
- compiler/GHC/JS/JStg/Monad.hs
- compiler/GHC/JS/JStg/Syntax.hs
- compiler/GHC/JS/Make.hs
- compiler/GHC/JS/Optimizer.hs
- compiler/GHC/JS/Ppr.hs
- compiler/GHC/JS/Syntax.hs
- compiler/GHC/JS/Transform.hs
- + compiler/GHC/Linker/ByteCode.hs
- compiler/GHC/Linker/Config.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Dynamic.hs
- + compiler/GHC/Linker/Executable.hs
- − compiler/GHC/Linker/ExtraObj.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Linker/Static.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Linker/Windows.hs
- compiler/GHC/Llvm/MetaData.hs
- compiler/GHC/Llvm/Ppr.hs
- compiler/GHC/Llvm/Types.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/Errors/Basic.hs
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Header.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Parser/String.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Platform.hs
- compiler/GHC/Platform/Reg.hs
- compiler/GHC/Platform/Reg/Class.hs
- compiler/GHC/Platform/Reg/Class/NoVectors.hs
- compiler/GHC/Platform/Reg/Class/Separate.hs
- compiler/GHC/Platform/Reg/Class/Unified.hs
- compiler/GHC/Prelude/Basic.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Expr.hs-boot
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Debugger.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Heap/Layout.hs
- compiler/GHC/Runtime/Interpreter.hs
- + compiler/GHC/Runtime/Interpreter/C.hs
- + compiler/GHC/Runtime/Interpreter/Init.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Interpreter/Process.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Interpreter/Types/SymbolCache.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/Debug.hs
- + compiler/GHC/Stg/Debug/Types.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
- compiler/GHC/Stg/EnforceEpt/TagSig.hs
- compiler/GHC/Stg/EnforceEpt/Types.hs
- compiler/GHC/Stg/FVs.hs
- compiler/GHC/Stg/Lift/Analysis.hs
- compiler/GHC/Stg/Lift/Monad.hs
- compiler/GHC/Stg/Lift/Types.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/Stg/Syntax.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/Stg/Utils.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm.hs
- compiler/GHC/StgToCmm/ArgRep.hs
- compiler/GHC/StgToCmm/CgUtils.hs
- compiler/GHC/StgToCmm/Closure.hs
- compiler/GHC/StgToCmm/ExtCode.hs
- compiler/GHC/StgToCmm/Lit.hs
- compiler/GHC/StgToCmm/Monad.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/StgToJS/Apply.hs
- compiler/GHC/StgToJS/Arg.hs
- compiler/GHC/StgToJS/CodeGen.hs
- compiler/GHC/StgToJS/DataCon.hs
- compiler/GHC/StgToJS/Deps.hs
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/StgToJS/ExprCtx.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/StgToJS/Heap.hs
- compiler/GHC/StgToJS/Ids.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- compiler/GHC/StgToJS/Linker/Opt.hs
- compiler/GHC/StgToJS/Linker/Types.hs
- compiler/GHC/StgToJS/Literal.hs
- compiler/GHC/StgToJS/Monad.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/StgToJS/Regs.hs
- compiler/GHC/StgToJS/Rts/Rts.hs
- compiler/GHC/StgToJS/Rts/Types.hs
- compiler/GHC/StgToJS/Sinker/Collect.hs
- compiler/GHC/StgToJS/Sinker/Sinker.hs
- compiler/GHC/StgToJS/Sinker/StringsUnfloat.hs
- compiler/GHC/StgToJS/Types.hs
- compiler/GHC/StgToJS/Utils.hs
- compiler/GHC/SysTools.hs
- compiler/GHC/SysTools/Ar.hs
- compiler/GHC/SysTools/BaseDir.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/SysTools/Terminal.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Functor.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Hole.hs
- compiler/GHC/Tc/Errors/Hole/FitTypes.hs
- compiler/GHC/Tc/Errors/Hole/Plugin.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Errors/Types/PromotionErr.hs
- compiler/GHC/Tc/Gen/Annotation.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Arrow.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Foreign.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- + compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Irred.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Solver/Solve.hs-boot
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Build.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/CtLoc.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Utils/Unify.hs-boot
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/Monad.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Annotations.hs
- compiler/GHC/Types/Avail.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/CompleteMatch.hs
- compiler/GHC/Types/CostCentre.hs
- compiler/GHC/Types/CostCentre/State.hs
- compiler/GHC/Types/DefaultEnv.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/FieldLabel.hs
- compiler/GHC/Types/Fixity.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/ForeignStubs.hs
- compiler/GHC/Types/GREInfo.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Name/Set.hs
- compiler/GHC/Types/PkgQual.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/SaneDouble.hs
- compiler/GHC/Types/SourceError.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Types/SptEntry.hs
- compiler/GHC/Types/SrcLoc.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Types/TyThing.hs
- compiler/GHC/Types/TyThing/Ppr.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/DSM.hs
- compiler/GHC/Types/Unique/DSet.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Unique/Map.hs
- compiler/GHC/Types/Unique/SDFM.hs
- compiler/GHC/Types/Unique/Set.hs
- compiler/GHC/Types/Unique/Supply.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Home/ModInfo.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/Location.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Unit/Types.hs-boot
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Binary/Typeable.hs
- + compiler/GHC/Utils/EndoOS.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Exception.hs
- compiler/GHC/Utils/Json.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Misc.hs
- compiler/GHC/Utils/Monad/Codensity.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Panic.hs
- compiler/GHC/Utils/Panic/Plain.hs
- compiler/GHC/Wasm/ControlFlow.hs
- compiler/GHC/Wasm/ControlFlow/FromCmm.hs
- compiler/Language/Haskell/Syntax.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Expr.hs-boot
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Pat.hs-boot
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/Setup.hs
- compiler/cbits/keepCAFsForGHCi.c
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/bugs.rst
- docs/users_guide/compare-flags.py
- docs/users_guide/conf.py
- docs/users_guide/debug-info.rst
- docs/users_guide/debugging.rst
- docs/users_guide/extending_ghc.rst
- docs/users_guide/exts/arrows.rst
- docs/users_guide/exts/data_kinds.rst
- docs/users_guide/exts/derive_any_class.rst
- docs/users_guide/exts/deriving_extra.rst
- docs/users_guide/exts/deriving_inferred.rst
- docs/users_guide/exts/deriving_strategies.rst
- docs/users_guide/exts/explicit_namespaces.rst
- docs/users_guide/exts/gadt.rst
- docs/users_guide/exts/gadt_syntax.rst
- docs/users_guide/exts/generics.rst
- docs/users_guide/exts/overloaded_labels.rst
- docs/users_guide/exts/overloaded_strings.rst
- docs/users_guide/exts/pattern_synonyms.rst
- docs/users_guide/exts/poly_kinds.rst
- docs/users_guide/exts/primitives.rst
- docs/users_guide/exts/rank_polymorphism.rst
- docs/users_guide/exts/rebindable_syntax.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/exts/scoped_type_variables.rst
- docs/users_guide/exts/standalone_deriving.rst
- docs/users_guide/exts/template_haskell.rst
- docs/users_guide/exts/tuple_sections.rst
- docs/users_guide/exts/type_data.rst
- docs/users_guide/exts/type_defaulting.rst
- docs/users_guide/exts/type_families.rst
- docs/users_guide/ghci.rst
- docs/users_guide/gone_wrong.rst
- docs/users_guide/hints.rst
- docs/users_guide/javascript.rst
- docs/users_guide/phases.rst
- docs/users_guide/profiling.rst
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using.rst
- docs/users_guide/wasm.rst
- docs/users_guide/win32-dlls.rst
- ghc/GHC/Driver/Session/Lint.hs
- ghc/GHC/Driver/Session/Mode.hs
- ghc/GHCi/Leak.hs
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Exception.hs
- ghc/GHCi/UI/Info.hs
- ghc/GHCi/UI/Monad.hs
- ghc/Main.hs
- ghc/ghc-bin.cabal.in
- hadrian/bindist/config.mk.in
- hadrian/doc/flavours.md
- hadrian/src/Builder.hs
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/ArgsHash.hs
- hadrian/src/Hadrian/Oracles/Cabal/Type.hs
- hadrian/src/Hadrian/Oracles/DirectoryContents.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/ModuleFiles.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Libffi.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Warnings.hs
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Data/List.hs
- libraries/base/src/Data/List/NonEmpty.hs
- + libraries/base/src/Data/List/NubOrdSet.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Num.hs
- libraries/base/src/System/IO.hs
- libraries/base/tests/all.T
- libraries/exceptions
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-boot/GHC/Unit/Database.hs
- libraries/ghc-boot/Setup.hs
- libraries/ghc-boot/ghc-boot.cabal.in
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Lazy/Imp.hs
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/List.hs
- + libraries/ghc-internal/src/GHC/Internal/Stack/ConstantsProf.hsc
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- + libraries/ghc-internal/tests/backtraces/T26507.hs
- + libraries/ghc-internal/tests/backtraces/T26507.stderr
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/all.T
- libraries/ghc-prim/changelog.md
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ObjLink.hs
- libraries/ghci/GHCi/Run.hs
- libraries/os-string
- + libraries/template-haskell-lift
- + libraries/template-haskell-quasiquoter
- libraries/template-haskell/vendored-filepath/System/FilePath/Posix.hs
- libraries/template-haskell/vendored-filepath/System/FilePath/Windows.hs
- libraries/unix
- libraries/xhtml
- m4/fp_check_pthreads.m4
- m4/fp_cmm_cpp_cmd_with_args.m4
- − m4/fp_set_cflags_c99.m4
- m4/fptools_alex.m4
- m4/fptools_happy.m4
- + rts/.ubsan-suppressions
- rts/Apply.cmm
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/CloneStack.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Interpreter.c
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/Printer.c
- rts/RtsAPI.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- + rts/RtsToHsIface.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/ThreadPaused.c
- rts/configure.ac
- rts/eventlog/EventLog.c
- − rts/external-symbols.list.in
- rts/gen_event_types.py
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/Stg.h
- rts/include/rts/Bytecodes.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/rts/Types.h
- rts/include/rts/storage/Block.h
- rts/include/stg/MiscClosures.h
- rts/include/stg/Prim.h
- rts/include/stg/Types.h
- rts/linker/Elf.c
- rts/linker/LoadArchive.c
- rts/linker/PEi386.c
- rts/posix/OSMem.c
- rts/posix/Signals.c
- libraries/ghc-internal/cbits/atomic.c → rts/prim/atomic.c
- libraries/ghc-internal/cbits/bitrev.c → rts/prim/bitrev.c
- libraries/ghc-internal/cbits/bswap.c → rts/prim/bswap.c
- libraries/ghc-internal/cbits/clz.c → rts/prim/clz.c
- libraries/ghc-internal/cbits/ctz.c → rts/prim/ctz.c
- libraries/ghc-internal/cbits/int64x2minmax.c → rts/prim/int64x2minmax.c
- libraries/ghc-internal/cbits/longlong.c → rts/prim/longlong.c
- libraries/ghc-internal/cbits/mulIntMayOflo.c → rts/prim/mulIntMayOflo.c
- libraries/ghc-internal/cbits/pdep.c → rts/prim/pdep.c
- libraries/ghc-internal/cbits/pext.c → rts/prim/pext.c
- libraries/ghc-internal/cbits/popcnt.c → rts/prim/popcnt.c
- libraries/ghc-internal/cbits/vectorQuotRem.c → rts/prim/vectorQuotRem.c
- libraries/ghc-internal/cbits/word2float.c → rts/prim/word2float.c
- rts/rts.buildinfo.in
- rts/rts.cabal
- rts/sm/NonMoving.c
- rts/sm/NonMovingMark.c
- rts/sm/Scav.c
- rts/wasm/JSFFI.c
- rts/wasm/scheduler.cmm
- rts/win32/libHSghc-internal.def
- testsuite/config/ghc
- testsuite/driver/cpu_features.py
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/mk/boilerplate.mk
- testsuite/tests/backpack/should_fail/T19244a.stderr
- + testsuite/tests/bytecode/T23973.hs
- + testsuite/tests/bytecode/T23973.script
- + testsuite/tests/bytecode/T23973.stdout
- testsuite/tests/bytecode/T24634/T24634a.stdout
- testsuite/tests/bytecode/T24634/T24634b.stdout
- + testsuite/tests/bytecode/T26565.hs
- + testsuite/tests/bytecode/T26565.script
- + testsuite/tests/bytecode/T26565.stdout
- + testsuite/tests/bytecode/T26640.hs
- + testsuite/tests/bytecode/T26640.script
- + testsuite/tests/bytecode/T26640.stdout
- testsuite/tests/bytecode/all.T
- + testsuite/tests/cabal/Bytecode.hs
- + testsuite/tests/cabal/BytecodeForeign.c
- + testsuite/tests/cabal/BytecodeForeign.hs
- testsuite/tests/cabal/Makefile
- testsuite/tests/cabal/all.T
- + testsuite/tests/cabal/bytecode.pkg
- + testsuite/tests/cabal/bytecode.script
- + testsuite/tests/cabal/bytecode_foreign.pkg
- + testsuite/tests/cabal/bytecode_foreign.script
- testsuite/tests/cabal/ghcpkg03.stderr
- testsuite/tests/cabal/ghcpkg03.stderr-mingw32
- testsuite/tests/cabal/ghcpkg05.stderr
- testsuite/tests/cabal/ghcpkg05.stderr-mingw32
- + testsuite/tests/cabal/pkg_bytecode.stderr
- + testsuite/tests/cabal/pkg_bytecode.stdout
- + testsuite/tests/cabal/pkg_bytecode_foreign.stderr
- + testsuite/tests/cabal/pkg_bytecode_foreign.stdout
- + testsuite/tests/cabal/pkg_bytecode_with_gbc.stderr
- + testsuite/tests/cabal/pkg_bytecode_with_gbc.stdout
- + testsuite/tests/cabal/pkg_bytecode_with_o.stderr
- + testsuite/tests/cabal/pkg_bytecode_with_o.stdout
- + testsuite/tests/cmm/opt/T25664.hs
- + testsuite/tests/cmm/opt/T25664.stdout
- testsuite/tests/cmm/opt/all.T
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/mavx-should-enable-popcnt.asm
- + testsuite/tests/codeGen/should_gen_asm/mavx-should-enable-popcnt.hs
- + testsuite/tests/codeGen/should_gen_asm/msse-option-order.asm
- + testsuite/tests/codeGen/should_gen_asm/msse-option-order.hs
- + testsuite/tests/codeGen/should_run/T24016.hs
- + testsuite/tests/codeGen/should_run/T24016.stdout
- + testsuite/tests/codeGen/should_run/T26537.hs
- + testsuite/tests/codeGen/should_run/T26537.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/concurrent/prog001/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/cpranal/should_compile/T18174.stderr
- testsuite/tests/default/default-fail05.stderr
- testsuite/tests/dependent/should_fail/T11334b.stderr
- testsuite/tests/dependent/should_fail/T13135_simple.stderr
- testsuite/tests/deriving/should_fail/T3621.stderr
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/Makefile
- testsuite/tests/driver/T11429c.stderr
- + testsuite/tests/driver/T20696/T20696.stderr-ext-interp
- testsuite/tests/driver/T21682.stderr
- + testsuite/tests/driver/T24120.hs
- + testsuite/tests/driver/T24731.hs
- + testsuite/tests/driver/T26551.hs
- + testsuite/tests/driver/T26551.stderr
- testsuite/tests/driver/T5313.hs
- testsuite/tests/driver/all.T
- + testsuite/tests/driver/bytecode-object/A.hs
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.c
- + testsuite/tests/driver/bytecode-object/BytecodeForeign.hs
- + testsuite/tests/driver/bytecode-object/BytecodeMain.hs
- + testsuite/tests/driver/bytecode-object/BytecodeTest.hs
- + testsuite/tests/driver/bytecode-object/Makefile
- + testsuite/tests/driver/bytecode-object/all.T
- + testsuite/tests/driver/bytecode-object/bytecode_object12.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object13.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object14.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object15.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object16.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object17.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object18.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object19.script
- + testsuite/tests/driver/bytecode-object/bytecode_object19.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object20.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object21.stderr
- + testsuite/tests/driver/bytecode-object/bytecode_object21.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object23.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object24.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object25.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object4.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object5.stdout
- + testsuite/tests/driver/bytecode-object/bytecode_object6.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405.stdout
- testsuite/tests/driver/fat-iface/T22405/T22405b.stdout
- testsuite/tests/driver/fat-iface/fat011.stderr
- + testsuite/tests/driver/fat-iface/fat012.stderr-ext-interp
- + testsuite/tests/driver/fat-iface/fat015.stderr-ext-interp
- testsuite/tests/driver/j-space/jspace.hs
- testsuite/tests/generics/T10604/T10604_deriving.stderr
- + testsuite/tests/ghc-api-browser/README.md
- + testsuite/tests/ghc-api-browser/all.T
- + testsuite/tests/ghc-api-browser/index.html
- + testsuite/tests/ghc-api-browser/playground001.hs
- + testsuite/tests/ghc-api-browser/playground001.js
- + testsuite/tests/ghc-api-browser/playground001.sh
- + testsuite/tests/ghc-api-browser/playground001.stdout
- testsuite/tests/ghc-api/T10052/T10052.hs
- testsuite/tests/ghc-api/T10942.hs
- + testsuite/tests/ghc-api/T26264.hs
- + testsuite/tests/ghc-api/T26264.stdout
- testsuite/tests/ghc-api/T8639_api.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghc-api/annotations-literals/literals.hs
- testsuite/tests/ghc-api/apirecomp001/myghc.hs
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci.debugger/scripts/print012.stdout
- testsuite/tests/ghci/linking/dyn/T3372.hs
- testsuite/tests/ghci/scripts/T10321.stdout
- testsuite/tests/ghci/scripts/T24459.stdout
- testsuite/tests/ghci/scripts/T7730.stdout
- testsuite/tests/ghci/scripts/T8959b.stderr
- testsuite/tests/ghci/scripts/ghci051.stderr
- testsuite/tests/ghci/scripts/ghci065.stdout
- testsuite/tests/ghci/should_run/PackedDataCon/packeddatacon.T
- testsuite/tests/ghci/should_run/UnboxedTuples/unboxedtuples.T
- testsuite/tests/ghci/should_run/UnliftedDataTypeInterp/unlifteddatatypeinterp.T
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/indexed-types/should_compile/T12538.stderr
- testsuite/tests/indexed-types/should_fail/T14369.stderr
- testsuite/tests/indexed-types/should_fail/T14887.stderr
- testsuite/tests/indexed-types/should_fail/T1897b.stderr
- testsuite/tests/indexed-types/should_fail/T21092.hs
- − testsuite/tests/indexed-types/should_fail/T21092.stderr
- testsuite/tests/indexed-types/should_fail/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- + testsuite/tests/linear/should_compile/LinearEtaExpansions.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/T19361.stderr
- testsuite/tests/linear/should_fail/TypeClass.hs
- testsuite/tests/linear/should_fail/TypeClass.stderr
- testsuite/tests/linear/should_run/LinearGhci.stdout
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/linters/all.T
- testsuite/tests/linters/notes.stdout
- testsuite/tests/llvm/should_run/all.T
- + testsuite/tests/module/T25901_exp_plain_wc.hs
- + testsuite/tests/module/T25901_exp_plain_wc.stderr
- + testsuite/tests/module/T25901_imp_plain_wc.hs
- + testsuite/tests/module/T25901_imp_plain_wc.stderr
- testsuite/tests/module/all.T
- testsuite/tests/module/mod4.stderr
- testsuite/tests/numeric/should_compile/T16402.stderr-ws-64
- testsuite/tests/overloadedrecflds/should_compile/BootFldReexport.stderr
- testsuite/tests/overloadedrecflds/should_fail/T16745.stderr
- testsuite/tests/overloadedrecflds/should_fail/T18999_NoDisambiguateRecordFields.stderr
- + testsuite/tests/overloadedrecflds/should_fail/T26480.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480.stderr
- + testsuite/tests/overloadedrecflds/should_fail/T26480_aux1.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480_aux2.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480b.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480b.stderr
- testsuite/tests/overloadedrecflds/should_fail/all.T
- testsuite/tests/overloadedrecflds/should_fail/hasfieldfail01.stderr
- testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.hs
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T12488c.hs
- + testsuite/tests/parser/should_fail/T12488c.stderr
- + testsuite/tests/parser/should_fail/T12488d.hs
- + testsuite/tests/parser/should_fail/T12488d.stderr
- testsuite/tests/parser/should_fail/T20654a.stderr
- testsuite/tests/parser/should_fail/all.T
- testsuite/tests/partial-sigs/should_fail/T14584a.stderr
- + testsuite/tests/patsyn/should_compile/T26465b.hs
- + testsuite/tests/patsyn/should_compile/T26465c.hs
- + testsuite/tests/patsyn/should_compile/T26465d.hs
- + testsuite/tests/patsyn/should_compile/T26465d.stderr
- testsuite/tests/patsyn/should_compile/all.T
- + testsuite/tests/patsyn/should_fail/T26465.hs
- + testsuite/tests/patsyn/should_fail/T26465.stderr
- testsuite/tests/patsyn/should_fail/all.T
- testsuite/tests/perf/compiler/Makefile
- + testsuite/tests/perf/compiler/MultiLayerModulesDefsGhciWithBytecodeFiles.script
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/should_run/T3586.hs
- testsuite/tests/perf/should_run/UniqLoop.hs
- testsuite/tests/perf/should_run/all.T
- + testsuite/tests/pmcheck/should_compile/T26400.hs
- + testsuite/tests/pmcheck/should_compile/T26400.stderr
- + testsuite/tests/pmcheck/should_compile/T26400b.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- testsuite/tests/polykinds/T6068.stdout
- − testsuite/tests/process/process010.stdout-i386-unknown-solaris2
- testsuite/tests/quantified-constraints/T15359.hs
- testsuite/tests/regalloc/regalloc_unit_tests.hs
- + testsuite/tests/rename/should_compile/T12488b.hs
- + testsuite/tests/rename/should_compile/T12488f.hs
- + testsuite/tests/rename/should_compile/T25901_exp_1.hs
- + testsuite/tests/rename/should_compile/T25901_exp_1_helper.hs
- + testsuite/tests/rename/should_compile/T25901_exp_2.hs
- + testsuite/tests/rename/should_compile/T25901_exp_2_helper.hs
- + testsuite/tests/rename/should_compile/T25901_imp_hq.hs
- + testsuite/tests/rename/should_compile/T25901_imp_hu.hs
- + testsuite/tests/rename/should_compile/T25901_imp_sq.hs
- + testsuite/tests/rename/should_compile/T25901_imp_su.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T12488a.hs
- + testsuite/tests/rename/should_fail/T12488a.stderr
- + testsuite/tests/rename/should_fail/T12488a_foo.hs
- + testsuite/tests/rename/should_fail/T12488a_foo.stderr
- + testsuite/tests/rename/should_fail/T12488e.hs
- + testsuite/tests/rename/should_fail/T12488e.stderr
- + testsuite/tests/rename/should_fail/T12488g.hs
- + testsuite/tests/rename/should_fail/T12488g.stderr
- testsuite/tests/rename/should_fail/T19843h.stderr
- testsuite/tests/rename/should_fail/T25899e2.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1_helper.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2_helper.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_5.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_5.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_6.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_6.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_hu_fail_4.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hu_fail_4.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_2.hs
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_2.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_3.hs
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_3.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_su_fail_1.hs
- + testsuite/tests/rename/should_fail/T25901_imp_su_fail_1.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/rename/should_fail/rnfail055.stderr
- testsuite/tests/rep-poly/RepPolyCase1.stderr
- − testsuite/tests/rep-poly/RepPolyCase2.stderr
- testsuite/tests/rep-poly/RepPolyNPlusK.stderr
- testsuite/tests/rep-poly/RepPolyRightSection.stderr
- testsuite/tests/rep-poly/RepPolyRule3.stderr
- testsuite/tests/rep-poly/RepPolyTuple4.stderr
- testsuite/tests/rep-poly/T13233.stderr
- − testsuite/tests/rep-poly/T17021.stderr
- testsuite/tests/rep-poly/T19709b.stderr
- testsuite/tests/rep-poly/T20363b.stderr
- − testsuite/tests/rep-poly/T21650_a.stderr
- − testsuite/tests/rep-poly/T21650_b.stderr
- testsuite/tests/rep-poly/T23903.stderr
- + testsuite/tests/rep-poly/T26072.hs
- + testsuite/tests/rep-poly/T26072b.hs
- + testsuite/tests/rep-poly/T26528.hs
- testsuite/tests/rep-poly/UnliftedNewtypesLevityBinder.stderr
- testsuite/tests/rep-poly/all.T
- testsuite/tests/roles/should_compile/Roles13.stderr
- testsuite/tests/rts/KeepCafsBase.hs
- testsuite/tests/rts/T22859.hs
- testsuite/tests/rts/all.T
- + testsuite/tests/rts/ipe/distinct-tables/Main.hs
- + testsuite/tests/rts/ipe/distinct-tables/Makefile
- + testsuite/tests/rts/ipe/distinct-tables/X.hs
- + testsuite/tests/rts/ipe/distinct-tables/all.T
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables01.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables02.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables03.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables04.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables05.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables06.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables07.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables08.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables09.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables10.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables11.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables12.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables13.stdout
- − testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-32-mingw32
- − testsuite/tests/rts/linker/T11223/T11223_simple_duplicate_lib.stderr-ws-32-mingw32
- testsuite/tests/rts/linker/T2615.hs
- − testsuite/tests/rts/outofmem.stderr-i386-apple-darwin
- − testsuite/tests/rts/outofmem.stderr-i386-unknown-mingw32
- − testsuite/tests/rts/outofmem.stderr-powerpc-apple-darwin
- testsuite/tests/saks/should_compile/saks023.stdout
- testsuite/tests/saks/should_compile/saks034.stdout
- testsuite/tests/saks/should_compile/saks035.stdout
- testsuite/tests/showIface/Makefile
- + testsuite/tests/showIface/T26246a.hs
- + testsuite/tests/showIface/T26246a.stdout
- testsuite/tests/showIface/all.T
- + testsuite/tests/simd/should_run/T26410_ffi.hs
- + testsuite/tests/simd/should_run/T26410_ffi.stdout
- + testsuite/tests/simd/should_run/T26410_ffi_c.c
- + testsuite/tests/simd/should_run/T26410_prim.hs
- + testsuite/tests/simd/should_run/T26410_prim.stdout
- + testsuite/tests/simd/should_run/T26542.hs
- + testsuite/tests/simd/should_run/T26542.stdout
- + testsuite/tests/simd/should_run/T26550.hs
- + testsuite/tests/simd/should_run/T26550.stdout
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/simd015.hs
- + testsuite/tests/simd/should_run/simd015.stdout
- + testsuite/tests/simd/should_run/simd016.hs
- + testsuite/tests/simd/should_run/simd016.stdout
- + testsuite/tests/simd/should_run/simd017.hs
- + testsuite/tests/simd/should_run/simd017.stdout
- testsuite/tests/simplCore/should_compile/OpaqueNoCastWW.stderr
- testsuite/tests/simplCore/should_compile/T17673.stderr
- testsuite/tests/simplCore/should_compile/T18078.stderr
- testsuite/tests/simplCore/should_compile/T18995.stderr
- testsuite/tests/simplCore/should_compile/T19890.stderr
- testsuite/tests/simplCore/should_compile/T21948.stderr
- testsuite/tests/simplCore/should_compile/T21960.stderr
- testsuite/tests/simplCore/should_compile/T24808.stderr
- − testsuite/tests/simplCore/should_compile/T25713.stderr
- + testsuite/tests/simplCore/should_compile/T26349.hs
- + testsuite/tests/simplCore/should_compile/T26349.stderr
- + testsuite/tests/simplCore/should_compile/T26588.hs
- + testsuite/tests/simplCore/should_compile/T26589.hs
- testsuite/tests/simplCore/should_compile/T4201.stdout
- testsuite/tests/simplCore/should_compile/T8331.stderr
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_compile/rule2.stderr
- testsuite/tests/simplStg/should_compile/T22840.stderr
- + testsuite/tests/splice-imports/SI07.stderr-ext-interp
- + testsuite/tests/th/T26099.hs
- + testsuite/tests/th/T26099.stderr
- + testsuite/tests/th/T26568.hs
- + testsuite/tests/th/T26568.stderr
- testsuite/tests/th/T8761.stderr
- testsuite/tests/th/all.T
- testsuite/tests/typecheck/T16127/T16127.stderr
- testsuite/tests/typecheck/no_skolem_info/T13499.stderr
- testsuite/tests/typecheck/no_skolem_info/T20232.stderr
- testsuite/tests/typecheck/should_compile/T13651.hs
- − testsuite/tests/typecheck/should_compile/T13651.stderr
- + testsuite/tests/typecheck/should_compile/T14745.hs
- + testsuite/tests/typecheck/should_compile/T17705.hs
- testsuite/tests/typecheck/should_compile/T22560d.stdout
- + testsuite/tests/typecheck/should_compile/T26451.hs
- + testsuite/tests/typecheck/should_compile/T26457.hs
- + testsuite/tests/typecheck/should_compile/T26582.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/hole_constraints_nested.stderr
- testsuite/tests/typecheck/should_compile/tc126.hs
- testsuite/tests/typecheck/should_fail/AmbigFDs.hs
- − testsuite/tests/typecheck/should_fail/AmbigFDs.stderr
- testsuite/tests/typecheck/should_fail/FD3.stderr
- testsuite/tests/typecheck/should_fail/FDsFromGivens2.stderr
- testsuite/tests/typecheck/should_fail/T11672.stderr
- testsuite/tests/typecheck/should_fail/T12373.stderr
- testsuite/tests/typecheck/should_fail/T13506.stderr
- testsuite/tests/typecheck/should_fail/T15629.stderr
- testsuite/tests/typecheck/should_fail/T15807.stderr
- testsuite/tests/typecheck/should_fail/T15883e.stderr
- testsuite/tests/typecheck/should_fail/T16074.stderr
- testsuite/tests/typecheck/should_fail/T16512a.stderr
- testsuite/tests/typecheck/should_fail/T18357a.stderr
- testsuite/tests/typecheck/should_fail/T18851b.hs
- − testsuite/tests/typecheck/should_fail/T18851b.stderr
- testsuite/tests/typecheck/should_fail/T18851c.hs
- − testsuite/tests/typecheck/should_fail/T18851c.stderr
- testsuite/tests/typecheck/should_fail/T19415.stderr
- testsuite/tests/typecheck/should_fail/T19415b.stderr
- testsuite/tests/typecheck/should_fail/T19627.stderr
- testsuite/tests/typecheck/should_fail/T20241b.stderr
- testsuite/tests/typecheck/should_fail/T21530a.stderr
- testsuite/tests/typecheck/should_fail/T22684.stderr
- + testsuite/tests/typecheck/should_fail/T23162a.hs
- + testsuite/tests/typecheck/should_fail/T23162a.stderr
- testsuite/tests/typecheck/should_fail/T2414.stderr
- testsuite/tests/typecheck/should_fail/T24279.hs
- − testsuite/tests/typecheck/should_fail/T24279.stderr
- testsuite/tests/typecheck/should_fail/T25325.stderr
- testsuite/tests/typecheck/should_fail/T2534.stderr
- testsuite/tests/typecheck/should_fail/T5246.stderr
- testsuite/tests/typecheck/should_fail/T5978.stderr
- testsuite/tests/typecheck/should_fail/T7264.stderr
- testsuite/tests/typecheck/should_fail/T7368a.stderr
- testsuite/tests/typecheck/should_fail/T7696.stderr
- testsuite/tests/typecheck/should_fail/T8603.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/TcStaticPointersFail03.stderr
- testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr
- testsuite/tests/typecheck/should_fail/VisFlag1.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail122.stderr
- testsuite/tests/typecheck/should_fail/tcfail143.stderr
- testsuite/tests/unboxedsums/UbxSumUnpackedSize.hs
- + testsuite/tests/warnings/should_compile/DodgyExports02.hs
- + testsuite/tests/warnings/should_compile/DodgyExports02.stderr
- + testsuite/tests/warnings/should_compile/DodgyExports03.hs
- + testsuite/tests/warnings/should_compile/DodgyExports03.stderr
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dodgy.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dodgy.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_1.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_2.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_2.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_3.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_3.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_4.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_4.stderr
- + testsuite/tests/warnings/should_compile/T25901_helper_1.hs
- + testsuite/tests/warnings/should_compile/T25901_helper_2.hs
- + testsuite/tests/warnings/should_compile/T25901_helper_3.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_1.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_2.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_2.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_1.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_2.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_2.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_3.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_3.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_4.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_4.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Parsers.hs
- utils/check-exact/Preprocess.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/deriveConstants/Main.hs
- utils/genprimopcode/genprimopcode.cabal
- utils/ghc-pkg/Main.hs
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/MergeObjs.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/cabal.project
- utils/haddock/haddock-api/haddock-api.cabal
- − utils/haddock/haddock-api/src/Haddock/Backends/HaddockDB.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Renderer.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Names.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Themes.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Doc.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/haddock/haddock-api/src/Haddock/Utils.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Parser.hs
- utils/haddock/haddock-test/src/Test/Haddock.hs
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1050.html
- utils/haddock/html-test/ref/Bug26.html
- + utils/haddock/html-test/ref/Bug26246.html
- utils/haddock/html-test/ref/Bug298.html
- utils/haddock/html-test/ref/Bug458.html
- utils/haddock/html-test/ref/Bug85.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/BundledPatterns.html
- utils/haddock/html-test/ref/BundledPatterns2.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/GADTRecords.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/Nesting.html
- utils/haddock/html-test/ref/PatternSyns.html
- + utils/haddock/html-test/ref/PatternSyns2.html
- utils/haddock/html-test/ref/PromotedTypes.html
- utils/haddock/html-test/ref/TitledPicture.html
- utils/haddock/html-test/ref/TypeOperators.html
- utils/haddock/html-test/ref/Unicode.html
- utils/haddock/html-test/ref/Unicode2.html
- + utils/haddock/html-test/src/Bug26246.hs
- + utils/haddock/html-test/src/PatternSyns2.hs
- utils/haddock/hypsrc-test/ref/src/Classes.html
- utils/haddock/hypsrc-test/ref/src/Quasiquoter.html
- utils/haddock/latex-test/ref/LinearTypes/LinearTypes.tex
- utils/hpc
- utils/hsc2hs
- utils/iserv/iserv.cabal.in
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/425939009cdc8cda04fe86c2e04a03…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/425939009cdc8cda04fe86c2e04a03…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/jeltsch/obtaining-os-handles] 19 commits: compiler: remove unused CPP code in foreign stub
by Wolfgang Jeltsch (@jeltsch) 18 Dec '25
by Wolfgang Jeltsch (@jeltsch) 18 Dec '25
18 Dec '25
Wolfgang Jeltsch pushed to branch wip/jeltsch/obtaining-os-handles at Glasgow Haskell Compiler / GHC
Commits:
d99f8326 by Cheng Shao at 2025-12-11T19:14:18-05:00
compiler: remove unused CPP code in foreign stub
This patch removes unused CPP code in the generated foreign stub:
- `#define IN_STG_CODE 0` is not needed, since `Rts.h` already
includes this definition
- The `if defined(__cplusplus)` code paths are not needed in the `.c`
file, since we don't generate C++ stubs and don't include C++
headers in our stubs. But it still needs to be present in the `.h`
header since it might be later included into C++ source files.
- - - - -
46c9746f by Cheng Shao at 2025-12-11T19:14:57-05:00
configure: bump LlvmMaxVersion to 22
This commit bumps LlvmMaxVersion to 22; 21.x releases have been
available since Aug 26th, 2025 and there's no regressions with 21.x so
far. This bump is also required for updating fedora image to 43.
- - - - -
96fce8d0 by Cheng Shao at 2025-12-12T01:17:51+01:00
hadrian: add support for building with UndefinedBehaviorSanitizer
This patch adds a +ubsan flavour transformer to hadrian to build all
stage1+ C/C++ code with UndefinedBehaviorSanitizer. This is
particularly useful to catch potential undefined behavior in the RTS
codebase.
- - - - -
f7a06d8c by Cheng Shao at 2025-12-12T01:17:51+01:00
ci: update alpine/fedora & add ubsan job
This patch updates alpine image to 3.23, fedora image to 43, and adds
a `x86_64-linux-fedora43-validate+debug_info+ubsan` job that's run in
validate/nightly pipelines to catch undefined behavior in the RTS
codebase.
- - - - -
2ccd11ca by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix zero-length VLA undefined behavior in interpretBCO
This commit fixes a zero-length VLA undefined behavior in interpretBCO, caught by UBSan:
```
+rts/Interpreter.c:3133:19: runtime variable length array bound evaluates to non-positive value 0
```
- - - - -
4156ed19 by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix unaligned ReadSpB in interpretBCO
This commit fixes unaligned ReadSpB in interpretBCO, caught by UBSan:
```
+rts/Interpreter.c:2174:64: runtime load of misaligned address 0x004202059dd1 for type 'StgWord', which requires 8 byte alignment
```
To perform proper unaligned read, we define StgUnalignedWord as a type
alias of StgWord with aligned(1) attribute, and load StgUnalignedWord
instead of StgWord in ReadSpB, so the C compiler is aware that we're
not loading with natural alignment.
- - - - -
fef89fb9 by Cheng Shao at 2025-12-12T01:17:51+01:00
rts: fix signed integer overflow in subword arithmetic in interpretBCO
This commit fixes signed integer overflow in subword arithmetic in
interpretBCO, see added note for detailed explanation.
- - - - -
3c001377 by Cheng Shao at 2025-12-13T05:03:15-05:00
ci: use treeless fetch for perf notes
This patch improves the ci logic for fetching perf notes by using
treeless fetch
(https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-…)
to avoid downloading all blobs of the perf notes repo at once, and
only fetch the actually required blobs on-demand when needed. This
makes the initial `test-metrics.sh pull` operation much faster, and
also more robust, since we are seeing an increasing rate of 504 errors
in CI when fetching all perf notes at once, which is a major source of
CI flakiness at this point.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
123a8d77 by Peter Trommler at 2025-12-13T05:03:57-05:00
Cmm: remove restriction in MachOp folding
- - - - -
0b54b5fd by Andreas Klebinger at 2025-12-13T05:04:38-05:00
Remove explicit Typeable deriviations.
- - - - -
08b13f7b by Cheng Shao at 2025-12-13T05:05:18-05:00
ci: set gc.auto=0 during setup stage
This patch sets `gc.auto=0` during `setup` stage of CI, see added
comment for detailed explanation.
- - - - -
3b5aecb5 by Ben Gamari at 2025-12-13T23:43:10+01:00
Bump exceptions submodule to 0.10.11
- - - - -
c32de3b0 by Johan Förberg at 2025-12-15T02:36:03-05:00
base: Define Semigroup and Monoid instances for lazy ST
CLC proposal:
https://github.com/haskell/core-libraries-committee/issues/374
Fixes #26581
- - - - -
4f8b660c by mangoiv at 2025-12-15T02:37:05-05:00
ci: do not require nightly cabal-reinstall job to succeed
- - - - -
2c2a3ef3 by Cheng Shao at 2025-12-15T11:51:53-05:00
docs: drop obsolete warning about -fexternal-interpreter on windows
This patch drops an obsolete warning about -fexternal-interpreter not
supported on windows; it is supported since a long time ago, including
the profiled way.
- - - - -
68573aa5 by Marc Scholten at 2025-12-15T11:53:00-05:00
haddock: Drop Haddock.Backends.HaddockDB as it's unused
- - - - -
b230d549 by mangoiv at 2025-12-16T15:17:45-05:00
base: generalize delete{Firsts,}By
When we delete{Firsts,}By we should not require the
lists to be the same type. This is an especially useful
generalisation in the case of deleteFirstsBy because we
can skip an invocation of the map function.
This change was discussed on the core-libraries-committee's bug
tracker at https://github.com/haskell/core-libraries-committee/issues/372.
- - - - -
6a2b43e3 by Cheng Shao at 2025-12-16T15:18:30-05:00
compiler: clean up redundant LANGUAGE pragmas
This patch bumps `default-language` of `ghc`/`ghc-bin` from `GHC2021`
to `GHC2024` (which is supported in ghc 9.10, current boot ghc lower
version bound), and also cleans up redundant `LANGUAGE` pragmas (as
well as `default-extensions`/`other-extensions`) that are already
implied by `GHC2024`.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
300d8d85 by Wolfgang Jeltsch at 2025-12-18T17:09:58+02:00
Add operations for obtaining operating-system handles
This contribution implements CLC proposal #369. It adds operations for
obtaining POSIX file descriptors and Windows handles that underlie
Haskell handles. Those operating system handles can also be obtained
without such additional operations, but this is more involved and, more
importantly, requires using internals.
- - - - -
478 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- .gitlab/test-metrics.sh
- compiler/GHC.hs
- compiler/GHC/Builtin/PrimOps.hs
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/Builtin/Types/Literals.hs
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/InfoTable.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/BlockId.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Config.hs
- compiler/GHC/Cmm/ContFlowOpt.hs
- compiler/GHC/Cmm/Dataflow.hs
- compiler/GHC/Cmm/Dataflow/Block.hs
- compiler/GHC/Cmm/Dataflow/Graph.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/Cmm/DebugBlock.hs
- compiler/GHC/Cmm/Dominators.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Graph.hs
- compiler/GHC/Cmm/Info/Build.hs
- compiler/GHC/Cmm/LRegSet.hs
- compiler/GHC/Cmm/LayoutStack.hs
- compiler/GHC/Cmm/Lint.hs
- compiler/GHC/Cmm/Liveness.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Node.hs
- compiler/GHC/Cmm/Opt.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/ProcPoint.hs
- compiler/GHC/Cmm/Reducibility.hs
- compiler/GHC/Cmm/Reg.hs
- compiler/GHC/Cmm/Sink.hs
- compiler/GHC/Cmm/Switch.hs
- compiler/GHC/Cmm/Switch/Implement.hs
- compiler/GHC/Cmm/ThreadSanitizer.hs
- compiler/GHC/Cmm/UniqueRenamer.hs
- compiler/GHC/Cmm/Utils.hs
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/CmmToAsm/CPrim.hs
- compiler/GHC/CmmToAsm/Dwarf/Types.hs
- compiler/GHC/CmmToAsm/Format.hs
- compiler/GHC/CmmToAsm/LA64/CodeGen.hs
- compiler/GHC/CmmToAsm/Monad.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Graph.hs
- compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs
- compiler/GHC/CmmToAsm/Reg/Graph/SpillCost.hs
- compiler/GHC/CmmToAsm/Reg/Linear/State.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs
- compiler/GHC/CmmToAsm/Wasm.hs
- compiler/GHC/CmmToAsm/Wasm/Asm.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/Wasm/Types.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/Base.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion.hs-boot
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Core/LateCC/OverloadedCalls.hs
- compiler/GHC/Core/LateCC/TopLevelBinds.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Lint/Interactive.hs
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Core/Opt/CallerCC.hs
- compiler/GHC/Core/Opt/ConstantFold.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/Compare.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/TyCon/Env.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Type.hs-boot
- compiler/GHC/Core/Unify.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/Data/Bag.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Data/Graph/Collapse.hs
- compiler/GHC/Data/Graph/Color.hs
- compiler/GHC/Data/Graph/Directed.hs
- compiler/GHC/Data/List/Infinite.hs
- compiler/GHC/Data/List/NonEmpty.hs
- compiler/GHC/Data/Maybe.hs
- compiler/GHC/Data/Pair.hs
- compiler/GHC/Data/Stream.hs
- compiler/GHC/Data/Strict.hs
- compiler/GHC/Data/StringBuffer.hs
- compiler/GHC/Data/TrieMap.hs
- compiler/GHC/Data/Word64Map.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/CmdLine.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Config/Tidy.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Env/KnotVars.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Errors/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/GenerateCgIPEStub.hs
- compiler/GHC/Driver/Hooks.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeSem.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Pipeline/LogQueue.hs
- compiler/GHC/Driver/Pipeline/Monad.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Inspect.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Basic.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Doc.hs
- compiler/GHC/Hs/Doc.hs-boot
- compiler/GHC/Hs/DocString.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Expr.hs-boot
- compiler/GHC/Hs/Extension.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Pat.hs-boot
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Arrows.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Ppr.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/Decl.hs
- compiler/GHC/HsToCore/ListComp.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Check.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Pmc/Types.hs
- compiler/GHC/HsToCore/Pmc/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Env.hs
- compiler/GHC/Iface/Errors.hs
- compiler/GHC/Iface/Errors/Ppr.hs
- compiler/GHC/Iface/Errors/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Ext/Debug.hs
- compiler/GHC/Iface/Ext/Types.hs
- compiler/GHC/Iface/Ext/Utils.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/JS/Ident.hs
- compiler/GHC/JS/JStg/Monad.hs
- compiler/GHC/JS/JStg/Syntax.hs
- compiler/GHC/JS/Make.hs
- compiler/GHC/JS/Optimizer.hs
- compiler/GHC/JS/Ppr.hs
- compiler/GHC/JS/Syntax.hs
- compiler/GHC/JS/Transform.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Llvm/MetaData.hs
- compiler/GHC/Llvm/Ppr.hs
- compiler/GHC/Llvm/Types.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/Errors/Basic.hs
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Parser/String.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Platform.hs
- compiler/GHC/Platform/Reg/Class.hs
- compiler/GHC/Platform/Reg/Class/NoVectors.hs
- compiler/GHC/Platform/Reg/Class/Separate.hs
- compiler/GHC/Platform/Reg/Class/Unified.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Expr.hs-boot
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Heap/Layout.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/JS.hs
- compiler/GHC/Runtime/Interpreter/Process.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Runtime/Interpreter/Types/SymbolCache.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/Debug.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
- compiler/GHC/Stg/EnforceEpt/TagSig.hs
- compiler/GHC/Stg/EnforceEpt/Types.hs
- compiler/GHC/Stg/FVs.hs
- compiler/GHC/Stg/Lift/Analysis.hs
- compiler/GHC/Stg/Lift/Monad.hs
- compiler/GHC/Stg/Lift/Types.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/Stg/Syntax.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/Stg/Utils.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm.hs
- compiler/GHC/StgToCmm/ArgRep.hs
- compiler/GHC/StgToCmm/CgUtils.hs
- compiler/GHC/StgToCmm/Closure.hs
- compiler/GHC/StgToCmm/ExtCode.hs
- compiler/GHC/StgToCmm/Lit.hs
- compiler/GHC/StgToCmm/Monad.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToCmm/Utils.hs
- compiler/GHC/StgToJS/Apply.hs
- compiler/GHC/StgToJS/Arg.hs
- compiler/GHC/StgToJS/CodeGen.hs
- compiler/GHC/StgToJS/DataCon.hs
- compiler/GHC/StgToJS/Deps.hs
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/StgToJS/ExprCtx.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/StgToJS/Heap.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- compiler/GHC/StgToJS/Linker/Opt.hs
- compiler/GHC/StgToJS/Linker/Types.hs
- compiler/GHC/StgToJS/Literal.hs
- compiler/GHC/StgToJS/Monad.hs
- compiler/GHC/StgToJS/Object.hs
- compiler/GHC/StgToJS/Rts/Rts.hs
- compiler/GHC/StgToJS/Rts/Types.hs
- compiler/GHC/StgToJS/Sinker/Collect.hs
- compiler/GHC/StgToJS/Sinker/Sinker.hs
- compiler/GHC/StgToJS/Sinker/StringsUnfloat.hs
- compiler/GHC/StgToJS/Types.hs
- compiler/GHC/StgToJS/Utils.hs
- compiler/GHC/SysTools.hs
- compiler/GHC/SysTools/Ar.hs
- compiler/GHC/SysTools/BaseDir.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/SysTools/Terminal.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Functor.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Hole.hs
- compiler/GHC/Tc/Errors/Hole/FitTypes.hs
- compiler/GHC/Tc/Errors/Hole/Plugin.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Errors/Types/PromotionErr.hs
- compiler/GHC/Tc/Gen/Annotation.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Arrow.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Default.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Foreign.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Irred.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/ErrCtxt.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/Monad.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Annotations.hs
- compiler/GHC/Types/Avail.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/CompleteMatch.hs
- compiler/GHC/Types/CostCentre.hs
- compiler/GHC/Types/CostCentre/State.hs
- compiler/GHC/Types/DefaultEnv.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/FieldLabel.hs
- compiler/GHC/Types/Fixity.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/ForeignStubs.hs
- compiler/GHC/Types/GREInfo.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Types/Name.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Name/Set.hs
- compiler/GHC/Types/PkgQual.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/SaneDouble.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Types/SrcLoc.hs
- compiler/GHC/Types/Tickish.hs
- compiler/GHC/Types/TyThing.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/DSet.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Unique/Map.hs
- compiler/GHC/Types/Unique/SDFM.hs
- compiler/GHC/Types/Unique/Set.hs
- compiler/GHC/Types/Var.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Home/PackageTable.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/Module/Status.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Unit/Types.hs-boot
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Binary/Typeable.hs
- compiler/GHC/Utils/Exception.hs
- compiler/GHC/Utils/Json.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Misc.hs
- compiler/GHC/Utils/Monad/Codensity.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/GHC/Utils/Panic.hs
- compiler/GHC/Utils/Panic/Plain.hs
- compiler/GHC/Wasm/ControlFlow.hs
- compiler/GHC/Wasm/ControlFlow/FromCmm.hs
- compiler/Language/Haskell/Syntax.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Expr.hs-boot
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- compiler/Language/Haskell/Syntax/Pat.hs-boot
- compiler/Language/Haskell/Syntax/Type.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/ghci.rst
- ghc/GHC/Driver/Session/Lint.hs
- ghc/GHC/Driver/Session/Mode.hs
- ghc/GHCi/Leak.hs
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Exception.hs
- ghc/GHCi/UI/Info.hs
- ghc/GHCi/UI/Monad.hs
- ghc/Main.hs
- ghc/ghc-bin.cabal.in
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/ArgsHash.hs
- hadrian/src/Hadrian/Oracles/Cabal/Type.hs
- hadrian/src/Hadrian/Oracles/DirectoryContents.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/ModuleFiles.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- + libraries/base/src/System/IO/OS.hs
- libraries/exceptions
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Control/Monad/ST/Lazy/Imp.hs
- libraries/ghc-internal/src/GHC/Internal/Data/OldList.hs
- + libraries/ghc-internal/src/GHC/Internal/System/IO/OS.hs
- + rts/.ubsan-suppressions
- rts/Interpreter.c
- rts/include/stg/Types.h
- rts/rts.cabal
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- utils/haddock/haddock-api/haddock-api.cabal
- − utils/haddock/haddock-api/src/Haddock/Backends/HaddockDB.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0319831e3f9a15c42dd58b7d81fd8d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0319831e3f9a15c42dd58b7d81fd8d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0