Simon Peyton Jones pushed to branch wip/T26314 at Glasgow Haskell Compiler / GHC

Commits:

7 changed files:

Changes:

  • compiler/GHC/StgToByteCode.hs
    ... ... @@ -84,11 +84,11 @@ import Data.Coerce (coerce)
    84 84
     #if MIN_VERSION_rts(1,0,3)
    
    85 85
     import qualified Data.ByteString.Char8 as BS
    
    86 86
     #endif
    
    87
    -import Data.Map (Map)
    
    88 87
     import Data.IntMap (IntMap)
    
    89 88
     import qualified Data.Map as Map
    
    90 89
     import qualified Data.IntMap as IntMap
    
    91
    -import qualified GHC.Data.FiniteMap as Map
    
    90
    +import GHC.Types.Unique.Map (UniqMap)
    
    91
    +import qualified GHC.Types.Unique.Map as UniqMap
    
    92 92
     import Data.Ord
    
    93 93
     import Data.Either ( partitionEithers )
    
    94 94
     
    
    ... ... @@ -209,7 +209,7 @@ type StackDepth = ByteOff
    209 209
     
    
    210 210
     -- | Maps Ids to their stack depth. This allows us to avoid having to mess with
    
    211 211
     -- it after each push/pop.
    
    212
    -type BCEnv = Map Id StackDepth -- To find vars on the stack
    
    212
    +type BCEnv = UniqMap Id StackDepth -- To find vars on the stack
    
    213 213
     
    
    214 214
     {-
    
    215 215
     ppBCEnv :: BCEnv -> SDoc
    
    ... ... @@ -379,7 +379,7 @@ schemeR_wrk fvs nm original_body (args, body)
    379 379
              sum_szsb_args  = sum szsb_args
    
    380 380
              -- Make a stack offset for each argument or free var -- they should
    
    381 381
              -- appear contiguous in the stack, in order.
    
    382
    -         p_init    = Map.fromList (zip all_args (mkStackOffsets 0 szsb_args))
    
    382
    +         p_init    = UniqMap.listToUniqMap (zip all_args (mkStackOffsets 0 szsb_args))
    
    383 383
     
    
    384 384
              -- make the arg bitmap
    
    385 385
              bits = argBits platform (reverse (map (idArgRep platform) all_args))
    
    ... ... @@ -442,7 +442,7 @@ fvsToEnv :: BCEnv -> CgStgRhs -> [Id]
    442 442
     -- it, have to agree about this layout
    
    443 443
     
    
    444 444
     fvsToEnv p rhs =  [v | v <- dVarSetElems $ freeVarsOfRhs rhs,
    
    445
    -                       v `Map.member` p]
    
    445
    +                       v `UniqMap.elemUniqMap` p]
    
    446 446
     
    
    447 447
     -- -----------------------------------------------------------------------------
    
    448 448
     -- schemeE
    
    ... ... @@ -533,7 +533,7 @@ schemeE d s p (StgLet _xlet
    533 533
             alloc_code <- mkConAppCode d s p data_con args
    
    534 534
             platform <- targetPlatform <$> getDynFlags
    
    535 535
             let !d2 = d + wordSize platform
    
    536
    -        body_code <- schemeE d2 s (Map.insert x d2 p) body
    
    536
    +        body_code <- schemeE d2 s (UniqMap.addToUniqMap p x d2) body
    
    537 537
             return (alloc_code `appOL` body_code)
    
    538 538
     -- General case for let.  Generates correct, if inefficient, code in
    
    539 539
     -- all situations.
    
    ... ... @@ -557,7 +557,7 @@ schemeE d s p (StgLet _ext binds body) = do
    557 557
              -- after the closures have been allocated in the heap (but not
    
    558 558
              -- filled in), and pointers to them parked on the stack.
    
    559 559
              offsets = mkStackOffsets d (genericReplicate n_binds (wordSize platform))
    
    560
    -         p' = Map.insertList (zipEqual xs offsets) p
    
    560
    +         p' = UniqMap.addListToUniqMap p $ zipEqual xs offsets
    
    561 561
              d' = d + wordsToBytes platform n_binds
    
    562 562
     
    
    563 563
              -- ToDo: don't build thunks for things with no free variables
    
    ... ... @@ -1180,7 +1180,7 @@ doCase d s p scrut bndr alts
    1180 1180
     
    
    1181 1181
             -- Env in which to compile the alts, not including
    
    1182 1182
             -- any vars bound by the alts themselves
    
    1183
    -        p_alts = Map.insert bndr d_bndr p
    
    1183
    +        p_alts = UniqMap.addToUniqMap p bndr d_bndr
    
    1184 1184
     
    
    1185 1185
             bndr_ty = idType bndr
    
    1186 1186
             isAlgCase = isAlgType bndr_ty
    
    ... ... @@ -1208,12 +1208,11 @@ doCase d s p scrut bndr alts
    1208 1208
     
    
    1209 1209
                      stack_bot = d_alts
    
    1210 1210
     
    
    1211
    -                 p' = Map.insertList
    
    1211
    +                 p' = UniqMap.addListToUniqMap p_alts
    
    1212 1212
                             [ (arg, tuple_start -
    
    1213 1213
                                     wordsToBytes platform (nativeCallSize call_info) +
    
    1214 1214
                                     offset)
    
    1215 1215
                             | (NonVoid arg, offset) <- args_offsets]
    
    1216
    -                        p_alts
    
    1217 1216
                  in do
    
    1218 1217
                    rhs_code <- schemeE stack_bot s p' rhs
    
    1219 1218
                    return (NoDiscr, rhs_code)
    
    ... ... @@ -1227,10 +1226,9 @@ doCase d s p scrut bndr alts
    1227 1226
                      stack_bot = d_alts + wordsToBytes platform size
    
    1228 1227
     
    
    1229 1228
                      -- convert offsets from Sp into offsets into the virtual stack
    
    1230
    -                 p' = Map.insertList
    
    1229
    +                 p' = UniqMap.addListToUniqMap p_alts
    
    1231 1230
                             [ (arg, stack_bot - ByteOff offset)
    
    1232 1231
                             | (NonVoid arg, offset) <- args_offsets ]
    
    1233
    -                        p_alts
    
    1234 1232
     
    
    1235 1233
                  in do
    
    1236 1234
                  massert isAlgCase
    
    ... ... @@ -1312,12 +1310,13 @@ doCase d s p scrut bndr alts
    1312 1310
               -- NB: unboxed tuple cases bind the scrut binder to the same offset
    
    1313 1311
               -- as one of the alt binders, so we have to remove any duplicates here:
    
    1314 1312
               -- 'toAscList' takes care of sorting the result, which was previously done after the application of 'filter'.
    
    1315
    -          rel_slots = IntSet.toAscList $ IntSet.fromList $ Map.elems $ Map.mapMaybeWithKey spread p
    
    1316
    -          spread id offset | isUnboxedTupleType (idType id) ||
    
    1317
    -                             isUnboxedSumType (idType id) = Nothing
    
    1318
    -                           | isFollowableArg (idArgRep platform id) = Just (fromIntegral rel_offset)
    
    1319
    -                           | otherwise                      = Nothing
    
    1320
    -                where rel_offset = bytesToWords platform (d - offset)
    
    1313
    +          rel_slots = IntSet.toAscList $ UniqMap.nonDetFoldUniqMap go IntSet.empty p
    
    1314
    +          go (var, offset) !acc
    
    1315
    +            | isUnboxedTupleType (idType var) || isUnboxedSumType (idType var)
    
    1316
    +            = acc
    
    1317
    +            | isFollowableArg (idArgRep platform var)
    
    1318
    +            = fromIntegral (bytesToWords platform (d - offset)) `IntSet.insert` acc
    
    1319
    +            | otherwise = acc
    
    1321 1320
     
    
    1322 1321
             bitmap = intsToReverseBitmap platform bitmap_size' pointers
    
    1323 1322
     
    
    ... ... @@ -2546,7 +2545,7 @@ instance Outputable Discr where
    2546 2545
     
    
    2547 2546
     
    
    2548 2547
     lookupBCEnv_maybe :: Id -> BCEnv -> Maybe ByteOff
    
    2549
    -lookupBCEnv_maybe = Map.lookup
    
    2548
    +lookupBCEnv_maybe v env = UniqMap.lookupUniqMap env v
    
    2550 2549
     
    
    2551 2550
     idSizeW :: Platform -> Id -> WordOff
    
    2552 2551
     idSizeW platform = WordOff . argRepSizeW platform . idArgRep platform
    

  • compiler/GHC/Tc/Solver/Dict.hs
    ... ... @@ -588,22 +588,24 @@ solving fails and we use the superclass of C:
    588 588
     The moving parts are relatively simple:
    
    589 589
     
    
    590 590
     * To attempt to solve the constraint completely, we just recursively
    
    591
    -  call the constraint solver. See the use of `tryTcS` in
    
    591
    +  call the constraint solver. See the use of `tryShortCutTcS` in
    
    592 592
       `tcShortCutSolver`.
    
    593 593
     
    
    594
    -* When this attempted recursive solving, we set a special mode
    
    595
    -  `TcSShortCut`, which signals that we are trying to solve using only
    
    596
    -  top-level instances.  We switch on `TcSShortCut` mode in
    
    597
    -  `tryShortCutSolver`.
    
    594
    +* When this attempted recursive solving, in `tryShortCutTcS`, we
    
    595
    +  - start with an empty inert set: no Givens and no Wanteds
    
    596
    +  - set a special mode  `TcSShortCut`, which signals that we are trying to solve
    
    597
    +    using only top-level instances.
    
    598 598
     
    
    599
    -* When in TcSShortCut mode, we behave specially in a few places:
    
    600
    -  - `tryInertDicts`, where we would otherwise look for a Given to solve our Wanted
    
    601
    -  - `GHC.Tc.Solver.Monad.lookupInertDict` similarly
    
    602
    -  - `noMatchableGivenDicts`, which also consults the Givens
    
    603
    -  - `matchLocalInst`, which would otherwise consult Given quantified constraints
    
    604
    -  - `GHC.Tc.Solver.Instance.Class.matchInstEnv`: when short-cut solving, don't
    
    605
    -    pick overlappable top-level instances
    
    606
    -  - `GHC.Tc.Solver.Solve.runTcPluginsWanted`: don't pass any Givens to the plugin
    
    599
    +* When in TcSShortCut mode, since there are no Givens we can short-circuit;
    
    600
    +  these are all just optimisations:
    
    601
    +      - `tryInertDicts`
    
    602
    +      - `GHC.Tc.Solver.Monad.lookupInertDict`
    
    603
    +      - `noMatchableGivenDicts`
    
    604
    +      - `matchLocalInst`
    
    605
    +      - `GHC.Tc.Solver.Solve.runTcPluginsWanted`
    
    606
    +
    
    607
    +* In `GHC.Tc.Solver.Instance.Class.matchInstEnv`: when short-cut solving,
    
    608
    +  don't pick overlappable top-level instances
    
    607 609
     
    
    608 610
     Some wrinkles:
    
    609 611
     
    
    ... ... @@ -770,14 +772,14 @@ tryInertDicts dict_ct
    770 772
     
    
    771 773
     try_inert_dicts :: TcSMode -> InertCans -> DictCt -> TcS (StopOrContinue ())
    
    772 774
     try_inert_dicts mode inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys })
    
    773
    -  | not (mode == TcSShortCut)   -- Ignore the inerts (esp Givens) in short-cut mode
    
    774
    -                                -- See Note [Shortcut solving]
    
    775
    +  | not (mode == TcSShortCut)   -- Optimisation: ignore the inerts (esp Givens) in
    
    776
    +                                -- short-cut mode. See Note [Shortcut solving]
    
    775 777
       , Just dict_i <- lookupInertDict inerts cls tys
    
    776 778
       , let ev_i  = dictCtEvidence dict_i
    
    777 779
             loc_i = ctEvLoc ev_i
    
    778 780
             loc_w = ctEvLoc ev_w
    
    779 781
       = -- There is a matching dictionary in the inert set
    
    780
    -    do { -- First to try to solve it /completely/ from top level instances
    
    782
    +    do { -- For a Wanted, first to try to solve it /completely/ from top level instances
    
    781 783
              -- See Note [Shortcut solving]
    
    782 784
            ; short_cut_worked <- tryShortCutSolver (isGiven ev_i) dict_w
    
    783 785
     
    
    ... ... @@ -833,11 +835,7 @@ tryShortCutSolver try_short_cut dict_w@(DictCt { di_ev = ev_w })
    833 835
                 , gopt Opt_SolveConstantDicts dflags
    
    834 836
                   -- Enabled by the -fsolve-constant-dicts flag
    
    835 837
     
    
    836
    -            -> tryTcS $  -- tryTcS tries to completely solve some contraints
    
    837
    -               -- Inherit the current solved_dicts, so that one invocation of
    
    838
    -               -- tryShortCutSolver can benefit from the work of earlier invocations
    
    839
    -               -- See wrinkle (SCS3) of Note [Shortcut solving]
    
    840
    -               setTcSMode TcSShortCut $
    
    838
    +            -> tryShortCutTcS $  -- tryTcS tries to completely solve some contraints
    
    841 839
                    do { residual <- solveSimpleWanteds (unitBag (CDictCan dict_w))
    
    842 840
                       ; return (isEmptyBag residual) }
    
    843 841
     
    
    ... ... @@ -977,7 +975,7 @@ matchClassInst dflags mode inerts clas tys loc
    977 975
     noMatchableGivenDicts :: TcSMode -> InertSet -> CtLoc -> Class -> [TcType] -> Bool
    
    978 976
     noMatchableGivenDicts mode inerts@(IS { inert_cans = inert_cans }) loc_w clas tys
    
    979 977
       | TcSShortCut <- mode
    
    980
    -  = True  -- In TcSShortCut mode we behave as if there were no Givens at all
    
    978
    +  = True  -- Optimisation: in TcSShortCut mode there are no Givens
    
    981 979
       | otherwise
    
    982 980
       = not $ anyBag matchable_given $
    
    983 981
         findDictsByClass (inert_dicts inert_cans) clas
    
    ... ... @@ -1153,8 +1151,7 @@ matchLocalInst :: TcPredType -> CtLoc -> TcS ClsInstResult
    1153 1151
     -- Look up the predicate in Given quantified constraints,
    
    1154 1152
     -- which are effectively just local instance declarations.
    
    1155 1153
     matchLocalInst body_pred loc
    
    1156
    -  = do { -- In TcSShortCut mode we do not look at Givens;
    
    1157
    -         -- c.f. tryInertDicts
    
    1154
    +  = do { -- Optimisation: in TcSShortCut mode there are no Givens (c.f. tryInertDicts)
    
    1158 1155
              mode <- getTcSMode
    
    1159 1156
            ; case mode of
    
    1160 1157
                { TcSShortCut -> do { traceTcS "matchLocalInst:TcSShortCut" (ppr body_pred)
    

  • compiler/GHC/Tc/Solver/Monad.hs
    ... ... @@ -19,7 +19,7 @@ module GHC.Tc.Solver.Monad (
    19 19
         runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts,
    
    20 20
         failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS,
    
    21 21
         runTcSEqualities,
    
    22
    -    nestTcS, nestImplicTcS, tryTcS,
    
    22
    +    nestTcS, nestImplicTcS, tryShortCutTcS,
    
    23 23
         setEvBindsTcS, setTcLevelTcS,
    
    24 24
         emitFunDepWanteds,
    
    25 25
     
    
    ... ... @@ -1259,20 +1259,31 @@ nestTcS (TcS thing_inside)
    1259 1259
     
    
    1260 1260
            ; return res }
    
    1261 1261
     
    
    1262
    -tryTcS :: TcS Bool -> TcS Bool
    
    1262
    +tryShortCutTcS :: TcS Bool -> TcS Bool
    
    1263 1263
     -- Like nestTcS, but
    
    1264
    ---   (a) be a no-op if the nested computation returns Nothing
    
    1264
    +--   (a) be a no-op if the nested computation returns False
    
    1265 1265
     --   (b) if (but only if) success, propagate nested bindings to the caller
    
    1266 1266
     -- Use only by the short-cut solver;
    
    1267 1267
     --   see Note [Shortcut solving] in GHC.Tc.Solver.Dict
    
    1268
    -tryTcS (TcS thing_inside)
    
    1268
    +tryShortCutTcS (TcS thing_inside)
    
    1269 1269
       = TcS $ \ env@(TcSEnv { tcs_inerts = inerts_var
    
    1270 1270
                             , tcs_ev_binds = old_ev_binds_var }) ->
    
    1271
    -    do { old_inerts       <- TcM.readTcRef inerts_var
    
    1272
    -       ; new_inert_var    <- TcM.newTcRef old_inerts
    
    1271
    +    do { -- Initialise a fresh inert set, with no Givens and no Wanteds
    
    1272
    +         --    (i.e. empty `inert_cans`)
    
    1273
    +         -- But inherit all the InertSet cache fields; in particular
    
    1274
    +         --  * the given_eq_lvl, so we don't accidentally unify a
    
    1275
    +         --    unification variable from outside a GADT match
    
    1276
    +         --  * the `solved_dicts`; see wrinkle (SCS3) of Note [Shortcut solving]
    
    1277
    +         --  * the `famapp_cache`; similarly
    
    1278
    +         old_inerts <- TcM.readTcRef inerts_var
    
    1279
    +       ; let given_eq_lvl = inert_given_eq_lvl (inert_cans old_inerts)
    
    1280
    +             new_inerts   = old_inerts { inert_cans = emptyInertCans given_eq_lvl }
    
    1281
    +       ; new_inert_var <- TcM.newTcRef new_inerts
    
    1282
    +
    
    1273 1283
            ; new_wl_var       <- TcM.newTcRef emptyWorkList
    
    1274 1284
            ; new_ev_binds_var <- TcM.cloneEvBindsVar old_ev_binds_var
    
    1275
    -       ; let nest_env = env { tcs_ev_binds = new_ev_binds_var
    
    1285
    +       ; let nest_env = env { tcs_mode     = TcSShortCut
    
    1286
    +                            , tcs_ev_binds = new_ev_binds_var
    
    1276 1287
                                 , tcs_inerts   = new_inert_var
    
    1277 1288
                                 , tcs_worklist = new_wl_var }
    
    1278 1289
     
    

  • compiler/GHC/Tc/Solver/Solve.hs
    ... ... @@ -1679,8 +1679,9 @@ runTcPluginsWanted wanted
    1679 1679
            ; if null solvers then return (False, wanted) else
    
    1680 1680
     
    
    1681 1681
         do { -- Find the set of Givens to give to the plugin.
    
    1682
    -         -- If TcSMode = TcSShortCut, we are solving with
    
    1683
    -         -- no Givens so don't return any (#26258)!
    
    1682
    +         -- Optimisation: if TcSMode = TcSShortCut, we are solving with
    
    1683
    +         -- no Givens so don't bother to look (#26258 was a bug in an earlier
    
    1684
    +         -- version when we left the Givens in the inert set)
    
    1684 1685
              -- See Note [Shortcut solving] in GHC.Tc.Solver.Dict
    
    1685 1686
              mode <- getTcSMode
    
    1686 1687
            ; given <- case mode of
    

  • configure.ac
    ... ... @@ -536,7 +536,7 @@ AC_SUBST(InstallNameToolCmd)
    536 536
     # versions of LLVM simultaneously, but that stopped working around
    
    537 537
     # 3.5/3.6 release of LLVM.
    
    538 538
     LlvmMinVersion=13  # inclusive
    
    539
    -LlvmMaxVersion=20  # not inclusive
    
    539
    +LlvmMaxVersion=21  # not inclusive
    
    540 540
     AC_SUBST([LlvmMinVersion])
    
    541 541
     AC_SUBST([LlvmMaxVersion])
    
    542 542
     
    

  • libffi-tarballs
    1
    -Subproject commit a5480d7e7f86a9bb5b44dd1156a92f69f7c185ec
    1
    +Subproject commit 7c51059557b68d29820a0a87cebfa6fe73c8adf5

  • rts/Hash.c
    ... ... @@ -81,7 +81,7 @@ hashWord(const HashTable *table, StgWord key)
    81 81
         int bucket;
    
    82 82
     
    
    83 83
         /* Strip the boring zero bits */
    
    84
    -    key >>= sizeof(StgWord);
    
    84
    +    key /= sizeof(StgWord);
    
    85 85
     
    
    86 86
         /* Mod the size of the hash table (a power of 2) */
    
    87 87
         bucket = key & table->mask1;