Simon Jakobi pushed to branch wip/sjakobi/upsert at Glasgow Haskell Compiler / GHC
Commits:
-
c75616e1
by Simon Jakobi at 2026-04-01T21:36:59+02:00
20 changed files:
- compiler/GHC/Cmm/CommonBlockElim.hs
- compiler/GHC/Cmm/Dataflow/Graph.hs
- compiler/GHC/Cmm/Dataflow/Label.hs
- compiler/GHC/CmmToAsm/CFG.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/TyCon/Env.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Data/FastString/Env.hs
- compiler/GHC/Data/Word64Map/Internal.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Data/Word64Map/Strict.hs
- compiler/GHC/Data/Word64Map/Strict/Internal.hs
- compiler/GHC/Tc/Solver/Types.hs
- compiler/GHC/Types/Name/Env.hs
- compiler/GHC/Types/Name/Occurrence.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/GHC/Wasm/ControlFlow/FromCmm.hs
Changes:
| ... | ... | @@ -307,6 +307,6 @@ groupByInt :: (a -> Int) -> [a] -> [[a]] |
| 307 | 307 | groupByInt f xs = nonDetEltsUFM $ List.foldl' go emptyUFM xs
|
| 308 | 308 | -- See Note [Unique Determinism and code generation]
|
| 309 | 309 | where
|
| 310 | - go m x = alterUFM addEntry m (f x)
|
|
| 310 | + go m x = strictUpsertUFM addEntry m (f x)
|
|
| 311 | 311 | where
|
| 312 | - addEntry xs = Just $! maybe [x] (x:) xs |
|
| 312 | + addEntry = maybe [x] (x:) |
| ... | ... | @@ -56,10 +56,10 @@ bodyToBlockList body = mapElems body |
| 56 | 56 | addBlock
|
| 57 | 57 | :: (NonLocal block, HasDebugCallStack)
|
| 58 | 58 | => block C C -> LabelMap (block C C) -> LabelMap (block C C)
|
| 59 | -addBlock block body = mapAlter add lbl body
|
|
| 59 | +addBlock block body = mapUpsert add lbl body
|
|
| 60 | 60 | where
|
| 61 | 61 | lbl = entryLabel block
|
| 62 | - add Nothing = Just block
|
|
| 62 | + add Nothing = block
|
|
| 63 | 63 | add _ = error $ "duplicate label " ++ show lbl ++ " in graph"
|
| 64 | 64 | |
| 65 | 65 |
| ... | ... | @@ -38,6 +38,7 @@ module GHC.Cmm.Dataflow.Label |
| 38 | 38 | , mapInsertWith
|
| 39 | 39 | , mapDelete
|
| 40 | 40 | , mapAlter
|
| 41 | + , mapUpsert
|
|
| 41 | 42 | , mapAdjust
|
| 42 | 43 | , mapUnion
|
| 43 | 44 | , mapUnions
|
| ... | ... | @@ -207,6 +208,9 @@ mapDelete (Label k) (LM m) = LM (M.delete k m) |
| 207 | 208 | mapAlter :: (Maybe v -> Maybe v) -> Label -> LabelMap v -> LabelMap v
|
| 208 | 209 | mapAlter f (Label k) (LM m) = LM (M.alter f k m)
|
| 209 | 210 | |
| 211 | +mapUpsert :: (Maybe v -> v) -> Label -> LabelMap v -> LabelMap v
|
|
| 212 | +mapUpsert f (Label k) (LM m) = LM (M.upsert f k m)
|
|
| 213 | + |
|
| 210 | 214 | mapAdjust :: (v -> v) -> Label -> LabelMap v -> LabelMap v
|
| 211 | 215 | mapAdjust f (Label k) (LM m) = LM (M.adjust f k m)
|
| 212 | 216 |
| ... | ... | @@ -357,15 +357,14 @@ addImmediateSuccessor weights node follower cfg |
| 357 | 357 | -- | Adds a new edge, overwrites existing edges if present
|
| 358 | 358 | addEdge :: BlockId -> BlockId -> EdgeInfo -> CFG -> CFG
|
| 359 | 359 | addEdge from to info cfg =
|
| 360 | - mapAlter addFromToEdge from $
|
|
| 361 | - mapAlter addDestNode to cfg
|
|
| 360 | + mapUpsert addFromToEdge from $
|
|
| 361 | + mapUpsert addDestNode to cfg
|
|
| 362 | 362 | where
|
| 363 | 363 | -- Simply insert the edge into the edge list.
|
| 364 | - addFromToEdge Nothing = Just $ mapSingleton to info
|
|
| 365 | - addFromToEdge (Just wm) = Just $ mapInsert to info wm
|
|
| 364 | + addFromToEdge Nothing = mapSingleton to info
|
|
| 365 | + addFromToEdge (Just wm) = mapInsert to info wm
|
|
| 366 | 366 | -- We must add the destination node explicitly
|
| 367 | - addDestNode Nothing = Just $ mapEmpty
|
|
| 368 | - addDestNode n@(Just _) = n
|
|
| 367 | + addDestNode = fromMaybe mapEmpty
|
|
| 369 | 368 | |
| 370 | 369 | |
| 371 | 370 | -- | Adds a edge with the given weight to the cfg
|
| ... | ... | @@ -610,11 +609,11 @@ getCfg platform weights graph = |
| 610 | 609 | edgelessCfg = mapFromList $ zip (map G.entryLabel blocks) (repeat mapEmpty)
|
| 611 | 610 | insertEdge :: CFG -> ((BlockId,BlockId),EdgeInfo) -> CFG
|
| 612 | 611 | insertEdge m ((from,to),weight) =
|
| 613 | - mapAlter f from m
|
|
| 612 | + mapUpsert f from m
|
|
| 614 | 613 | where
|
| 615 | - f :: Maybe (LabelMap EdgeInfo) -> Maybe (LabelMap EdgeInfo)
|
|
| 616 | - f Nothing = Just $ mapSingleton to weight
|
|
| 617 | - f (Just destMap) = Just $ mapInsert to weight destMap
|
|
| 614 | + f :: Maybe (LabelMap EdgeInfo) -> LabelMap EdgeInfo
|
|
| 615 | + f Nothing = mapSingleton to weight
|
|
| 616 | + f (Just destMap) = mapInsert to weight destMap
|
|
| 618 | 617 | getBlockEdges :: CmmBlock -> [((BlockId,BlockId),EdgeInfo)]
|
| 619 | 618 | getBlockEdges block =
|
| 620 | 619 | case branch of
|
| ... | ... | @@ -4297,7 +4297,7 @@ unconditional-inlining for join points. |
| 4297 | 4297 | postInlineUnconditionally is primarily to push allocation into cold
|
| 4298 | 4298 | branches; but a join point doesn't allocate, so that's a non-motivation.
|
| 4299 | 4299 | |
| 4300 | -(DJ2) In mkDupableAlt and mkDupableStrictBind, generate an alterative for /all/
|
|
| 4300 | +(DJ2) In mkDupableAlt and mkDupableStrictBind, generate an alternative for /all/
|
|
| 4301 | 4301 | alternatives, /except/ for ones that will definitely inline unconditionally
|
| 4302 | 4302 | straight away. (In that case it's silly to make a join point in the first
|
| 4303 | 4303 | place; it just takes an extra Simplifier iteration to undo.) This choice is
|
| ... | ... | @@ -39,6 +39,7 @@ import GHC.Types.Name.Env |
| 39 | 39 | |
| 40 | 40 | import Control.Monad (join)
|
| 41 | 41 | import Data.Data (Data)
|
| 42 | +import Data.Maybe (fromMaybe)
|
|
| 42 | 43 | import GHC.Utils.Panic
|
| 43 | 44 | |
| 44 | 45 | {-
|
| ... | ... | @@ -449,10 +450,9 @@ insertRM [] v rm@(RM {}) = |
| 449 | 450 | rm { rm_empty = v `consBag` rm_empty rm }
|
| 450 | 451 | |
| 451 | 452 | insertRM (RM_KnownTc k : ks) v rm@(RM {}) =
|
| 452 | - rm { rm_known = alterDNameEnv f (rm_known rm) k }
|
|
| 453 | + rm { rm_known = upsertDNameEnv f (rm_known rm) k }
|
|
| 453 | 454 | where
|
| 454 | - f Nothing = Just $ (insertRM ks v emptyRM)
|
|
| 455 | - f (Just m) = Just $ (insertRM ks v m)
|
|
| 455 | + f = insertRM ks v . fromMaybe emptyRM
|
|
| 456 | 456 | |
| 457 | 457 | insertRM (RM_WildCard : ks) v rm@(RM {}) =
|
| 458 | 458 | rm { rm_wild = insertRM ks v (rm_wild rm) }
|
| ... | ... | @@ -19,7 +19,7 @@ module GHC.Core.TyCon.Env ( |
| 19 | 19 | extendTyConEnv_C, extendTyConEnv_Acc, extendTyConEnv,
|
| 20 | 20 | extendTyConEnvList, extendTyConEnvList_C,
|
| 21 | 21 | filterTyConEnv, anyTyConEnv,
|
| 22 | - plusTyConEnv, plusTyConEnv_C, plusTyConEnv_CD, plusTyConEnv_CD2, alterTyConEnv,
|
|
| 22 | + plusTyConEnv, plusTyConEnv_C, plusTyConEnv_CD, plusTyConEnv_CD2, upsertTyConEnv, alterTyConEnv,
|
|
| 23 | 23 | lookupTyConEnv, lookupTyConEnv_NF, delFromTyConEnv, delListFromTyConEnv,
|
| 24 | 24 | elemTyConEnv, mapTyConEnv, disjointTyConEnv,
|
| 25 | 25 | |
| ... | ... | @@ -29,7 +29,7 @@ module GHC.Core.TyCon.Env ( |
| 29 | 29 | lookupDTyConEnv,
|
| 30 | 30 | delFromDTyConEnv, filterDTyConEnv,
|
| 31 | 31 | mapDTyConEnv, mapMaybeDTyConEnv,
|
| 32 | - adjustDTyConEnv, alterDTyConEnv, extendDTyConEnv, foldDTyConEnv
|
|
| 32 | + adjustDTyConEnv, upsertDTyConEnv, alterDTyConEnv, extendDTyConEnv, foldDTyConEnv
|
|
| 33 | 33 | ) where
|
| 34 | 34 | |
| 35 | 35 | import GHC.Prelude
|
| ... | ... | @@ -57,6 +57,7 @@ mkTyConEnv :: [(TyCon,a)] -> TyConEnv a |
| 57 | 57 | mkTyConEnvWith :: (a -> TyCon) -> [a] -> TyConEnv a
|
| 58 | 58 | nonDetTyConEnvElts :: TyConEnv a -> [a]
|
| 59 | 59 | alterTyConEnv :: (Maybe a-> Maybe a) -> TyConEnv a -> TyCon -> TyConEnv a
|
| 60 | +upsertTyConEnv :: (Maybe a -> a) -> TyConEnv a -> TyCon -> TyConEnv a
|
|
| 60 | 61 | extendTyConEnv_C :: (a->a->a) -> TyConEnv a -> TyCon -> a -> TyConEnv a
|
| 61 | 62 | extendTyConEnv_Acc :: (a->b->b) -> (a->b) -> TyConEnv b -> TyCon -> a -> TyConEnv b
|
| 62 | 63 | extendTyConEnv :: TyConEnv a -> TyCon -> a -> TyConEnv a
|
| ... | ... | @@ -85,6 +86,7 @@ extendTyConEnv x y z = addToUFM x y z |
| 85 | 86 | extendTyConEnvList x l = addListToUFM x l
|
| 86 | 87 | lookupTyConEnv x y = lookupUFM x y
|
| 87 | 88 | alterTyConEnv = alterUFM
|
| 89 | +upsertTyConEnv = upsertUFM
|
|
| 88 | 90 | mkTyConEnv l = listToUFM l
|
| 89 | 91 | mkTyConEnvWith f = mkTyConEnv . map (\a -> (f a, a))
|
| 90 | 92 | elemTyConEnv x y = elemUFM x y
|
| ... | ... | @@ -137,6 +139,9 @@ adjustDTyConEnv = adjustUDFM |
| 137 | 139 | alterDTyConEnv :: (Maybe a -> Maybe a) -> DTyConEnv a -> TyCon -> DTyConEnv a
|
| 138 | 140 | alterDTyConEnv = alterUDFM
|
| 139 | 141 | |
| 142 | +upsertDTyConEnv :: (Maybe a -> a) -> DTyConEnv a -> TyCon -> DTyConEnv a
|
|
| 143 | +upsertDTyConEnv = upsertUDFM
|
|
| 144 | + |
|
| 140 | 145 | extendDTyConEnv :: DTyConEnv a -> TyCon -> a -> DTyConEnv a
|
| 141 | 146 | extendDTyConEnv = addToUDFM
|
| 142 | 147 |
| ... | ... | @@ -2211,10 +2211,10 @@ extendFamEnv tc tys ty = UM $ \state -> |
| 2211 | 2211 | Unifiable (state { um_fam_env = extend (um_fam_env state) tc }, ())
|
| 2212 | 2212 | where
|
| 2213 | 2213 | extend :: FamSubstEnv -> TyCon -> FamSubstEnv
|
| 2214 | - extend = alterTyConEnv alter_tm
|
|
| 2214 | + extend = upsertTyConEnv alter_tm
|
|
| 2215 | 2215 | |
| 2216 | - alter_tm :: Maybe (ListMap TypeMap Type) -> Maybe (ListMap TypeMap Type)
|
|
| 2217 | - alter_tm m_elt = Just (alterTM tys (\_ -> Just ty) (m_elt `orElse` emptyTM))
|
|
| 2216 | + alter_tm :: Maybe (ListMap TypeMap Type) -> ListMap TypeMap Type
|
|
| 2217 | + alter_tm m_elt = alterTM tys (\_ -> Just ty) (m_elt `orElse` emptyTM)
|
|
| 2218 | 2218 | |
| 2219 | 2219 | umRnBndr2 :: UMEnv -> TyCoVar -> TyCoVar -> UMEnv
|
| 2220 | 2220 | umRnBndr2 env v1 v2
|
| ... | ... | @@ -16,7 +16,7 @@ module GHC.Data.FastString.Env ( |
| 16 | 16 | extendFsEnv_C, extendFsEnv_Acc, extendFsEnv,
|
| 17 | 17 | extendFsEnvList, extendFsEnvList_C,
|
| 18 | 18 | filterFsEnv,
|
| 19 | - plusFsEnv, plusFsEnv_C, alterFsEnv,
|
|
| 19 | + plusFsEnv, plusFsEnv_C, alterFsEnv, upsertFsEnv,
|
|
| 20 | 20 | lookupFsEnv, lookupFsEnv_NF, delFromFsEnv, delListFromFsEnv,
|
| 21 | 21 | elemFsEnv, mapFsEnv, strictMapFsEnv, mapMaybeFsEnv,
|
| 22 | 22 | nonDetFoldFsEnv,
|
| ... | ... | @@ -46,6 +46,7 @@ type FastStringEnv a = UniqFM FastString a -- Domain is FastString |
| 46 | 46 | emptyFsEnv :: FastStringEnv a
|
| 47 | 47 | mkFsEnv :: [(FastString,a)] -> FastStringEnv a
|
| 48 | 48 | alterFsEnv :: (Maybe a-> Maybe a) -> FastStringEnv a -> FastString -> FastStringEnv a
|
| 49 | +upsertFsEnv :: (Maybe a -> a) -> FastStringEnv a -> FastString -> FastStringEnv a
|
|
| 49 | 50 | extendFsEnv_C :: (a->a->a) -> FastStringEnv a -> FastString -> a -> FastStringEnv a
|
| 50 | 51 | extendFsEnv_Acc :: (a->b->b) -> (a->b) -> FastStringEnv b -> FastString -> a -> FastStringEnv b
|
| 51 | 52 | extendFsEnv :: FastStringEnv a -> FastString -> a -> FastStringEnv a
|
| ... | ... | @@ -69,6 +70,7 @@ extendFsEnv x y z = addToUFM x y z |
| 69 | 70 | extendFsEnvList x l = addListToUFM x l
|
| 70 | 71 | lookupFsEnv x y = lookupUFM x y
|
| 71 | 72 | alterFsEnv = alterUFM
|
| 73 | +upsertFsEnv = upsertUFM
|
|
| 72 | 74 | mkFsEnv l = listToUFM l
|
| 73 | 75 | elemFsEnv x y = elemUFM x y
|
| 74 | 76 | plusFsEnv x y = plusUFM x y
|
| ... | ... | @@ -98,6 +98,7 @@ module GHC.Data.Word64Map.Internal ( |
| 98 | 98 | , adjustWithKey
|
| 99 | 99 | , update
|
| 100 | 100 | , updateWithKey
|
| 101 | + , upsert
|
|
| 101 | 102 | , updateLookupWithKey
|
| 102 | 103 | , alter
|
| 103 | 104 | , alterLookup
|
| ... | ... | @@ -941,6 +942,24 @@ updateWithKey f k t@(Tip ky y) |
| 941 | 942 | | otherwise = t
|
| 942 | 943 | updateWithKey _ _ Nil = Nil
|
| 943 | 944 | |
| 945 | +-- | \(O(\min(n,W))\). Update the value at a key or insert a value if the key is
|
|
| 946 | +-- not in the map.
|
|
| 947 | +--
|
|
| 948 | +-- @
|
|
| 949 | +-- let inc = maybe 1 (+1)
|
|
| 950 | +-- upsert inc 100 (fromList [(100,1),(300,2)]) == fromList [(100,2),(300,2)]
|
|
| 951 | +-- upsert inc 200 (fromList [(100,1),(300,2)]) == fromList [(100,1),(200,1),(300,2)]
|
|
| 952 | +-- @
|
|
| 953 | +upsert :: (Maybe a -> a) -> Key -> Word64Map a -> Word64Map a
|
|
| 954 | +upsert f !k t@(Bin p m l r)
|
|
| 955 | + | nomatch k p m = link k (Tip k (f Nothing)) p t
|
|
| 956 | + | zero k m = Bin p m (upsert f k l) r
|
|
| 957 | + | otherwise = Bin p m l (upsert f k r)
|
|
| 958 | +upsert f !k t@(Tip ky y)
|
|
| 959 | + | k == ky = Tip ky (f (Just y))
|
|
| 960 | + | otherwise = link k (Tip k (f Nothing)) ky t
|
|
| 961 | +upsert f !k Nil = Tip k (f Nothing)
|
|
| 962 | + |
|
| 944 | 963 | -- | \(O(\min(n,W))\). Lookup and update.
|
| 945 | 964 | -- The function returns original value, if it is updated.
|
| 946 | 965 | -- This is different behavior than 'Data.Map.updateLookupWithKey'.
|
| ... | ... | @@ -91,6 +91,7 @@ module GHC.Data.Word64Map.Lazy ( |
| 91 | 91 | , adjustWithKey
|
| 92 | 92 | , update
|
| 93 | 93 | , updateWithKey
|
| 94 | + , upsert
|
|
| 94 | 95 | , updateLookupWithKey
|
| 95 | 96 | , alter
|
| 96 | 97 | , alterLookup
|
| ... | ... | @@ -109,6 +109,7 @@ module GHC.Data.Word64Map.Strict ( |
| 109 | 109 | , adjustWithKey
|
| 110 | 110 | , update
|
| 111 | 111 | , updateWithKey
|
| 112 | + , upsert
|
|
| 112 | 113 | , updateLookupWithKey
|
| 113 | 114 | , alter
|
| 114 | 115 | , alterF
|
| ... | ... | @@ -111,6 +111,7 @@ module GHC.Data.Word64Map.Strict.Internal ( |
| 111 | 111 | , adjustWithKey
|
| 112 | 112 | , update
|
| 113 | 113 | , updateWithKey
|
| 114 | + , upsert
|
|
| 114 | 115 | , updateLookupWithKey
|
| 115 | 116 | , alter
|
| 116 | 117 | , alterF
|
| ... | ... | @@ -536,6 +537,24 @@ updateWithKey f !k t = |
| 536 | 537 | | otherwise -> t
|
| 537 | 538 | Nil -> Nil
|
| 538 | 539 | |
| 540 | +-- | \(O(\min(n,W))\). Update the value at a key or insert a value if the key is
|
|
| 541 | +-- not in the map.
|
|
| 542 | +--
|
|
| 543 | +-- @
|
|
| 544 | +-- let inc = maybe 1 (+1)
|
|
| 545 | +-- upsert inc 100 (fromList [(100,1),(300,2)]) == fromList [(100,2),(300,2)]
|
|
| 546 | +-- upsert inc 200 (fromList [(100,1),(300,2)]) == fromList [(100,1),(200,1),(300,2)]
|
|
| 547 | +-- @
|
|
| 548 | +upsert :: (Maybe a -> a) -> Key -> Word64Map a -> Word64Map a
|
|
| 549 | +upsert f !k t@(Bin p m l r)
|
|
| 550 | + | nomatch k p m = link k (Tip k $! f Nothing) p t
|
|
| 551 | + | zero k m = Bin p m (upsert f k l) r
|
|
| 552 | + | otherwise = Bin p m l (upsert f k r)
|
|
| 553 | +upsert f !k t@(Tip ky y)
|
|
| 554 | + | k == ky = Tip ky $! f (Just y)
|
|
| 555 | + | otherwise = link k (Tip k (f Nothing)) ky t
|
|
| 556 | +upsert f !k Nil = Tip k $! f Nothing
|
|
| 557 | + |
|
| 539 | 558 | -- | \(O(\min(n,W))\). Lookup and update.
|
| 540 | 559 | -- The function returns original value, if it is updated.
|
| 541 | 560 | -- This is different behavior than 'Data.Map.updateLookupWithKey'.
|
| ... | ... | @@ -89,15 +89,15 @@ delTcApp :: TcAppMap a -> TyCon -> [Type] -> TcAppMap a |
| 89 | 89 | delTcApp m tc tys = adjustDTyConEnv (deleteTM tys) m tc
|
| 90 | 90 | |
| 91 | 91 | insertTcApp :: TcAppMap a -> TyCon -> [Type] -> a -> TcAppMap a
|
| 92 | -insertTcApp m tc tys ct = alterDTyConEnv alter_tm m tc
|
|
| 92 | +insertTcApp m tc tys ct = upsertDTyConEnv alter_tm m tc
|
|
| 93 | 93 | where
|
| 94 | - alter_tm mb_tm = Just (insertTM tys ct (mb_tm `orElse` emptyTM))
|
|
| 94 | + alter_tm mb_tm = insertTM tys ct (mb_tm `orElse` emptyTM)
|
|
| 95 | 95 | |
| 96 | 96 | alterTcApp :: forall a. TcAppMap a -> TyCon -> [Type] -> XT a -> TcAppMap a
|
| 97 | -alterTcApp m tc tys upd = alterDTyConEnv alter_tm m tc
|
|
| 97 | +alterTcApp m tc tys upd = upsertDTyConEnv alter_tm m tc
|
|
| 98 | 98 | where
|
| 99 | - alter_tm :: Maybe (ListMap LooseTypeMap a) -> Maybe (ListMap LooseTypeMap a)
|
|
| 100 | - alter_tm m_elt = Just (alterTM tys upd (m_elt `orElse` emptyTM))
|
|
| 99 | + alter_tm :: Maybe (ListMap LooseTypeMap a) -> ListMap LooseTypeMap a
|
|
| 100 | + alter_tm m_elt = alterTM tys upd (m_elt `orElse` emptyTM)
|
|
| 101 | 101 | |
| 102 | 102 | filterTcAppMap :: forall a. (a -> Bool) -> TcAppMap a -> TcAppMap a
|
| 103 | 103 | filterTcAppMap f m = mapMaybeDTyConEnv one_tycon m
|
| ... | ... | @@ -19,7 +19,7 @@ module GHC.Types.Name.Env ( |
| 19 | 19 | filterNameEnv, anyNameEnv,
|
| 20 | 20 | mapMaybeNameEnv,
|
| 21 | 21 | extendNameEnvListWith,
|
| 22 | - plusNameEnv, plusNameEnv_C, plusNameEnv_CD, plusNameEnv_CD2, alterNameEnv,
|
|
| 22 | + plusNameEnv, plusNameEnv_C, plusNameEnv_CD, plusNameEnv_CD2, alterNameEnv, upsertNameEnv,
|
|
| 23 | 23 | plusNameEnvList, plusNameEnvListWith,
|
| 24 | 24 | lookupNameEnv, lookupNameEnv_NF, delFromNameEnv, delListFromNameEnv,
|
| 25 | 25 | elemNameEnv, mapNameEnv, disjointNameEnv,
|
| ... | ... | @@ -32,7 +32,10 @@ module GHC.Types.Name.Env ( |
| 32 | 32 | lookupDNameEnv,
|
| 33 | 33 | delFromDNameEnv, filterDNameEnv,
|
| 34 | 34 | mapDNameEnv,
|
| 35 | - adjustDNameEnv, alterDNameEnv, extendDNameEnv,
|
|
| 35 | + adjustDNameEnv,
|
|
| 36 | + upsertDNameEnv,
|
|
| 37 | + alterDNameEnv,
|
|
| 38 | + extendDNameEnv,
|
|
| 36 | 39 | eltsDNameEnv, extendDNameEnv_C,
|
| 37 | 40 | plusDNameEnv_C,
|
| 38 | 41 | foldDNameEnv,
|
| ... | ... | @@ -107,6 +110,7 @@ mkNameEnvWith :: (a -> Name) -> [a] -> NameEnv a |
| 107 | 110 | fromUniqMap :: UniqMap Name a -> NameEnv a
|
| 108 | 111 | nonDetNameEnvElts :: NameEnv a -> [a]
|
| 109 | 112 | alterNameEnv :: (Maybe a-> Maybe a) -> NameEnv a -> Name -> NameEnv a
|
| 113 | +upsertNameEnv :: (Maybe a -> a) -> NameEnv a -> Name -> NameEnv a
|
|
| 110 | 114 | extendNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
|
| 111 | 115 | extendNameEnv_Acc :: (a->b->b) -> (a->b) -> NameEnv b -> Name -> a -> NameEnv b
|
| 112 | 116 | extendNameEnv :: NameEnv a -> Name -> a -> NameEnv a
|
| ... | ... | @@ -141,6 +145,7 @@ extendNameEnvList x l = addListToUFM x l |
| 141 | 145 | extendNameEnvListWith f x l = addListToUFM x (map (\a -> (f a, a)) l)
|
| 142 | 146 | lookupNameEnv x y = lookupUFM x y
|
| 143 | 147 | alterNameEnv = alterUFM
|
| 148 | +upsertNameEnv = upsertUFM
|
|
| 144 | 149 | mkNameEnv l = listToUFM l
|
| 145 | 150 | mkNameEnvWith f = mkNameEnv . map (\a -> (f a, a))
|
| 146 | 151 | fromUniqMap = mapUFM snd . getUniqMap
|
| ... | ... | @@ -198,6 +203,9 @@ adjustDNameEnv = adjustUDFM |
| 198 | 203 | alterDNameEnv :: (Maybe a -> Maybe a) -> DNameEnv a -> Name -> DNameEnv a
|
| 199 | 204 | alterDNameEnv = alterUDFM
|
| 200 | 205 | |
| 206 | +upsertDNameEnv :: (Maybe a -> a) -> DNameEnv a -> Name -> DNameEnv a
|
|
| 207 | +upsertDNameEnv = upsertUDFM
|
|
| 208 | + |
|
| 201 | 209 | extendDNameEnv :: DNameEnv a -> Name -> a -> DNameEnv a
|
| 202 | 210 | extendDNameEnv = addToUDFM
|
| 203 | 211 |
| ... | ... | @@ -732,7 +732,7 @@ extendOccEnv_Acc f g (MkOccEnv env) (OccName ns s) = |
| 732 | 732 | MkOccEnv . extendFsEnv_Acc f' g' env s
|
| 733 | 733 | where
|
| 734 | 734 | f' :: a -> UniqFM NameSpace b -> UniqFM NameSpace b
|
| 735 | - f' a bs = alterUFM (Just . \ case { Nothing -> g a ; Just b -> f a b }) bs ns
|
|
| 735 | + f' a bs = upsertUFM (\ case { Nothing -> g a ; Just b -> f a b }) bs ns
|
|
| 736 | 736 | g' a = unitUFM ns (g a)
|
| 737 | 737 | |
| 738 | 738 | -- | Delete one element from an 'OccEnv'.
|
| ... | ... | @@ -32,6 +32,7 @@ module GHC.Types.Unique.DFM ( |
| 32 | 32 | delListFromUDFM,
|
| 33 | 33 | adjustUDFM,
|
| 34 | 34 | adjustUDFM_Directly,
|
| 35 | + upsertUDFM,
|
|
| 35 | 36 | alterUDFM,
|
| 36 | 37 | alterUDFM_L,
|
| 37 | 38 | mapUDFM,
|
| ... | ... | @@ -451,6 +452,23 @@ alterUDFM f (UDFM m i) k = |
| 451 | 452 | inject Nothing = Nothing
|
| 452 | 453 | inject (Just v) = Just $ TaggedVal v i
|
| 453 | 454 | |
| 455 | +-- | The expression (@'upsertUDFM' f map k@) updates the value at @k@ or inserts
|
|
| 456 | +-- a new value if @k@ is absent.
|
|
| 457 | +--
|
|
| 458 | +-- Like 'alterUDFM', updating an existing entry assigns it the current tag, so it
|
|
| 459 | +-- becomes the newest element in deterministic iteration order.
|
|
| 460 | +upsertUDFM
|
|
| 461 | + :: Uniquable key
|
|
| 462 | + => (Maybe elt -> elt) -- ^ How to adjust the element
|
|
| 463 | + -> UniqDFM key elt -- ^ Old 'UniqDFM'
|
|
| 464 | + -> key -- ^ @key@ of the element to adjust
|
|
| 465 | + -> UniqDFM key elt -- ^ New element at @key@ and modified 'UniqDFM'
|
|
| 466 | +upsertUDFM f (UDFM m i) k =
|
|
| 467 | + UDFM (MS.upsert upsertf (getKey $ getUnique k) m) (i + 1)
|
|
| 468 | + where
|
|
| 469 | + upsertf Nothing = TaggedVal (f Nothing) i
|
|
| 470 | + upsertf (Just (TaggedVal v _)) = TaggedVal (f (Just v)) i
|
|
| 471 | + |
|
| 454 | 472 | -- | The expression (@'alterUDFM_L' f map k@) alters value @x@ at @k@, or absence
|
| 455 | 473 | -- thereof and returns the new element at @k@ if there is any.
|
| 456 | 474 | -- 'alterUDFM_L' can be used to insert, delete, or update a value in
|
| ... | ... | @@ -42,8 +42,9 @@ module GHC.Types.Unique.FM ( |
| 42 | 42 | addListToUFM,addListToUFM_C,
|
| 43 | 43 | addToUFM_Directly,
|
| 44 | 44 | addListToUFM_Directly,
|
| 45 | - adjustUFM, alterUFM, alterUFM_L, alterUFM_Directly,
|
|
| 46 | - adjustUFM_Directly,
|
|
| 45 | + adjustUFM, adjustUFM_Directly,
|
|
| 46 | + upsertUFM, strictUpsertUFM,
|
|
| 47 | + alterUFM, alterUFM_L, alterUFM_Directly,
|
|
| 47 | 48 | delFromUFM,
|
| 48 | 49 | delFromUFM_Directly,
|
| 49 | 50 | delListFromUFM,
|
| ... | ... | @@ -226,6 +227,22 @@ alterUFM |
| 226 | 227 | -> UniqFM key elt -- ^ result
|
| 227 | 228 | alterUFM f (UFM m) k = UFM (M.alter f (getKey $ getUnique k) m)
|
| 228 | 229 | |
| 230 | +upsertUFM
|
|
| 231 | + :: Uniquable key
|
|
| 232 | + => (Maybe elt -> elt) -- ^ How to adjust
|
|
| 233 | + -> UniqFM key elt -- ^ old
|
|
| 234 | + -> key -- ^ new
|
|
| 235 | + -> UniqFM key elt -- ^ result
|
|
| 236 | +upsertUFM f (UFM m) k = UFM (M.upsert f (getKey $ getUnique k) m)
|
|
| 237 | + |
|
| 238 | +strictUpsertUFM
|
|
| 239 | + :: Uniquable key
|
|
| 240 | + => (Maybe elt -> elt) -- ^ How to adjust
|
|
| 241 | + -> UniqFM key elt -- ^ old
|
|
| 242 | + -> key -- ^ new
|
|
| 243 | + -> UniqFM key elt -- ^ result
|
|
| 244 | +strictUpsertUFM f (UFM m) k = UFM (MS.upsert f (getKey $ getUnique k) m)
|
|
| 245 | + |
|
| 229 | 246 | alterUFM_L
|
| 230 | 247 | :: Uniquable key
|
| 231 | 248 | => (Maybe elt -> Maybe elt) -- ^ How to adjust
|
| ... | ... | @@ -15,7 +15,7 @@ module GHC.Types.Var.Env ( |
| 15 | 15 | strictPlusVarEnv, plusVarEnv, plusVarEnv_C,
|
| 16 | 16 | strictPlusVarEnv_C, strictPlusVarEnv_C_Directly,
|
| 17 | 17 | plusVarEnv_CD, plusMaybeVarEnv_C,
|
| 18 | - plusVarEnvList, alterVarEnv,
|
|
| 18 | + plusVarEnvList, alterVarEnv, upsertVarEnv,
|
|
| 19 | 19 | delVarEnvList, delVarEnv,
|
| 20 | 20 | minusVarEnv,
|
| 21 | 21 | lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv,
|
| ... | ... | @@ -40,7 +40,7 @@ module GHC.Types.Var.Env ( |
| 40 | 40 | isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv,
|
| 41 | 41 | mapDVarEnv, filterDVarEnv,
|
| 42 | 42 | modifyDVarEnv,
|
| 43 | - alterDVarEnv,
|
|
| 43 | + alterDVarEnv, upsertDVarEnv,
|
|
| 44 | 44 | plusDVarEnv, plusDVarEnv_C,
|
| 45 | 45 | unitDVarEnv,
|
| 46 | 46 | delDVarEnv,
|
| ... | ... | @@ -509,6 +509,7 @@ mkVarEnv_Directly :: [(Unique, a)] -> VarEnv a |
| 509 | 509 | zipVarEnv :: [Var] -> [a] -> VarEnv a
|
| 510 | 510 | unitVarEnv :: Var -> a -> VarEnv a
|
| 511 | 511 | alterVarEnv :: (Maybe a -> Maybe a) -> VarEnv a -> Var -> VarEnv a
|
| 512 | +upsertVarEnv :: (Maybe a -> a) -> VarEnv a -> Var -> VarEnv a
|
|
| 512 | 513 | extendVarEnv :: VarEnv a -> Var -> a -> VarEnv a
|
| 513 | 514 | extendVarEnv_C :: (a->a->a) -> VarEnv a -> Var -> a -> VarEnv a
|
| 514 | 515 | extendVarEnv_Acc :: (a->b->b) -> (a->b) -> VarEnv b -> Var -> a -> VarEnv b
|
| ... | ... | @@ -548,6 +549,7 @@ elemVarEnv = elemUFM |
| 548 | 549 | elemVarEnvByKey = elemUFM_Directly
|
| 549 | 550 | disjointVarEnv = disjointUFM
|
| 550 | 551 | alterVarEnv = alterUFM
|
| 552 | +upsertVarEnv = upsertUFM
|
|
| 551 | 553 | extendVarEnv = addToUFM
|
| 552 | 554 | extendVarEnv_C = addToUFM_C
|
| 553 | 555 | extendVarEnv_Acc = addToUFM_Acc
|
| ... | ... | @@ -671,6 +673,9 @@ mapMaybeDVarEnv f = mapMaybeUDFM f |
| 671 | 673 | alterDVarEnv :: (Maybe a -> Maybe a) -> DVarEnv a -> Var -> DVarEnv a
|
| 672 | 674 | alterDVarEnv = alterUDFM
|
| 673 | 675 | |
| 676 | +upsertDVarEnv :: (Maybe a -> a) -> DVarEnv a -> Var -> DVarEnv a
|
|
| 677 | +upsertDVarEnv = upsertUDFM
|
|
| 678 | + |
|
| 674 | 679 | plusDVarEnv :: DVarEnv a -> DVarEnv a -> DVarEnv a
|
| 675 | 680 | plusDVarEnv = plusUDFM
|
| 676 | 681 |
| ... | ... | @@ -330,9 +330,9 @@ smartPlus platform e k = |
| 330 | 330 | where width = cmmExprWidth platform e
|
| 331 | 331 | |
| 332 | 332 | addToList :: ([a] -> [a]) -> Label -> LabelMap [a] -> LabelMap [a]
|
| 333 | -addToList consx = mapAlter add
|
|
| 334 | - where add Nothing = Just (consx [])
|
|
| 335 | - add (Just xs) = Just (consx xs)
|
|
| 333 | +addToList consx = mapUpsert add
|
|
| 334 | + where add Nothing = consx []
|
|
| 335 | + add (Just xs) = consx xs
|
|
| 336 | 336 | |
| 337 | 337 | ------------------------------------------------------------------
|
| 338 | 338 | --- everything below here is for diagnostics in case of panic
|