Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
ce2d62fb
by Jessica Clarke at 2026-01-29T19:48:51-05:00
-
43d97761
by Michael Karcher at 2026-01-29T19:49:43-05:00
-
e8675d88
by Matthew Pickering at 2026-01-30T05:02:23-05:00
-
9a996fae
by Andrew Lelechenko at 2026-01-30T05:02:23-05:00
6 changed files:
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/Core/Map/Type.hs
- libraries/text
- + testsuite/tests/ghc-api/TypeMapStringLiteral.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
Changes:
| ... | ... | @@ -180,7 +180,7 @@ stmtToInstrs stmt = do |
| 180 | 180 | format = cmmTypeFormat ty
|
| 181 | 181 | |
| 182 | 182 | CmmUnsafeForeignCall target result_regs args
|
| 183 | - -> genCCall target result_regs args
|
|
| 183 | + -> genCCall platform target result_regs args
|
|
| 184 | 184 | |
| 185 | 185 | CmmBranch id -> genBranch id
|
| 186 | 186 | CmmCondBranch arg true false prediction -> do
|
| ... | ... | @@ -338,6 +338,8 @@ iselExpr64 (CmmReg (CmmLocal local_reg)) = do |
| 338 | 338 | let Reg64 hi lo = localReg64 local_reg
|
| 339 | 339 | return (RegCode64 nilOL hi lo)
|
| 340 | 340 | |
| 341 | +iselExpr64 regoff@(CmmRegOff _ _) = iselExpr64 $ mangleIndexTree regoff
|
|
| 342 | + |
|
| 341 | 343 | iselExpr64 (CmmLit (CmmInt i _)) = do
|
| 342 | 344 | Reg64 rhi rlo <- getNewReg64
|
| 343 | 345 | let
|
| ... | ... | @@ -1183,24 +1185,25 @@ genCondJump id bool prediction = do |
| 1183 | 1185 | -- @get_arg@, which moves the arguments to the correct registers/stack
|
| 1184 | 1186 | -- locations. Apart from that, the code is easy.
|
| 1185 | 1187 | |
| 1186 | -genCCall :: ForeignTarget -- function to call
|
|
| 1188 | +genCCall :: Platform
|
|
| 1189 | + -> ForeignTarget -- function to call
|
|
| 1187 | 1190 | -> [CmmFormal] -- where to put the result
|
| 1188 | 1191 | -> [CmmActual] -- arguments (of mixed type)
|
| 1189 | 1192 | -> NatM InstrBlock
|
| 1190 | -genCCall (PrimTarget MO_AcquireFence) _ _
|
|
| 1193 | +genCCall _ (PrimTarget MO_AcquireFence) _ _
|
|
| 1191 | 1194 | = return $ unitOL LWSYNC
|
| 1192 | -genCCall (PrimTarget MO_ReleaseFence) _ _
|
|
| 1195 | +genCCall _ (PrimTarget MO_ReleaseFence) _ _
|
|
| 1193 | 1196 | = return $ unitOL LWSYNC
|
| 1194 | -genCCall (PrimTarget MO_SeqCstFence) _ _
|
|
| 1197 | +genCCall _ (PrimTarget MO_SeqCstFence) _ _
|
|
| 1195 | 1198 | = return $ unitOL HWSYNC
|
| 1196 | 1199 | |
| 1197 | -genCCall (PrimTarget MO_Touch) _ _
|
|
| 1200 | +genCCall _ (PrimTarget MO_Touch) _ _
|
|
| 1198 | 1201 | = return $ nilOL
|
| 1199 | 1202 | |
| 1200 | -genCCall (PrimTarget (MO_Prefetch_Data _)) _ _
|
|
| 1203 | +genCCall _ (PrimTarget (MO_Prefetch_Data _)) _ _
|
|
| 1201 | 1204 | = return $ nilOL
|
| 1202 | 1205 | |
| 1203 | -genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]
|
|
| 1206 | +genCCall _ (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]
|
|
| 1204 | 1207 | = do let fmt = intFormat width
|
| 1205 | 1208 | reg_dst = getLocalRegReg dst
|
| 1206 | 1209 | (instr, n_code) <- case amop of
|
| ... | ... | @@ -1250,7 +1253,7 @@ genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] |
| 1250 | 1253 | (n_reg, n_code) <- getSomeReg n
|
| 1251 | 1254 | return (op dst dst (RIReg n_reg), n_code)
|
| 1252 | 1255 | |
| 1253 | -genCCall (PrimTarget (MO_AtomicRead width _)) [dst] [addr]
|
|
| 1256 | +genCCall _ (PrimTarget (MO_AtomicRead width _)) [dst] [addr]
|
|
| 1254 | 1257 | = do let fmt = intFormat width
|
| 1255 | 1258 | reg_dst = getLocalRegReg dst
|
| 1256 | 1259 | form = if widthInBits width == 64 then DS else D
|
| ... | ... | @@ -1277,12 +1280,12 @@ genCCall (PrimTarget (MO_AtomicRead width _)) [dst] [addr] |
| 1277 | 1280 | -- This is also what gcc does.
|
| 1278 | 1281 | |
| 1279 | 1282 | |
| 1280 | -genCCall (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do
|
|
| 1283 | +genCCall _ (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do
|
|
| 1281 | 1284 | code <- assignMem_IntCode (intFormat width) addr val
|
| 1282 | 1285 | return $ unitOL HWSYNC `appOL` code
|
| 1283 | 1286 | |
| 1284 | -genCCall (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]
|
|
| 1285 | - | width == W32 || width == W64
|
|
| 1287 | +genCCall platform (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]
|
|
| 1288 | + | width == W32 || (width == W64 && not (target32Bit platform))
|
|
| 1286 | 1289 | = do
|
| 1287 | 1290 | (old_reg, old_code) <- getSomeReg old
|
| 1288 | 1291 | (new_reg, new_code) <- getSomeReg new
|
| ... | ... | @@ -1311,9 +1314,8 @@ genCCall (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] |
| 1311 | 1314 | format = intFormat width
|
| 1312 | 1315 | |
| 1313 | 1316 | |
| 1314 | -genCCall (PrimTarget (MO_Clz width)) [dst] [src]
|
|
| 1315 | - = do platform <- getPlatform
|
|
| 1316 | - let reg_dst = getLocalRegReg dst
|
|
| 1317 | +genCCall platform (PrimTarget (MO_Clz width)) [dst] [src]
|
|
| 1318 | + = do let reg_dst = getLocalRegReg dst
|
|
| 1317 | 1319 | if target32Bit platform && width == W64
|
| 1318 | 1320 | then do
|
| 1319 | 1321 | RegCode64 code vr_hi vr_lo <- iselExpr64 src
|
| ... | ... | @@ -1361,9 +1363,8 @@ genCCall (PrimTarget (MO_Clz width)) [dst] [src] |
| 1361 | 1363 | let cntlz = unitOL (CNTLZ format reg_dst reg)
|
| 1362 | 1364 | return $ s_code `appOL` pre `appOL` cntlz `appOL` post
|
| 1363 | 1365 | |
| 1364 | -genCCall (PrimTarget (MO_Ctz width)) [dst] [src]
|
|
| 1365 | - = do platform <- getPlatform
|
|
| 1366 | - let reg_dst = getLocalRegReg dst
|
|
| 1366 | +genCCall platform (PrimTarget (MO_Ctz width)) [dst] [src]
|
|
| 1367 | + = do let reg_dst = getLocalRegReg dst
|
|
| 1367 | 1368 | if target32Bit platform && width == W64
|
| 1368 | 1369 | then do
|
| 1369 | 1370 | let format = II32
|
| ... | ... | @@ -1425,9 +1426,8 @@ genCCall (PrimTarget (MO_Ctz width)) [dst] [src] |
| 1425 | 1426 | , SUBFC dst r' (RIImm (ImmInt (format_bits)))
|
| 1426 | 1427 | ]
|
| 1427 | 1428 | |
| 1428 | -genCCall target dest_regs argsAndHints
|
|
| 1429 | - = do platform <- getPlatform
|
|
| 1430 | - case target of
|
|
| 1429 | +genCCall platform target dest_regs argsAndHints
|
|
| 1430 | + = do case target of
|
|
| 1431 | 1431 | PrimTarget (MO_S_QuotRem width) -> divOp1 True width
|
| 1432 | 1432 | dest_regs argsAndHints
|
| 1433 | 1433 | PrimTarget (MO_U_QuotRem width) -> divOp1 False width
|
| ... | ... | @@ -45,7 +45,7 @@ import GHC.Types.Name |
| 45 | 45 | import GHC.Types.Name.Env
|
| 46 | 46 | import GHC.Types.Var
|
| 47 | 47 | import GHC.Types.Var.Env
|
| 48 | -import GHC.Types.Unique.FM
|
|
| 48 | +import GHC.Types.Unique.DFM
|
|
| 49 | 49 | import GHC.Utils.Outputable
|
| 50 | 50 | |
| 51 | 51 | import GHC.Utils.Panic
|
| ... | ... | @@ -365,14 +365,14 @@ filterT f (TM { tm_var = tvar, tm_app = tapp, tm_tycon = ttycon |
| 365 | 365 | |
| 366 | 366 | ------------------------
|
| 367 | 367 | data TyLitMap a = TLM { tlm_number :: Map.Map Integer a
|
| 368 | - , tlm_string :: UniqFM FastString a
|
|
| 368 | + , tlm_string :: UniqDFM FastString a
|
|
| 369 | 369 | , tlm_char :: Map.Map Char a
|
| 370 | 370 | }
|
| 371 | 371 | |
| 372 | 372 | -- TODO(22292): derive
|
| 373 | 373 | instance Functor TyLitMap where
|
| 374 | 374 | fmap f TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc } = TLM
|
| 375 | - { tlm_number = Map.map f tn, tlm_string = mapUFM f ts, tlm_char = Map.map f tc }
|
|
| 375 | + { tlm_number = Map.map f tn, tlm_string = mapUDFM f ts, tlm_char = Map.map f tc }
|
|
| 376 | 376 | |
| 377 | 377 | instance TrieMap TyLitMap where
|
| 378 | 378 | type Key TyLitMap = TyLit
|
| ... | ... | @@ -384,34 +384,34 @@ instance TrieMap TyLitMap where |
| 384 | 384 | mapMaybeTM = mpTyLit
|
| 385 | 385 | |
| 386 | 386 | emptyTyLitMap :: TyLitMap a
|
| 387 | -emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = emptyUFM, tlm_char = Map.empty }
|
|
| 387 | +emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = emptyUDFM, tlm_char = Map.empty }
|
|
| 388 | 388 | |
| 389 | 389 | lkTyLit :: TyLit -> TyLitMap a -> Maybe a
|
| 390 | 390 | lkTyLit l =
|
| 391 | 391 | case l of
|
| 392 | 392 | NumTyLit n -> tlm_number >.> Map.lookup n
|
| 393 | - StrTyLit n -> tlm_string >.> (`lookupUFM` n)
|
|
| 393 | + StrTyLit n -> tlm_string >.> (`lookupUDFM` n)
|
|
| 394 | 394 | CharTyLit n -> tlm_char >.> Map.lookup n
|
| 395 | 395 | |
| 396 | 396 | xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a
|
| 397 | 397 | xtTyLit l f m =
|
| 398 | 398 | case l of
|
| 399 | 399 | NumTyLit n -> m { tlm_number = Map.alter f n (tlm_number m) }
|
| 400 | - StrTyLit n -> m { tlm_string = alterUFM f (tlm_string m) n }
|
|
| 400 | + StrTyLit n -> m { tlm_string = alterUDFM f (tlm_string m) n }
|
|
| 401 | 401 | CharTyLit n -> m { tlm_char = Map.alter f n (tlm_char m) }
|
| 402 | 402 | |
| 403 | 403 | foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b
|
| 404 | -foldTyLit l m = flip (nonDetFoldUFM l) (tlm_string m)
|
|
| 404 | +foldTyLit l m = flip (foldUDFM l) (tlm_string m)
|
|
| 405 | 405 | . flip (Map.foldr l) (tlm_number m)
|
| 406 | 406 | . flip (Map.foldr l) (tlm_char m)
|
| 407 | 407 | |
| 408 | 408 | filterTyLit :: (a -> Bool) -> TyLitMap a -> TyLitMap a
|
| 409 | 409 | filterTyLit f (TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc })
|
| 410 | - = TLM { tlm_number = Map.filter f tn, tlm_string = filterUFM f ts, tlm_char = Map.filter f tc }
|
|
| 410 | + = TLM { tlm_number = Map.filter f tn, tlm_string = filterUDFM f ts, tlm_char = Map.filter f tc }
|
|
| 411 | 411 | |
| 412 | 412 | mpTyLit :: (a -> Maybe b) -> TyLitMap a -> TyLitMap b
|
| 413 | 413 | mpTyLit f (TLM { tlm_number = tn, tlm_string = ts, tlm_char = tc })
|
| 414 | - = TLM { tlm_number = Map.mapMaybe f tn, tlm_string = mapMaybeUFM f ts, tlm_char = Map.mapMaybe f tc }
|
|
| 414 | + = TLM { tlm_number = Map.mapMaybe f tn, tlm_string = mapMaybeUDFM f ts, tlm_char = Map.mapMaybe f tc }
|
|
| 415 | 415 | |
| 416 | 416 | -------------------------------------------------
|
| 417 | 417 | -- | @TypeMap a@ is a map from 'Type' to @a@. If you are a client, this
|
| 1 | -Subproject commit 5f343f668f421bfb30cead594e52d0ac6206ff67 |
|
| 1 | +Subproject commit 423fd981e576bd17a8b5fa48d0ad6b9a0c370e77 |
| 1 | +{-# LANGUAGE OverloadedStrings #-}
|
|
| 2 | +module Main (main) where
|
|
| 3 | + |
|
| 4 | +import Control.Monad (unless)
|
|
| 5 | +import qualified Data.ByteString.Char8 as BSC
|
|
| 6 | +import qualified Data.ByteString.Short as SBS
|
|
| 7 | +import Data.Char (ord)
|
|
| 8 | +import Data.List (foldl')
|
|
| 9 | +import GHC.Core.Map.Type (TypeMap, emptyTypeMap, extendTypeMap, foldTypeMap)
|
|
| 10 | +import GHC.Core.Type (Type, mkStrLitTy)
|
|
| 11 | +import GHC.Data.FastString (FastString (..), FastZString (..))
|
|
| 12 | +import GHC.Utils.Encoding (zEncodeString)
|
|
| 13 | + |
|
| 14 | +main :: IO ()
|
|
| 15 | +main = do
|
|
| 16 | + let logicalEntries =
|
|
| 17 | + [ ("alpha", "payload-alpha")
|
|
| 18 | + , ("beta", "payload-beta")
|
|
| 19 | + , ("gamma", "payload-gamma")
|
|
| 20 | + ]
|
|
| 21 | + uniquesOne = [1, 2, 3]
|
|
| 22 | + uniquesTwo = [200, 100, 500]
|
|
| 23 | + |
|
| 24 | + tmOne = buildMap logicalEntries uniquesOne
|
|
| 25 | + tmTwo = buildMap logicalEntries uniquesTwo
|
|
| 26 | + |
|
| 27 | + foldedOne = foldValues tmOne
|
|
| 28 | + foldedTwo = foldValues tmTwo
|
|
| 29 | + |
|
| 30 | + assert "foldTypeMap order independent of FastString uniques" $
|
|
| 31 | + foldedOne == foldedTwo
|
|
| 32 | + |
|
| 33 | + |
|
| 34 | +buildMap :: [(String, a)] -> [Int] -> TypeMap a
|
|
| 35 | +buildMap entries uniques =
|
|
| 36 | + foldl' insertEntry emptyTypeMap (zip uniques entries)
|
|
| 37 | + where
|
|
| 38 | + insertEntry :: TypeMap a -> (Int, (String, a)) -> TypeMap a
|
|
| 39 | + insertEntry tm (u, (txt, payload)) =
|
|
| 40 | + extendTypeMap tm (strLiteralWithUnique u txt) payload
|
|
| 41 | + |
|
| 42 | +foldValues :: TypeMap a -> [a]
|
|
| 43 | +foldValues tm = foldTypeMap (:) [] tm
|
|
| 44 | + |
|
| 45 | +strLiteralWithUnique :: Int -> String -> Type
|
|
| 46 | +strLiteralWithUnique u = mkStrLitTy . fakeFastString u
|
|
| 47 | + |
|
| 48 | +fakeFastString :: Int -> String -> FastString
|
|
| 49 | +fakeFastString u s = FastString
|
|
| 50 | + { uniq = u
|
|
| 51 | + , n_chars = length s
|
|
| 52 | + , fs_sbs = SBS.pack (map (fromIntegral . ord) s)
|
|
| 53 | + , fs_zenc = error "unused"
|
|
| 54 | + }
|
|
| 55 | + |
|
| 56 | +assert :: String -> Bool -> IO ()
|
|
| 57 | +assert label condition = unless condition $
|
|
| 58 | + error ("TypeMap string literal test failed: " ++ label) |
| ... | ... | @@ -74,3 +74,4 @@ test('T25577', [ extra_run_opts(f'"{config.libdir}"') |
| 74 | 74 | test('T26120', [], compile_and_run, ['-package ghc'])
|
| 75 | 75 | |
| 76 | 76 | test('T26264', normal, compile_and_run, ['-package ghc'])
|
| 77 | +test('TypeMapStringLiteral', normal, compile_and_run, ['-package ghc']) |
| ... | ... | @@ -30,7 +30,13 @@ RecordDotSyntaxFail8.hs:53:17: error: [GHC-39999] |
| 30 | 30 | • No instance for ‘HasField "quux3" Quux r0’
|
| 31 | 31 | arising from selecting the field ‘quux3’
|
| 32 | 32 | NB: ‘HasField’ is not the built-in ‘GHC.Internal.Records.HasField’ class.
|
| 33 | - • In the expression: ....bar.baz.quux3
|
|
| 34 | - In the second argument of ‘($)’, namely ‘....baz.quux3.wob’
|
|
| 33 | + • In the second argument of ‘($)’, namely ‘....baz.quux3.wob’
|
|
| 35 | 34 | In a stmt of a 'do' block: print @Bool $ ....quux3.wob
|
| 35 | + In the expression:
|
|
| 36 | + do let a = Foo {foo = ...}
|
|
| 37 | + print @Quux $ ....quux1
|
|
| 38 | + let b = myQuux
|
|
| 39 | + print @Quux $ b.quux2
|
|
| 40 | + let c = Foo {foo = ...}
|
|
| 41 | + ...
|
|
| 36 | 42 |